aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS162
-rw-r--r--NEWS19
-rw-r--r--README4
-rw-r--r--backends/base-backend.h2
-rw-r--r--backends/events/default/default-events.cpp362
-rw-r--r--backends/events/default/default-events.h71
-rw-r--r--backends/keymapper/keymapper.cpp11
-rw-r--r--backends/keymapper/keymapper.h6
-rw-r--r--backends/platform/dc/dreamcast.mk11
-rw-r--r--backends/platform/dc/ip.txt.in11
-rw-r--r--backends/platform/ds/arm9/source/fat/disc_io.h2
-rw-r--r--backends/platform/ds/arm9/source/fat/gba_nds_fat.h2
-rw-r--r--backends/platform/ds/arm9/source/portdefs.h2
-rw-r--r--backends/platform/ds/commoninclude/NDS/scummvm_ipc.h2
-rw-r--r--backends/platform/ds/ds.mk111
-rw-r--r--backends/platform/ds/module.mk71
-rw-r--r--backends/platform/gp2x/build/README-GP2X38
-rw-r--r--backends/platform/gp2x/build/README-GP2X.html369
-rwxr-xr-xbackends/platform/gp2x/build/bundle.sh1
-rwxr-xr-xbackends/platform/gp2x/build/config-alleng.sh2
-rwxr-xr-xbackends/platform/gp2x/build/config.sh2
-rw-r--r--backends/platform/gp2x/events.cpp31
-rw-r--r--backends/platform/gp2x/gp2x-hw.cpp96
-rw-r--r--backends/platform/gp2x/gp2x-hw.h18
-rw-r--r--backends/platform/gp2x/gp2x.cpp17
-rw-r--r--backends/platform/gp2x/graphics.cpp1
-rw-r--r--backends/platform/gp2xwiz/build/README-GP2XWIZ41
-rwxr-xr-xbackends/platform/gp2xwiz/build/bundle.sh9
-rwxr-xr-xbackends/platform/gp2xwiz/build/scummvm.gpe4
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-events.cpp11
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-graphics.cpp425
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-hw.cpp2
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-main.cpp6
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-scaler.cpp40
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-scaler.h42
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-sdl.h15
-rw-r--r--backends/platform/gp2xwiz/module.mk2
-rw-r--r--backends/platform/sdl/graphics.cpp4
-rw-r--r--backends/platform/sdl/sdl.cpp4
-rw-r--r--backends/platform/wince/CEActionsPocket.cpp16
-rw-r--r--backends/platform/wince/CEActionsSmartphone.cpp17
-rw-r--r--backends/platform/wince/CEScaler.cpp13
-rw-r--r--backends/platform/wince/CEgui/SDL_ImageResource.cpp2
-rw-r--r--backends/platform/wince/Makefile11
-rw-r--r--backends/platform/wince/README-WinCE.txt64
-rw-r--r--backends/platform/wince/missing/missing.cpp2
-rw-r--r--backends/platform/wince/module.mk21
-rw-r--r--backends/platform/wince/wince-sdl.cpp58
-rw-r--r--backends/platform/wince/wince.mk5
-rw-r--r--backends/vkeybd/packs/vkeybd_default.zipbin508756 -> 184936 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/lowercase-symbols320x240.bmpbin153654 -> 153654 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/lowercase-symbols640x480.bmpbin612534 -> 612534 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/lowercase320x240.bmpbin153654 -> 153654 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/lowercase640x480.bmpbin612534 -> 612534 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/uppercase-symbols320x240.bmpbin153654 -> 153654 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/uppercase-symbols640x480.bmpbin612534 -> 612534 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/uppercase320x240.bmpbin153654 -> 153654 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/uppercase640x480.bmpbin612534 -> 612534 bytes
-rw-r--r--backends/vkeybd/packs/vkeybd_default/vkeybd_default.xml617
-rw-r--r--base/internal_version.h2
-rw-r--r--base/main.cpp15
-rw-r--r--common/EventDispatcher.cpp138
-rw-r--r--common/EventRecorder.cpp366
-rw-r--r--common/EventRecorder.h106
-rw-r--r--common/events.h208
-rw-r--r--common/file.cpp9
-rw-r--r--common/file.h13
-rw-r--r--common/module.mk2
-rw-r--r--common/str.cpp29
-rw-r--r--common/str.h5
-rw-r--r--common/stream.h2
-rw-r--r--common/unarj.cpp14
-rwxr-xr-xconfigure162
-rw-r--r--dists/msvc8/gob.vcproj52
-rw-r--r--dists/msvc9/gob.vcproj54
-rw-r--r--dists/msvc9/scummvm.vcproj1910
-rw-r--r--dists/redhat/scummvm.spec2
-rw-r--r--dists/scummvm.rc8
-rwxr-xr-xdists/slackware/scummvm.SlackBuild2
-rw-r--r--dists/wii/meta.xml2
-rw-r--r--engines/agi/agi.cpp165
-rw-r--r--engines/agi/agi.h4
-rw-r--r--engines/agi/cycle.cpp2
-rw-r--r--engines/agi/detection.cpp29
-rw-r--r--engines/agi/keyboard.cpp31
-rw-r--r--engines/agi/menu.cpp62
-rw-r--r--engines/agi/preagi_mickey.cpp2
-rw-r--r--engines/agi/saveload.cpp82
-rw-r--r--engines/agi/sprite.cpp5
-rw-r--r--engines/agos/agos.cpp3
-rw-r--r--engines/agos/agos.h44
-rw-r--r--engines/agos/debug.h2
-rw-r--r--engines/agos/detection_tables.h160
-rw-r--r--engines/agos/draw.cpp10
-rw-r--r--engines/agos/input.cpp5
-rw-r--r--engines/agos/midiparser_s1d.cpp4
-rw-r--r--engines/agos/pn.cpp50
-rw-r--r--engines/agos/res_snd.cpp4
-rw-r--r--engines/agos/saveload.cpp25
-rw-r--r--engines/agos/script_pn.cpp126
-rw-r--r--engines/agos/script_s1.cpp13
-rw-r--r--engines/agos/vga_e2.cpp44
-rw-r--r--engines/agos/vga_ww.cpp22
-rw-r--r--engines/cine/cine.cpp6
-rw-r--r--engines/cine/detection.cpp52
-rw-r--r--engines/cine/pal.cpp3
-rw-r--r--engines/cine/saveload.cpp9
-rw-r--r--engines/cruise/cruise.cpp3
-rw-r--r--engines/cruise/cruise_main.cpp42
-rw-r--r--engines/cruise/cruise_main.h8
-rw-r--r--engines/cruise/dataLoader.cpp2
-rw-r--r--engines/cruise/linker.cpp21
-rw-r--r--engines/cruise/mainDraw.cpp32
-rw-r--r--engines/cruise/mainDraw.h4
-rw-r--r--engines/cruise/menu.cpp1
-rw-r--r--engines/cruise/script.cpp7
-rw-r--r--engines/cruise/sound.cpp4
-rw-r--r--engines/cruise/staticres.cpp53
-rw-r--r--engines/cruise/staticres.h4
-rw-r--r--engines/drascula/converse.cpp26
-rw-r--r--engines/drascula/drascula.cpp11
-rw-r--r--engines/drascula/drascula.h4
-rw-r--r--engines/drascula/graphics.cpp62
-rw-r--r--engines/drascula/rooms.cpp39
-rw-r--r--engines/drascula/talk.cpp1
-rw-r--r--engines/gob/demos/demoplayer.cpp45
-rw-r--r--engines/gob/demos/demoplayer.h2
-rw-r--r--engines/gob/demos/scnplayer.cpp2
-rw-r--r--engines/gob/detection.cpp52
-rw-r--r--engines/gob/draw.cpp2
-rw-r--r--engines/gob/draw.h5
-rw-r--r--engines/gob/draw_v1.cpp2
-rw-r--r--engines/gob/draw_v2.cpp28
-rw-r--r--engines/gob/game.cpp6
-rw-r--r--engines/gob/global.cpp2
-rw-r--r--engines/gob/global.h2
-rw-r--r--engines/gob/gob.cpp183
-rw-r--r--engines/gob/gob.h3
-rw-r--r--engines/gob/init.cpp7
-rw-r--r--engines/gob/init.h38
-rw-r--r--engines/gob/init_v1.cpp3
-rw-r--r--engines/gob/init_v2.cpp3
-rw-r--r--engines/gob/init_v3.cpp3
-rw-r--r--engines/gob/init_v4.cpp45
-rw-r--r--engines/gob/init_v6.cpp3
-rw-r--r--engines/gob/inter_v1.cpp13
-rw-r--r--engines/gob/inter_v2.cpp66
-rw-r--r--engines/gob/map.h8
-rw-r--r--engines/gob/map_v2.cpp26
-rw-r--r--engines/gob/map_v4.cpp159
-rw-r--r--engines/gob/module.mk2
-rw-r--r--engines/gob/resources.cpp44
-rw-r--r--engines/gob/resources.h6
-rw-r--r--engines/gob/save/saveconverter.cpp6
-rw-r--r--engines/gob/save/saveload.h28
-rw-r--r--engines/gob/save/saveload_v4.cpp20
-rw-r--r--engines/gob/scenery.cpp13
-rw-r--r--engines/gob/script.cpp2
-rw-r--r--engines/gob/sound/bgatmosphere.cpp3
-rw-r--r--engines/gob/sound/sounddesc.cpp6
-rw-r--r--engines/gob/sound/soundmixer.cpp25
-rw-r--r--engines/gob/sound/soundmixer.h4
-rw-r--r--engines/gob/util.cpp12
-rw-r--r--engines/gob/util.h1
-rw-r--r--engines/gob/variables.cpp32
-rw-r--r--engines/gob/variables.h12
-rw-r--r--engines/gob/videoplayer.cpp16
-rw-r--r--engines/gob/videoplayer.h2
-rw-r--r--engines/groovie/cell.cpp819
-rw-r--r--engines/groovie/cell.h48
-rw-r--r--engines/groovie/script.cpp44
-rw-r--r--engines/groovie/script.h3
-rw-r--r--engines/kyra/gui.cpp10
-rw-r--r--engines/kyra/gui_hof.cpp2
-rw-r--r--engines/kyra/gui_mr.cpp2
-rw-r--r--engines/kyra/items_mr.cpp3
-rw-r--r--engines/kyra/kyra_hof.cpp6
-rw-r--r--engines/kyra/kyra_mr.h1
-rw-r--r--engines/kyra/kyra_v1.cpp3
-rw-r--r--engines/kyra/saveload.cpp6
-rw-r--r--engines/kyra/screen.cpp23
-rw-r--r--engines/kyra/script_mr.cpp8
-rw-r--r--engines/kyra/sequences_mr.cpp3
-rw-r--r--engines/kyra/sound_digital.cpp2
-rw-r--r--engines/kyra/sprites.cpp4
-rw-r--r--engines/lure/hotspots.cpp25
-rw-r--r--engines/lure/res.cpp3
-rw-r--r--engines/lure/scripts.cpp3
-rw-r--r--engines/m4/m4.cpp3
-rw-r--r--engines/made/made.cpp3
-rw-r--r--engines/parallaction/parallaction.cpp3
-rw-r--r--engines/parallaction/parser.h14
-rw-r--r--engines/parallaction/parser_br.cpp37
-rw-r--r--engines/parallaction/parser_ns.cpp33
-rw-r--r--engines/parallaction/saveload.cpp88
-rw-r--r--engines/parallaction/saveload.h1
-rw-r--r--engines/queen/display.cpp3
-rw-r--r--engines/queen/music.cpp3
-rw-r--r--engines/queen/queen.cpp3
-rw-r--r--engines/saga/detection.cpp4
-rw-r--r--engines/saga/font.cpp48
-rw-r--r--engines/saga/saga.cpp3
-rw-r--r--engines/sci/console.cpp25
-rw-r--r--engines/sci/debug.h1
-rw-r--r--engines/sci/engine/scriptdebug.cpp29
-rw-r--r--engines/sci/engine/seg_manager.cpp13
-rw-r--r--engines/sci/engine/seg_manager.h7
-rw-r--r--engines/sci/engine/vm.cpp14
-rw-r--r--engines/sci/engine/vm.h5
-rw-r--r--engines/sci/gfx/operations.cpp1
-rw-r--r--engines/sci/resource.cpp8
-rw-r--r--engines/sci/sci.cpp4
-rw-r--r--engines/scumm/actor.cpp65
-rw-r--r--engines/scumm/actor.h8
-rw-r--r--engines/scumm/boxes.cpp2
-rw-r--r--engines/scumm/costume.cpp207
-rw-r--r--engines/scumm/costume.h6
-rw-r--r--engines/scumm/detection.cpp72
-rw-r--r--engines/scumm/detection_tables.h12
-rw-r--r--engines/scumm/dialogs.cpp9
-rw-r--r--engines/scumm/dialogs.h4
-rw-r--r--engines/scumm/file.cpp9
-rw-r--r--engines/scumm/file.h5
-rw-r--r--engines/scumm/gfx.cpp14
-rw-r--r--engines/scumm/he/cup_player_he.cpp23
-rw-r--r--engines/scumm/he/intern_he.h2
-rw-r--r--engines/scumm/he/script_v100he.cpp4
-rw-r--r--engines/scumm/he/script_v60he.cpp23
-rw-r--r--engines/scumm/he/script_v72he.cpp10
-rw-r--r--engines/scumm/he/script_v80he.cpp6
-rw-r--r--engines/scumm/he/script_v90he.cpp2
-rw-r--r--engines/scumm/he/wiz_he.cpp4
-rw-r--r--engines/scumm/imuse_digi/dimuse_bndmgr.cpp2
-rw-r--r--engines/scumm/input.cpp17
-rw-r--r--engines/scumm/object.cpp64
-rw-r--r--engines/scumm/resource.cpp11
-rw-r--r--engines/scumm/resource_v2.cpp2
-rw-r--r--engines/scumm/resource_v3.cpp2
-rw-r--r--engines/scumm/resource_v4.cpp9
-rw-r--r--engines/scumm/saveload.cpp56
-rw-r--r--engines/scumm/saveload.h2
-rw-r--r--engines/scumm/script.cpp130
-rw-r--r--engines/scumm/script_v0.cpp153
-rw-r--r--engines/scumm/script_v5.cpp18
-rw-r--r--engines/scumm/script_v6.cpp8
-rw-r--r--engines/scumm/scumm-md5.h130
-rw-r--r--engines/scumm/scumm.cpp21
-rw-r--r--engines/scumm/scumm.h12
-rw-r--r--engines/scumm/scumm_v0.h30
-rw-r--r--engines/scumm/scumm_v2.h5
-rw-r--r--engines/scumm/sound.cpp14
-rw-r--r--engines/scumm/string.cpp5
-rw-r--r--engines/scumm/vars.cpp4
-rw-r--r--engines/scumm/verbs.cpp473
-rw-r--r--engines/sky/logic.cpp3
-rw-r--r--engines/sword1/animation.cpp42
-rw-r--r--engines/sword1/control.cpp2
-rw-r--r--engines/sword1/logic.cpp3
-rw-r--r--engines/sword1/resman.cpp6
-rw-r--r--engines/sword1/sound.cpp3
-rw-r--r--engines/sword2/animation.cpp39
-rw-r--r--engines/sword2/animation.h2
-rw-r--r--engines/sword2/resman.cpp6
-rw-r--r--engines/sword2/startup.cpp4
-rw-r--r--engines/sword2/sword2.cpp3
-rw-r--r--engines/tinsel/detection.cpp4
-rw-r--r--engines/tinsel/heapmem.cpp5
-rw-r--r--engines/tinsel/saveload.cpp27
-rw-r--r--engines/tinsel/tinsel.cpp3
-rw-r--r--engines/touche/touche.cpp3
-rw-r--r--engines/tucker/locations.cpp2
-rw-r--r--graphics/VectorRendererSpec.cpp30
-rw-r--r--graphics/module.mk6
-rw-r--r--graphics/scaler.cpp52
-rw-r--r--graphics/scaler.h3
-rwxr-xr-xgraphics/scaler/Normal2xARM.s171
-rw-r--r--graphics/scaler/scale2x.cpp38
-rw-r--r--graphics/scaler/scale2x.h10
-rwxr-xr-xgraphics/scaler/scale2xARM.s182
-rw-r--r--graphics/scaler/scalebit.cpp12
-rw-r--r--graphics/sjis.cpp112
-rw-r--r--graphics/sjis.h79
-rw-r--r--graphics/video/coktelvideo/coktelvideo.cpp1652
-rw-r--r--graphics/video/coktelvideo/coktelvideo.h256
-rw-r--r--graphics/video/smk_decoder.cpp6
-rw-r--r--graphics/video/smk_decoder.h4
-rw-r--r--gui/ListWidget.cpp12
-rw-r--r--gui/ScrollBarWidget.cpp4
-rw-r--r--gui/ThemeEngine.h2
-rw-r--r--gui/browser.cpp2
-rw-r--r--gui/credits.h245
-rw-r--r--gui/debugger.cpp95
-rw-r--r--gui/debugger.h13
-rw-r--r--gui/options.cpp4
-rw-r--r--gui/themes/default.inc14
-rw-r--r--gui/themes/scummclassic.zipbin53307 -> 53291 bytes
-rw-r--r--gui/themes/scummclassic/THEMERC2
-rw-r--r--gui/themes/scummclassic/classic_layout.stx2
-rw-r--r--gui/themes/scummclassic/classic_layout_lowres.stx12
-rw-r--r--gui/themes/scummmodern.zipbin157995 -> 157979 bytes
-rw-r--r--gui/themes/scummmodern/THEMERC2
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx2
-rw-r--r--gui/themes/scummmodern/scummmodern_layout_lowres.stx12
-rw-r--r--ports.mk28
-rw-r--r--sound/fmopl.h2
-rw-r--r--sound/softsynth/mt32/partial.cpp2
-rw-r--r--sound/softsynth/mt32/synth.cpp2
-rw-r--r--sound/softsynth/mt32/tables.cpp2
-rw-r--r--test/common/str.h8
-rwxr-xr-xtools/credits.pl173
-rw-r--r--tools/module.mk4
-rw-r--r--tools/scumm-md5.txt142
312 files changed, 10015 insertions, 4753 deletions
diff --git a/AUTHORS b/AUTHORS
index afa8877bbc..bc52898b18 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,14 +15,19 @@ ScummVM Team
------------
SCUMM:
Torbjorn Andersson
+ James Brown - (retired)
+ Jonathan Gray - (retired)
+ Vincent Hamm - (retired)
Max Horn
Travis Howell
Pawel Kolodziejski - Codecs, iMUSE, Smush, etc.
Gregory Montoir
Eugene Sandulenko - FT INSANE, MM NES, MM C64, game detection,
Herc/CGA
+ Ludvig Strigeus - (retired)
HE:
+ Jonathan Gray - (retired)
Travis Howell
Gregory Montoir
Eugene Sandulenko
@@ -35,42 +40,53 @@ ScummVM Team
Walter van Niftrik
Kari Salminen
Eugene Sandulenko
+ David Symonds - (retired)
AGOS:
Torbjorn Andersson
Paul Gilbert
Travis Howell
+ Oliver Kiehl - (retired)
+ Ludvig Strigeus - (retired)
BASS:
+ Robert Goeffringmann - (retired)
+ Oliver Kiehl - (retired)
Joost Peters
Broken Sword 1:
+ Fabio Battaglia - PSX version support
+ Robert Goeffringmann - (retired)
Broken Sword 2:
Torbjorn Andersson
+ Fabio Battaglia - PSX version support
+ Jonathan Gray - (retired)
Cinematique evo 1:
- Vincent Hamm - original CinE engine author
+ Vincent Hamm - (retired)
Pawel Kolodziejski
Gregory Montoir
+ Kari Salminen
Eugene Sandulenko
Cinematique evo 2:
- Vincent Hamm - original CruisE engine author
Paul Gilbert
+ Vincent Hamm - (retired)
Drascula:
Filippos Karapetis
Pawel Kolodziejski
FOTAQ:
+ David Eriksson - (retired)
Gregory Montoir
Joost Peters
Gob:
Torbjorn Andersson
+ Arnaud Boutonne
Sven Hesse
- Willem Jan Palenstijn
Eugene Sandulenko
Groovie:
@@ -103,7 +119,6 @@ ScummVM Team
SAGA:
Torbjorn Andersson
- Sven Hesse
Filippos Karapetis
Andrew Kurushin
Eugene Sandulenko
@@ -114,11 +129,13 @@ ScummVM Team
Max Horn
Filippos Karapetis
Walter van Niftrik
+ Willem Jan Palenstijn
Jordi Vilalta Prat
Lars Skovlund
Tinsel:
Torbjorn Andersson
+ Fabio Battaglia - PSX version support
Paul Gilbert
Sven Hesse
Max Horn
@@ -152,9 +169,11 @@ ScummVM Team
Chris Apers
PocketPC / WinCE:
+ Nicolas Bacca - (retired)
Kostas Nakos
PlayStation 2:
+ Robert Goeffringmann - (retired)
Max Lingua
PSP (PlayStation Portable):
@@ -179,19 +198,26 @@ ScummVM Team
Eugene Sandulenko
GUI:
+ Vicent Marti
Eugene Sandulenko
Johannes Schickel
Miscellaneous:
David Corrales-Lopez - Filesystem access improvements (GSoC 2007
- task)
- Jerome Fisher - MT-32 emulator
+ task) (retired)
+ Jerome Fisher - MT-32 emulator (retired)
+ Benjamin Haisch - Heavily improved de-/encoder for DXA videos
Jochen Hoenicke - Speaker & PCjr sound support, AdLib work
+ (retired)
Chris Page - Return to launcher, savestate improvements,
- leak fixes, ... (GSoC 2008 task)
+ leak fixes, ... (GSoC 2008 task) (retired)
Robin Watts - ARM assembly routines for nice speedups on
several ports; improvements to the sound mixer
+ Website (code)
+ --------------
+ Fredrik Wendel
+
Website (content)
-----------------
All active team members
@@ -201,86 +227,25 @@ ScummVM Team
Joachim Eberhard - Numerous contributions to documentation
Matthew Hoops - Wiki editor
- FreeSCI Contributors
- --------------------
- Anders Baden Nielsen - PPC testing
- Bas Zoetekouw - Man pages, debian package management, CVS
- maintenance
- Carl Muckenhoupt - Sources to the SCI resource viewer tools that
- started it all
- Chris Kehler - Makefile enhancements
- Christoph Reichenbach - UN*X code, VM/Graphics/Sound/other
- infrastructure
- Christopher T. Lansdo - Original CVS maintainer, Alpha compatibility
- fixes
- Claudio Matsuoka - CVS snapshots, daily builds, BeOS and cygwin
- ports
- Dark Minister - SCI research (bytecode and parser)
- Dmitry Jemerov - Port to the Win32 platform, numerous bugfixes
- Emmanuel Jeandel - Bugfixes and bug reports
- Francois-R Boyer - MT-32 information and mapping code
- George Reid - FreeBSD package management
- Hubert Maier - AmigaOS 4 port
- Hugues Valois - Game selection menu
- Johannes Manhave - Document format translation
- Jordi Vilalta - Numerous code and website clean-up patches
- Lars Skovlund - Project maintenance, most documentation,
- bugfixes, SCI1 support
- Magnus Reftel - Heap implementation, Python class viewer,
- bugfixes
- Matt Hargett - Clean-ups, bugfixes, Hardcore QA, Win32
- Max Horn - SetJump implementation
- Paul David Doherty - Game version information
- Petr Vyhnak - The DCL-INFLATE algorithm, many Win32
- improvements
- Rainer Canavan - IRIX MIDI driver and bug fixes
- Rainer De Temple - SCI research
- Ravi I. - SCI0 sound resource specification
- Ruediger Hanke - Port to the MorphOS platform
- Rune Orsval - Configuration file editor
- Rickard Lind - MT32->GM MIDI mapping magic, sound research
- Rink Springer - Port to the DOS platform, several bug fixes
- Robey Pointer - Bug tracking system hosting
- Sergey Lapin - Port of Carl's type 2 decompression code
- Solomon Peachy - SDL ports and much of the sound subsystem
- Vyacheslav Dikonov - Config script improvements
- Walter van Niftrik - Ports to the Dreamcast and GP32 platforms
- Xiaojun Chen
- Sean Terrell
-
- Special thanks to Prof. Dr. Gary Nutt for allowing the FreeSCI VM
- extension as a course project in his Advanced OS course
-
- Special thanks to Bob Heitman and Corey Cole for their support of
- FreeSCI
-
Retired Team Members
--------------------
- Tore Anderson - Former Debian GNU/Linux maintainer
- Nicolas Bacca - Former WinCE porter
Ralph Brorsen - Help with GUI implementation
Jamieson Christian - iMUSE, MIDI, all things musical
- David Eriksson - Engines: FOTAQ
- Hans-Jorg Frieden - Former AmigaOS 4 packager
- Robert Goeffringmann - Original PS2 porter; Engines: BASS, BS1
- Jonathan Gray - Engines: SCUMM, HE, BS2
- Ruediger Hanke - Port: MorphOS
Felix Jakschitsch - Zak256 reverse engineering
- Oliver Kiehl - Engines: AGOS, BASS
Mutwin Kraus - Original MacOS porter
Peter Moraliyski - Port: GP32
- Juha Niemimaki - Former AmigaOS 4 packager
Jeremy Newman - Former webmaster
Lionel Ulmer - Port: X11
Won Star - Former GP32 porter
- David Symonds - Engines: AGI
Other contributions
*******************
Packages
--------
AmigaOS 4:
+ Hans-Jorg Frieden - (retired)
Hubert Maier
+ Juha Niemimaki - (retired)
Atari/FreeMiNT:
Keith Scroggins
@@ -290,6 +255,7 @@ Other contributions
Luc Schrijvers
Debian GNU/Linux:
+ Tore Anderson - (retired)
David Weinehall
Fedora / RedHat:
@@ -304,6 +270,7 @@ Other contributions
MorphOS:
Fabien Coeurjoly
+ Ruediger Hanke - (retired)
OS/2:
Paul Smedley
@@ -341,7 +308,6 @@ Other contributions
Thierry Crozat - Support for Broken Sword 1 Macintosh version
Martin Doucha - CinE engine objectification
Thomas Fach-Pedersen - ProTracker module player
- Benjamin Haisch - Heavily improved de-/encoder for DXA videos
Janne Huttunen - V3 actor mask support, Dig/FT SMUSH audio
Kovacs Endre Janos - Several fixes for Simon1
Jeroen Janssen - Numerous readability and bugfix patches
@@ -356,12 +322,66 @@ Other contributions
Tim Phillips - Initial MI1 CD music support
Quietust - Sound support for Amiga SCUMM V2/V3 games, MM
NES support
+ segra - Improved support for Apple II/C64 versions of MM
Andreas Roever - Broken Sword 1/2 MPEG2 cutscene support
Edward Rudd - Fixes for playing MP3 versions of MI1/Loom audio
Daniel Schepler - Final MI1 CD music support, initial Ogg Vorbis
support
Andre Souza - SDL-based OpenGL renderer
+ FreeSCI Contributors
+ --------------------
+ Anders Baden Nielsen - PPC testing
+ Bas Zoetekouw - Man pages, debian package management, CVS
+ maintenance
+ Carl Muckenhoupt - Sources to the SCI resource viewer tools that
+ started it all
+ Chris Kehler - Makefile enhancements
+ Christoph Reichenbach - UN*X code, VM/Graphics/Sound/other
+ infrastructure
+ Christopher T. Lansdo - Original CVS maintainer, Alpha compatibility
+ fixes
+ Claudio Matsuoka - CVS snapshots, daily builds, BeOS and cygwin
+ ports
+ Dark Minister - SCI research (bytecode and parser)
+ Dmitry Jemerov - Port to the Win32 platform, numerous bugfixes
+ Emmanuel Jeandel - Bugfixes and bug reports
+ Francois-R Boyer - MT-32 information and mapping code
+ George Reid - FreeBSD package management
+ Hubert Maier - AmigaOS 4 port
+ Hugues Valois - Game selection menu
+ Johannes Manhave - Document format translation
+ Jordi Vilalta - Numerous code and website clean-up patches
+ Lars Skovlund - Project maintenance, most documentation,
+ bugfixes, SCI1 support
+ Magnus Reftel - Heap implementation, Python class viewer,
+ bugfixes
+ Matt Hargett - Clean-ups, bugfixes, Hardcore QA, Win32
+ Max Horn - SetJump implementation
+ Paul David Doherty - Game version information
+ Petr Vyhnak - The DCL-INFLATE algorithm, many Win32
+ improvements
+ Rainer Canavan - IRIX MIDI driver and bug fixes
+ Rainer De Temple - SCI research
+ Ravi I. - SCI0 sound resource specification
+ Ruediger Hanke - Port to the MorphOS platform
+ Rune Orsval - Configuration file editor
+ Rickard Lind - MT32->GM MIDI mapping magic, sound research
+ Rink Springer - Port to the DOS platform, several bug fixes
+ Robey Pointer - Bug tracking system hosting
+ Sergey Lapin - Port of Carl's type 2 decompression code
+ Solomon Peachy - SDL ports and much of the sound subsystem
+ Vyacheslav Dikonov - Config script improvements
+ Walter van Niftrik - Ports to the Dreamcast and GP32 platforms
+ Xiaojun Chen
+ Sean Terrell
+
+ Special thanks to Prof. Dr. Gary Nutt for allowing the FreeSCI VM
+ extension as a course project in his Advanced OS course.
+
+ Special thanks to Bob Heitman and Corey Cole for their support of
+ FreeSCI.
+
And to all the contributors, users, and beta testers we've missed. Thanks!
Special thanks to
diff --git a/NEWS b/NEWS
index 60fc870a33..222bc4b87f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,13 @@
For a more comprehensive changelog for the latest experimental SVN code, see:
http://scummvm.svn.sourceforge.net/viewvc/scummvm/?view=log
+1.1.0 (????-??-??)
+ General:
+ - Added support for a custom SJIS font for FM-TOWNS and PC98 games.
+
+ KYRA:
+ - Adapted KYRA to support the custom SJIS font.
+
1.0.0 (2009-??-??)
New Games:
- Added support for Discworld.
@@ -18,6 +25,9 @@ For a more comprehensive changelog for the latest experimental SVN code, see:
- Added per-game GUI options.
- Improved Mass Add dialog.
+ New Ports:
+ - Added GP2X Wiz port.
+
AGI:
- Increased compatibility for Sierra games.
- Implemented all 'unknown' commands.
@@ -41,13 +51,12 @@ For a more comprehensive changelog for the latest experimental SVN code, see:
- Introduced a new savegame format to fix a fatal flaw of the old one,
breaking compatibility with old savegames made on big-endian systems.
+ Groovie:
+ - Increased microscope puzzle difficulty to match original.
+
KYRA:
- Added support for PC Speaker based music and sound effects.
- - Added support for 16 color dithering in Kyrandia PC-9801 (Japanese version
- only).
-
- New Ports:
- - Added GP2X Wiz port.
+ - Added support for 16 color dithering in Kyrandia PC-9801.
0.13.1 (2009-04-27)
AGOS:
diff --git a/README b/README
index 3f008bd707..0c27eaca95 100644
--- a/README
+++ b/README
@@ -771,10 +771,8 @@ site, please see the section on reporting bugs.
The Legend of Kyrandia:
- Amiga versions aren't supported
- Waxworks:
- - No music in the PC version
-
Humongous Entertainment games:
+ - Only the original load and save interface can be used.
- No support for printing images
diff --git a/backends/base-backend.h b/backends/base-backend.h
index 697577cd33..3fcca9c3b7 100644
--- a/backends/base-backend.h
+++ b/backends/base-backend.h
@@ -29,7 +29,7 @@
#include "common/system.h"
#include "backends/events/default/default-events.h"
-class BaseBackend : public OSystem, EventProvider {
+class BaseBackend : public OSystem, Common::EventSource {
public:
virtual Common::EventManager *getEventManager();
virtual void displayMessageOnOSD(const char *msg);
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index 4fdf96e57e..2efaec32f2 100644
--- a/backends/events/default/default-events.cpp
+++ b/backends/events/default/default-events.cpp
@@ -35,242 +35,38 @@
#include "engines/engine.h"
#include "gui/message.h"
-#define RECORD_SIGNATURE 0x54455354
-#define RECORD_VERSION 1
-
-void readRecord(Common::InSaveFile *inFile, uint32 &diff, Common::Event &event) {
- diff = inFile->readUint32LE();
-
- event.type = (Common::EventType)inFile->readUint32LE();
-
- switch(event.type) {
- case Common::EVENT_KEYDOWN:
- case Common::EVENT_KEYUP:
- event.kbd.keycode = (Common::KeyCode)inFile->readSint32LE();
- event.kbd.ascii = inFile->readUint16LE();
- event.kbd.flags = inFile->readByte();
- break;
- case Common::EVENT_MOUSEMOVE:
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_WHEELUP:
- case Common::EVENT_WHEELDOWN:
- event.mouse.x = inFile->readSint16LE();
- event.mouse.y = inFile->readSint16LE();
- break;
- default:
- break;
- }
-}
-
-void writeRecord(Common::OutSaveFile *outFile, uint32 diff, Common::Event &event) {
- outFile->writeUint32LE(diff);
-
- outFile->writeUint32LE((uint32)event.type);
-
- switch(event.type) {
- case Common::EVENT_KEYDOWN:
- case Common::EVENT_KEYUP:
- outFile->writeSint32LE(event.kbd.keycode);
- outFile->writeUint16LE(event.kbd.ascii);
- outFile->writeByte(event.kbd.flags);
- break;
- case Common::EVENT_MOUSEMOVE:
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_WHEELUP:
- case Common::EVENT_WHEELDOWN:
- outFile->writeSint16LE(event.mouse.x);
- outFile->writeSint16LE(event.mouse.y);
- break;
- default:
- break;
- }
-}
-
-DefaultEventManager::DefaultEventManager(EventProvider *boss) :
- _boss(boss),
+DefaultEventManager::DefaultEventManager(Common::EventSource *boss) :
_buttonState(0),
_modifierState(0),
_shouldQuit(false),
_shouldRTL(false),
_confirmExitDialogActive(false) {
- assert(_boss);
+ assert(boss);
- _recordFile = NULL;
- _recordTimeFile = NULL;
- _playbackFile = NULL;
- _playbackTimeFile = NULL;
- _timeMutex = g_system->createMutex();
- _recorderMutex = g_system->createMutex();
+ _dispatcher.registerSource(boss, false);
+ _dispatcher.registerSource(&_artificialEventSource, false);
- _eventCount = 0;
- _lastEventCount = 0;
- _lastMillis = 0;
-
- Common::String recordModeString = ConfMan.get("record_mode");
- if (recordModeString.compareToIgnoreCase("record") == 0) {
- _recordMode = kRecorderRecord;
- } else {
- if (recordModeString.compareToIgnoreCase("playback") == 0) {
- _recordMode = kRecorderPlayback;
- } else {
- _recordMode = kPassthrough;
- }
- }
-
- _recordFileName = ConfMan.get("record_file_name");
- if (_recordFileName.empty()) {
- _recordFileName = "record.bin";
- }
- _recordTempFileName = ConfMan.get("record_temp_file_name");
- if (_recordTempFileName.empty()) {
- _recordTempFileName = "record.tmp";
- }
- _recordTimeFileName = ConfMan.get("record_time_file_name");
- if (_recordTimeFileName.empty()) {
- _recordTimeFileName = "record.time";
- }
+ _dispatcher.registerObserver(this, kEventManPriority, false);
// Reset key repeat
_currentKeyDown.keycode = 0;
- // recorder stuff
- if (_recordMode == kRecorderRecord) {
- _recordCount = 0;
- _recordTimeCount = 0;
- _recordFile = g_system->getSavefileManager()->openForSaving(_recordTempFileName);
- _recordTimeFile = g_system->getSavefileManager()->openForSaving(_recordTimeFileName);
- _recordSubtitles = ConfMan.getBool("subtitles");
- }
-
- uint32 sign;
- uint32 version;
- uint32 randomSourceCount;
- if (_recordMode == kRecorderPlayback) {
- _playbackCount = 0;
- _playbackTimeCount = 0;
- _playbackFile = g_system->getSavefileManager()->openForLoading(_recordFileName);
- _playbackTimeFile = g_system->getSavefileManager()->openForLoading(_recordTimeFileName);
-
- if (!_playbackFile) {
- warning("Cannot open playback file %s. Playback was switched off", _recordFileName.c_str());
- _recordMode = kPassthrough;
- }
-
- if (!_playbackTimeFile) {
- warning("Cannot open playback time file %s. Playback was switched off", _recordTimeFileName.c_str());
- _recordMode = kPassthrough;
- }
- }
-
- if (_recordMode == kRecorderPlayback) {
- sign = _playbackFile->readUint32LE();
- if (sign != RECORD_SIGNATURE) {
- error("Unknown record file signature");
- }
- version = _playbackFile->readUint32LE();
-
- // conf vars
- ConfMan.setBool("subtitles", _playbackFile->readByte() != 0);
-
- _recordCount = _playbackFile->readUint32LE();
- _recordTimeCount = _playbackFile->readUint32LE();
- randomSourceCount = _playbackFile->readUint32LE();
- for (uint i = 0; i < randomSourceCount; ++i) {
- RandomSourceRecord rec;
- rec.name = "";
- uint32 sLen = _playbackFile->readUint32LE();
- for (uint j = 0; j < sLen; ++j) {
- char c = _playbackFile->readSByte();
- rec.name += c;
- }
- rec.seed = _playbackFile->readUint32LE();
- _randomSourceRecords.push_back(rec);
- }
-
- _hasPlaybackEvent = false;
- }
-
#ifdef ENABLE_VKEYBD
_vk = new Common::VirtualKeyboard();
#endif
#ifdef ENABLE_KEYMAPPER
_keymapper = new Common::Keymapper(this);
+ // EventDispatcher will automatically free the keymapper
+ _dispatcher.registerMapper(_keymapper);
_remap = false;
#endif
}
DefaultEventManager::~DefaultEventManager() {
-#ifdef ENABLE_KEYMAPPER
- delete _keymapper;
-#endif
#ifdef ENABLE_VKEYBD
delete _vk;
#endif
- g_system->lockMutex(_timeMutex);
- g_system->lockMutex(_recorderMutex);
- _recordMode = kPassthrough;
- g_system->unlockMutex(_timeMutex);
- g_system->unlockMutex(_recorderMutex);
-
- if (!artificialEventQueue.empty())
- artificialEventQueue.clear();
-
- if (_playbackFile != NULL) {
- delete _playbackFile;
- }
- if (_playbackTimeFile != NULL) {
- delete _playbackTimeFile;
- }
-
- if (_recordFile != NULL) {
- _recordFile->finalize();
- delete _recordFile;
- _recordTimeFile->finalize();
- delete _recordTimeFile;
-
- _playbackFile = g_system->getSavefileManager()->openForLoading(_recordTempFileName);
-
- assert(_playbackFile);
-
- _recordFile = g_system->getSavefileManager()->openForSaving(_recordFileName);
- _recordFile->writeUint32LE(RECORD_SIGNATURE);
- _recordFile->writeUint32LE(RECORD_VERSION);
-
- // conf vars
- _recordFile->writeByte(_recordSubtitles ? 1 : 0);
-
- _recordFile->writeUint32LE(_recordCount);
- _recordFile->writeUint32LE(_recordTimeCount);
-
- _recordFile->writeUint32LE(_randomSourceRecords.size());
- for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
- _recordFile->writeUint32LE(_randomSourceRecords[i].name.size());
- _recordFile->writeString(_randomSourceRecords[i].name);
- _recordFile->writeUint32LE(_randomSourceRecords[i].seed);
- }
-
- for (uint i = 0; i < _recordCount; ++i) {
- uint32 tempDiff;
- Common::Event tempEvent;
- readRecord(_playbackFile, tempDiff, tempEvent);
- writeRecord(_recordFile, tempDiff, tempEvent);
- }
-
- _recordFile->finalize();
- delete _recordFile;
- delete _playbackFile;
-
- //TODO: remove recordTempFileName'ed file
- }
- g_system->deleteMutex(_timeMutex);
- g_system->deleteMutex(_recorderMutex);
}
void DefaultEventManager::init() {
@@ -283,145 +79,14 @@ void DefaultEventManager::init() {
#endif
}
-bool DefaultEventManager::playback(Common::Event &event) {
-
- if (!_hasPlaybackEvent) {
- if (_recordCount > _playbackCount) {
- readRecord(_playbackFile, const_cast<uint32&>(_playbackDiff), _playbackEvent);
- _playbackCount++;
- _hasPlaybackEvent = true;
- }
- }
-
- if (_hasPlaybackEvent) {
- if (_playbackDiff <= (_eventCount - _lastEventCount)) {
- switch(_playbackEvent.type) {
- case Common::EVENT_MOUSEMOVE:
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_WHEELUP:
- case Common::EVENT_WHEELDOWN:
- g_system->warpMouse(_playbackEvent.mouse.x, _playbackEvent.mouse.y);
- break;
- default:
- break;
- }
- event = _playbackEvent;
- _hasPlaybackEvent = false;
- _lastEventCount = _eventCount;
- return true;
- }
- }
-
- return false;
-}
-
-void DefaultEventManager::record(Common::Event &event) {
- writeRecord(_recordFile, _eventCount - _lastEventCount, event);
-
- _recordCount++;
- _lastEventCount = _eventCount;
-}
-
-void DefaultEventManager::registerRandomSource(Common::RandomSource &rnd, const char *name) {
-
- if (_recordMode == kRecorderRecord) {
- RandomSourceRecord rec;
- rec.name = name;
- rec.seed = rnd.getSeed();
- _randomSourceRecords.push_back(rec);
- }
-
- if (_recordMode == kRecorderPlayback) {
- for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
- if (_randomSourceRecords[i].name == name) {
- rnd.setSeed(_randomSourceRecords[i].seed);
- _randomSourceRecords.remove_at(i);
- break;
- }
- }
- }
-}
-
-void DefaultEventManager::processMillis(uint32 &millis) {
- uint32 d;
- if (_recordMode == kPassthrough) {
- return;
- }
-
- g_system->lockMutex(_timeMutex);
- if (_recordMode == kRecorderRecord) {
- //Simple RLE compression
- d = millis - _lastMillis;
- if (d >= 0xff) {
- _recordTimeFile->writeByte(0xff);
- _recordTimeFile->writeUint32LE(d);
- } else {
- _recordTimeFile->writeByte(d);
- }
- _recordTimeCount++;
- }
-
- if (_recordMode == kRecorderPlayback) {
- if (_recordTimeCount > _playbackTimeCount) {
- d = _playbackTimeFile->readByte();
- if (d == 0xff) {
- d = _playbackTimeFile->readUint32LE();
- }
- millis = _lastMillis + d;
- _playbackTimeCount++;
- }
- }
-
- _lastMillis = millis;
- g_system->unlockMutex(_timeMutex);
-}
-
bool DefaultEventManager::pollEvent(Common::Event &event) {
uint32 time = g_system->getMillis();
- bool result;
+ bool result = false;
- if (!artificialEventQueue.empty()) {
- event = artificialEventQueue.pop();
+ _dispatcher.dispatch();
+ if (!_eventQueue.empty()) {
+ event = _eventQueue.pop();
result = true;
- } else {
- result = _boss->pollEvent(event);
-
-#ifdef ENABLE_KEYMAPPER
- if (result) {
- // send key press events to keymapper
- if (event.type == Common::EVENT_KEYDOWN) {
- if (_keymapper->mapKeyDown(event.kbd)) {
- result = false;
- }
- } else if (event.type == Common::EVENT_KEYUP) {
- if (_keymapper->mapKeyUp(event.kbd)) {
- result = false;
- }
- }
- }
-#endif
- }
-
- if (_recordMode != kPassthrough) {
-
- g_system->lockMutex(_recorderMutex);
- _eventCount++;
-
- if (_recordMode == kRecorderPlayback) {
- if (event.type != Common::EVENT_QUIT) {
- result = playback(event);
- }
- } else {
- if (_recordMode == kRecorderRecord) {
- if (result) {
- record(event);
- }
- }
- }
- g_system->unlockMutex(_recorderMutex);
}
if (result) {
@@ -598,13 +263,12 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
}
void DefaultEventManager::pushEvent(const Common::Event &event) {
-
// If already received an EVENT_QUIT, don't add another one
if (event.type == Common::EVENT_QUIT) {
if (!_shouldQuit)
- artificialEventQueue.push(event);
+ _artificialEventSource.addEvent(event);
} else
- artificialEventQueue.push(event);
+ _artificialEventSource.addEvent(event);
}
#endif // !defined(DISABLE_DEFAULT_EVENTMANAGER)
diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h
index 9d47104608..06db1dc027 100644
--- a/backends/events/default/default-events.h
+++ b/backends/events/default/default-events.h
@@ -27,8 +27,6 @@
#define BACKEND_EVENTS_DEFAULT_H
#include "common/events.h"
-#include "common/savefile.h"
-#include "common/mutex.h"
#include "common/queue.h"
namespace Common {
@@ -41,21 +39,7 @@ namespace Common {
}
-class EventProvider {
-public:
- virtual ~EventProvider() {}
- /**
- * Get the next event in the event queue.
- * @param event point to an Common::Event struct, which will be filled with the event data.
- * @return true if an event was retrieved.
- */
- virtual bool pollEvent(Common::Event &event) = 0;
-};
-
-
-class DefaultEventManager : public Common::EventManager {
- EventProvider *_boss;
-
+class DefaultEventManager : public Common::EventManager, Common::EventObserver {
#ifdef ENABLE_VKEYBD
Common::VirtualKeyboard *_vk;
#endif
@@ -65,7 +49,13 @@ class DefaultEventManager : public Common::EventManager {
bool _remap;
#endif
- Common::Queue<Common::Event> _artificialEventQueue;
+ Common::ArtificialEventSource _artificialEventSource;
+
+ Common::Queue<Common::Event> _eventQueue;
+ bool notifyEvent(const Common::Event &ev) {
+ _eventQueue.push(ev);
+ return true;
+ }
Common::Point _mousePos;
int _buttonState;
@@ -74,44 +64,6 @@ class DefaultEventManager : public Common::EventManager {
bool _shouldRTL;
bool _confirmExitDialogActive;
- class RandomSourceRecord {
- public:
- Common::String name;
- uint32 seed;
- };
- Common::Array<RandomSourceRecord> _randomSourceRecords;
-
- bool _recordSubtitles;
- volatile uint32 _recordCount;
- volatile uint32 _lastRecordEvent;
- volatile uint32 _recordTimeCount;
- Common::OutSaveFile *_recordFile;
- Common::OutSaveFile *_recordTimeFile;
- Common::MutexRef _timeMutex;
- Common::MutexRef _recorderMutex;
- volatile uint32 _lastMillis;
-
- volatile uint32 _playbackCount;
- volatile uint32 _playbackDiff;
- volatile bool _hasPlaybackEvent;
- volatile uint32 _playbackTimeCount;
- Common::Event _playbackEvent;
- Common::InSaveFile *_playbackFile;
- Common::InSaveFile *_playbackTimeFile;
-
- volatile uint32 _eventCount;
- volatile uint32 _lastEventCount;
-
- enum RecordMode {
- kPassthrough = 0,
- kRecorderRecord = 1,
- kRecorderPlayback = 2
- };
- volatile RecordMode _recordMode;
- Common::String _recordFileName;
- Common::String _recordTempFileName;
- Common::String _recordTimeFileName;
-
// for continuous events (keyDown)
enum {
kKeyRepeatInitialDelay = 400,
@@ -124,18 +76,13 @@ class DefaultEventManager : public Common::EventManager {
int keycode;
} _currentKeyDown;
uint32 _keyRepeatTime;
-
- void record(Common::Event &event);
- bool playback(Common::Event &event);
public:
- DefaultEventManager(EventProvider *boss);
+ DefaultEventManager(Common::EventSource *boss);
~DefaultEventManager();
virtual void init();
virtual bool pollEvent(Common::Event &event);
virtual void pushEvent(const Common::Event &event);
- virtual void registerRandomSource(Common::RandomSource &rnd, const char *name);
- virtual void processMillis(uint32 &millis);
virtual Common::Point getMousePos() const { return _mousePos; }
virtual int getButtonState() const { return _buttonState; }
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
index 7d888828c6..c0c454168c 100644
--- a/backends/keymapper/keymapper.cpp
+++ b/backends/keymapper/keymapper.cpp
@@ -168,6 +168,15 @@ void Keymapper::popKeymap() {
_activeMaps.pop();
}
+bool Keymapper::notifyEvent(const Common::Event &ev) {
+ if (ev.type == Common::EVENT_KEYDOWN)
+ return mapKeyDown(ev.kbd);
+ else if (ev.type == Common::EVENT_KEYUP)
+ return mapKeyUp(ev.kbd);
+ else
+ return false;
+}
+
bool Keymapper::mapKeyDown(const KeyState& key) {
return mapKey(key, true);
}
@@ -255,7 +264,7 @@ void Keymapper::executeAction(const Action *action, bool keyDown) {
}
evt.mouse = _eventMan->getMousePos();
- _eventMan->pushEvent(evt);
+ addEvent(evt);
}
}
diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h
index c82f64b0ed..f492882ca2 100644
--- a/backends/keymapper/keymapper.h
+++ b/backends/keymapper/keymapper.h
@@ -39,7 +39,7 @@
namespace Common {
-class Keymapper {
+class Keymapper : public Common::EventMapper, private Common::ArtificialEventSource {
public:
struct MapRecord {
@@ -134,6 +134,10 @@ public:
*/
void popKeymap();
+ // Implementation of the EventMapper interface
+ bool notifyEvent(const Common::Event &ev);
+ bool pollEvent(Common::Event &ev) { return Common::ArtificialEventSource::pollEvent(ev); }
+
/**
* @brief Map a key press event.
* If the active keymap contains a Action mapped to the given key, then
diff --git a/backends/platform/dc/dreamcast.mk b/backends/platform/dc/dreamcast.mk
index c33867b7f4..cd0d4748bd 100644
--- a/backends/platform/dc/dreamcast.mk
+++ b/backends/platform/dc/dreamcast.mk
@@ -6,8 +6,7 @@ ronindir = /usr/local/ronin
CC := $(CXX)
ASFLAGS := $(CXXFLAGS)
-
-dist : SCUMMVM.BIN plugin_dist
+dist : SCUMMVM.BIN IP.BIN plugin_dist
plugin_dist : plugins
@[ -z "$(PLUGINS)" ] || for p in $(or $(PLUGINS),none); do \
@@ -24,4 +23,12 @@ SCUMMVM.BIN : scummvm.bin
scummvm.bin : scummvm.elf
sh-elf-objcopy -S -R .stack -O binary $< $@
+IP.BIN : ip.txt
+ makeip $< $@
+
+ip.txt : $(srcdir)/backends/platform/dc/ip.txt.in
+ if [ x"$(VER_EXTRA)" = xsvn ]; then \
+ if [ -z "$(VER_SVNREV)" ]; then ver="SVN"; else ver="r$(VER_SVNREV)"; fi; \
+ else ver="V$(VERSION)"; fi; \
+ sed -e 's/[@]VERSION[@]/'"$$ver"/ -e 's/[@]DATE[@]/$(shell date '+%Y%m%d')/' < $< > $@
diff --git a/backends/platform/dc/ip.txt.in b/backends/platform/dc/ip.txt.in
new file mode 100644
index 0000000000..23424e0950
--- /dev/null
+++ b/backends/platform/dc/ip.txt.in
@@ -0,0 +1,11 @@
+Hardware ID : SEGA SEGAKATANA
+Maker ID : SEGA ENTERPRISES
+Device Info : 0000 CD-ROM1/1
+Area Symbols : JUE
+Peripherals : E000F10
+Product No : T0000
+Version : @VERSION@
+Release Date : @DATE@
+Boot Filename : SCUMMVM.BIN
+SW Maker Name : The ScummVM team
+Game Title : ScummVM
diff --git a/backends/platform/ds/arm9/source/fat/disc_io.h b/backends/platform/ds/arm9/source/fat/disc_io.h
index d9a3c67353..0fc83a7493 100644
--- a/backends/platform/ds/arm9/source/fat/disc_io.h
+++ b/backends/platform/ds/arm9/source/fat/disc_io.h
@@ -64,7 +64,7 @@
#endif
#ifdef NDS
- #include <nds/jtypes.h>
+ #include <nds/ndstypes.h>
#else
#include "gba_types.h"
#endif
diff --git a/backends/platform/ds/arm9/source/fat/gba_nds_fat.h b/backends/platform/ds/arm9/source/fat/gba_nds_fat.h
index f9746560e0..dd5c8ba85f 100644
--- a/backends/platform/ds/arm9/source/fat/gba_nds_fat.h
+++ b/backends/platform/ds/arm9/source/fat/gba_nds_fat.h
@@ -47,7 +47,7 @@
#endif
#ifdef NDS
- #include <nds/jtypes.h>
+ #include <nds/ndstypes.h>
#else
#include "gba_types.h"
#endif
diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/arm9/source/portdefs.h
index 7f22709206..560bd8ab4b 100644
--- a/backends/platform/ds/arm9/source/portdefs.h
+++ b/backends/platform/ds/arm9/source/portdefs.h
@@ -36,7 +36,7 @@ typedef unsigned int u32;
typedef signed int s32;
*/
-#include "nds/jtypes.h"
+#include "nds/ndstypes.h"
// Somebody removed these from scummsys.h, but they're still required, so I'm adding them here
diff --git a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h b/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
index 743d158d34..9344be68f9 100644
--- a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
+++ b/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
@@ -27,7 +27,7 @@
//////////////////////////////////////////////////////////////////////
-#include <nds/jtypes.h>
+#include <nds/ndstypes.h>
#include <nds/ipc.h>
//////////////////////////////////////////////////////////////////////
diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
new file mode 100644
index 0000000000..aeba1820c6
--- /dev/null
+++ b/backends/platform/ds/ds.mk
@@ -0,0 +1,111 @@
+# Repeat "all" target here, to make sure it is the first target
+# Currently disabled, so only arm7.bin gets build
+#all:
+
+
+
+# Files in this list will be optimisied for speed, otherwise they will be optimised for space
+OPTLIST := actor.cpp ds_main.cpp osystem_ds.cpp blitters.cpp fmopl.cpp rate.cpp isomap.cpp image.cpp gfx.cpp sprite.cpp actor_path.cpp actor_walk.cpp
+#OPTLIST :=
+
+# Compiler options for files which should be optimised for speed
+OPT_SPEED := -O3
+
+# Compiler options for files which should be optimised for space
+OPT_SIZE := -Os -mthumb
+
+
+#-mthumb -fno-gcse -fno-schedule-insns2
+
+
+OBJS := $(DATA_OBJS) $(LIBCARTRESET_OBJS) $(PORT_OBJS) $(COMPRESSOR_OBJS) $(FAT_OBJS)
+
+
+# TODO: Handle files in OPTLIST.
+# For this, the list should be made explicit. So, replace actor.cpp by path/to/actor.cpp --
+# in fact, there are several actor.cpp files, and right now all are "optimized", but
+# I think Neil only had the SAGA one in mind. Same for gfx.cpp
+
+
+
+
+
+
+#############################################################################
+#############################################################################
+#############################################################################
+
+
+#ndsdir = $(srcdir)/backends/platform/ds
+ndsdir = backends/platform/ds
+
+#############################################################################
+#
+# ARM7 rules.
+# For ARM7 files, we need different compiler flags, which leads to the
+# extra rules for .o files below
+#
+#############################################################################
+
+$(ndsdir)/arm7/arm7.bin: $(ndsdir)/arm7/arm7.elf
+
+$(ndsdir)/arm7/arm7.elf: \
+ $(ndsdir)/arm7/source/libcartreset/cartreset.o \
+ $(ndsdir)/arm7/source/main.o
+
+# HACK/FIXME: C compiler, for cartreset.c -- we should switch this to use CXX
+# as soon as possible.
+CC := $(DEVKITARM)/bin/arm-eabi-gcc
+
+# HACK/TODO: Pointer to objcopy. This should really be set by configure
+OBJCOPY := $(DEVKITARM)/bin/arm-eabi-objcopy
+
+#
+# Set various flags
+#
+ARM7_ARCH := -mthumb-interwork
+
+# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
+# *insists* it has a FPU or VFP, and it won't take no for an answer!
+ARM7_CFLAGS := -g -Wall -O2\
+ -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
+ -ffast-math \
+ $(ARM7_ARCH) \
+ -I$(srcdir)/$(ndsdir)/arm7/source/libcartreset \
+ -I$(srcdir)/$(ndsdir)/commoninclude \
+ -I$(DEVKITPRO)/libnds/include \
+ -I$(DEVKITPRO)/libnds/include/nds \
+ -DARM7
+
+ARM7_CXXFLAGS := $(ARM7_CFLAGS) -fno-exceptions -fno-rtti
+
+ARM7_LDFLAGS := -g $(ARM7_ARCH) -mno-fpu
+
+# HACK/FIXME: Define a custom build rule for cartreset.c.
+# We do this because it is a .c file, not a .cpp file and so is outside our
+# regular build system anyway. But this is *bad*. It should be changed into a
+# .cpp file and this rule be removed.
+%.o: %.c
+ $(MKDIR) $(*D)/$(DEPDIR)
+ $(CC) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
+
+
+# Set custom build flags for cartreset.o
+$(ndsdir)/arm7/source/libcartreset/cartreset.o: CXXFLAGS=$(ARM7_CFLAGS)
+$(ndsdir)/arm7/source/libcartreset/cartreset.o: CPPFLAGS=
+
+# Set custom build flags for main.o
+$(ndsdir)/arm7/source/main.o: CXXFLAGS=$(ARM7_CXXFLAGS)
+$(ndsdir)/arm7/source/main.o: CPPFLAGS=
+
+# Rule for creating ARM7 .bin files from .elf files
+%.bin: %.elf
+ @echo ------
+ @echo Building $@...
+ $(OBJCOPY) -O binary $< $@
+
+# Rule for creating ARM7 .elf files by linking .o files together with a special linker script
+%.elf:
+ @echo ------
+ @echo Building $@...
+ $(CXX) $(ARM7_LDFLAGS) -specs=ds_arm7.specs $+ -L/opt/devkitPro/libnds/lib -lnds7 -o $@
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
new file mode 100644
index 0000000000..16630dc070
--- /dev/null
+++ b/backends/platform/ds/module.mk
@@ -0,0 +1,71 @@
+MODULE := backends/platform/ds
+
+ARM7_MODULE_OBJS := \
+ arm7/source/main.o \
+ arm7/source/libcartreset/cartreset.o \
+
+PORT_OBJS := \
+ arm9/source/blitters_arm.o \
+ arm9/source/cdaudio.o \
+ arm9/source/dsmain.o \
+ ../../fs/ds/ds-fs.o \
+ arm9/source/gbampsave.o \
+ arm9/source/scummhelp.o \
+ arm9/source/osystem_ds.o \
+ arm9/source/portdefs.o \
+ arm9/source/ramsave.o \
+ arm9/source/touchkeyboard.o \
+ arm9/source/zipreader.o \
+ arm9/source/dsoptions.o \
+ arm9/source/keys.o \
+ arm9/source/wordcompletion.o \
+ arm9/source/interrupt.o
+
+ifdef USE_PROFILER
+ PORT_OBJS += arm9/source/profiler/cyg-profile.o
+endif
+
+DATA_OBJS := \
+ arm9/data/icons.o \
+ arm9/data/keyboard.o \
+ arm9/data/keyboard_pal.o \
+ arm9/data/default_font.o \
+ arm9/data/8x8font_tga.o
+
+COMPRESSOR_OBJS := #arm9/source/compressor/lz.o
+
+FAT_OBJS := arm9/source/fat/disc_io.o arm9/source/fat/gba_nds_fat.o\
+ arm9/source/fat/io_fcsr.o \
+ arm9/source/fat/io_m3cf.o \
+ arm9/source/fat/io_mpcf.o \
+ arm9/source/fat/io_sccf.o \
+ arm9/source/fat/io_m3sd.o \
+ arm9/source/fat/io_nmmc.o \
+ arm9/source/fat/io_scsd.o \
+ arm9/source/fat/io_scsd_asm.o \
+ arm9/source/fat/io_njsd.o \
+ arm9/source/fat/io_mmcf.o \
+ arm9/source/fat/io_sd_common.o \
+ arm9/source/fat/io_m3_common.o \
+ arm9/source/fat/io_dldi.o \
+ arm9/source/fat/m3sd.o
+
+
+# arm9/source/fat/io_cf_common.o arm9/source/fat/io_m3_common.o\
+# arm9/source/fat/io_sd_common.o arm9/source/fat/io_scsd_s.o \
+# arm9/source/fat/io_sc_common.o arm9/source/fat/io_sd_common.o
+
+LIBCARTRESET_OBJS :=
+ #arm9/source/libcartreset/cartreset.o
+
+
+MODULE_OBJS :=
+
+
+
+# TODO: Should add more dirs to MODULE_DIRS so that "make distclean" can remove .deps dirs.
+MODULE_DIRS += \
+ backends/platform/ds/
+
+# We don't use the rules.mk here on purpose
+OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)
diff --git a/backends/platform/gp2x/build/README-GP2X b/backends/platform/gp2x/build/README-GP2X
index 7e10fc484e..f95a974230 100644
--- a/backends/platform/gp2x/build/README-GP2X
+++ b/backends/platform/gp2x/build/README-GP2X
@@ -12,10 +12,19 @@ Contents:
* How to save <#How_to_save>
* Controller mappings <#Controller_mappings>
* Know issues <#Know_issues>
- * Major TODO's <#Major_TODOs>
+ * TODO's <#Major_TODOs>
* Additional resources/links <#Additional_resourceslinks>
* Credits <#Credits>
+------------------------------------------------------------------------
+
+Please refer to the:
+
+GP2X/GP2XWiz ScummVM Forum: <http://forums.scummvm.org/viewforum.php?f=14>
+WiKi: <http://wiki.scummvm.org/index.php/GP2X>
+
+for the most current information on the port and any updates to this
+documentation.
------------------------------------------------------------------------
About the backend/port
@@ -58,22 +67,6 @@ Included engines
Just because an engine is included does not mean any/all of its games
are supported. Please check game compatability for more infomation.
- * Scumm - (All games supported by ScummVM should work to some
- extent, using the hardware scalar if needed)
- * AGOS (AKA Simon) - (Simon the Sorcerer one and two).
- * Sky - (Beneath a Steel Sky)
- * Sword - (Broken Sword 1) - This engine uses the hardware scalar to
- downsize the graphics to fix on the GP2X. It is NOT very nice to
- look at.
- * Sword2 - (Broken Sword 2) - This engine uses the hardware scalar
- to downsize the graphics to fix on the GP2X. It is NOT very nice
- to look at.
- * Gob - (Goblins one)
- * Queen - (Flight of the Amazon Queen)
- * Kyra - (The Legend of Kyrandia)
-
-All other game engines are disabled in this release.
-
------------------------------------------------------------------------
Supported audio options
@@ -169,16 +162,10 @@ It happens very infrequently, both times it was in the DOTT CD intro.
Saving often is never a bad idea anyhow.
------------------------------------------------------------------------
-Major TODO's
+TODO's
Fix save support when using the Sky engine (Beneath a Steel Sky) - You
CAN'T save at the moment but auto save works.
-Look into inconsistencies with AGOS engine and map Y key to a button
-combination to allow clean quitting (Simon 1/2).
-Add splash-screen and pre-ScummVM config menu (CPU speed, LCD timings
-etc.) - Partly done.
-Fix TV out, maybe make it an option in the pre-ScummVM config menu.
-Any help appreciated :).
------------------------------------------------------------------------
Additional resources/links
@@ -186,7 +173,7 @@ Additional resources/links
* ScummVM WiKi GP2X page <http://wiki.scummvm.org/index.php/GP2X>
* ScummVM forums GP2X forum
<http://forums.scummvm.org/viewforum.php?f=14>
- * My own ScummVM page <http://www.distant-earth.com/scummvm> (for
+ * My own ScummVM page <http://scummvm.distant-earth.com/> (for
SVN/test builds)
* Main ScummVM site <http://www.scummvm.org> (for official supported
release builds)
@@ -197,4 +184,3 @@ Credits
Core ScummVM code (c) The ScummVM Team
Portions of the GP2X backend (c) John Willis
Detailed (c) information can be found within the source code
-
diff --git a/backends/platform/gp2x/build/README-GP2X.html b/backends/platform/gp2x/build/README-GP2X.html
deleted file mode 100644
index 1b5f1a4173..0000000000
--- a/backends/platform/gp2x/build/README-GP2X.html
+++ /dev/null
@@ -1,369 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <title>ScummVM - GP2X SPECIFIC README</title>
-
-
-</head>
-
-
-<body>
-
-<span style="font-weight: bold;">ScummVM -
-GP2X&nbsp;SPECIFIC README - HEAD SVN<br>
-
-</span>
-<hr style="width: 100%; height: 2px;"><br>
-
-<span style="font-weight: bold;">Contents:</span><br>
-
-<ul>
-
- <li><a href="#About_the_backendport">About the
-backend/port</a></li>
-
- <li><a href="#Game_compatibility">Game
-compatability</a></li>
-
- <li><a href="#Included_engines">Included engines</a></li>
-
- <li><a href="#Supported_audio_options">Supported
-audio options</a></li>
-
- <li><a href="#Supported_cut-scene_options">Supported
-cut-scene options</a></li>
-
- <li><a href="#Recent_changes">Recent changes</a></li>
-
- <li><a href="#How_to_save">How to save</a></li>
-
- <li><a href="#Controller_mappings">Controller
-mappings</a></li>
-
- <li><a href="#Know_issues">Know issues</a></li>
-
- <li><a href="#Major_TODOs">Major TODO's</a></li>
-
- <li><a href="#Additional_resourceslinks">Additional
-resources/links</a></li>
-
- <li><a href="#Credits">Credits</a></li>
-
-</ul>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="About_the_backendport"></a><span style="font-weight: bold;">About the backend/port</span><br>
-
-<br>
-
-This is the readme for the offficial GP2X ScummVM backend (also known
-as the GP2X port).<br>
-
-<br>
-
-This is an SVN test release of ScummVM for the GP2X, it would be
-appreciated
-if this SVN test distribution was not mirrored and that people be
-directed to <a href="http://www.distant-earth.com/scummvm">http://www.distant-earth.com/scummvm</a>
-instead for updated SVN builds.<br>
-
-<br>
-
-Full supported official releases of the GP2X ScummVM backend are made
-in line with main official releases and are avalalble from the <a href="http://www.scummvm.org/downloads.php">ScummVM
-downloads page</a>.<br>
-
-<br>
-
-This build is in an active state of development and as such no
-&lsquo;expected&rsquo; behavior can be guaranteed ;).<br>
-
-<br>
-
-SVN builds are quickly tested with firmware 2.0.0 for reference.<br>
-
-<br>
-
-Please refer to the <a href="http://forums.scummvm.org/viewforum.php?f=14">GP2X
-ScummVM forum</a> and <a href="http://wiki.scummvm.org/index.php/GP2X">WiKi</a>
-for the latest information on the port.<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Game_compatibility"></a><span style="font-weight: bold;">Game compatibility</span><br>
-
-<br>
-
-For information on the compatability of a specific game please refer to
-the <a href="http://wiki.scummvm.org/index.php/GP2X#Compatibility_List">GP2X
-compatability section of the ScummVM WiKi</a>.<br>
-
-<br>
-
-Please note the version and date of the ScummVM build you are running
-when reviewing the above list.<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Included_engines"></a><span style="font-weight: bold;">Included engines</span><br>
-
-<br>
-
-Just because an engine is included does not mean any/all of its games
-are supported. Please check game compatability for more infomation.<br>
-
-<ul>
-
- <li>Scumm - (All games supported by ScummVM should work to some
-extent, using the hardware scalar if needed)</li>
-
- <li>AGOS (AKA Simon) - (Simon the Sorcerer one and two).</li>
-
- <li>Sky - (Beneath a Steel Sky)</li>
-
- <li>Sword - (Broken Sword 1) - This engine uses the hardware
-scalar to
-downsize the graphics to fix on the GP2X. It is NOT very nice to look
-at.</li>
-
- <li>Sword2 - (Broken Sword 2) - This engine uses the hardware
-scalar to downsize the graphics to fix on the GP2X. It is NOT very nice
-to look at.</li>
-
- <li>Gob - (Goblins one)</li>
-
- <li>Queen - (Flight of the Amazon Queen)</li>
-
- <li>Kyra - (The Legend of Kyrandia)</li>
-
-</ul>
-
-All other game engines are disabled in this release.<br>
-
-<br style="font-weight: bold;">
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Supported_audio_options"></a><span style="font-weight: bold;">Supported audio options</span><br>
-
-<br>
-
-Raw audio.<br>
-
-MP3 audio.<br>
-
-OGG Vorbis audio.<br>
-
-<br>
-
-FLAC audio is currently unsupported.<br>
-
-<br>
-
-For best results use uncompressed audio in games.<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Supported_cut-scene_options"></a><span style="font-weight: bold;">Supported cut-scene options</span><br>
-
-<br>
-
-No cut scene compression options are currently supported. <br>
-
-<br>
-
-DXA video support will be added as soon as it is stable.<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Recent_changes"></a><span style="font-weight: bold;">Recent changes<br>
-
-<br>
-
-</span>Refined audio hacks to reduce audio delay a little more.<br>
-
-Enabled hardware scalar code.<br>
-
-Now built using SDL 1.2.9 for the parts of the port that use SDL (some
-parts now hit the hardware directly).<br>
-
-Enabled new launcher - (Ensure defaulttheme.zip is in the same folder
-as the executable).<br>
-
-Aspect Ratio Correction can now be disabled &lsquo;per
-game&rsquo;. When adding a game you can find this option on the GFX
-tab. <br>
-
-Note: This will cause the game to run with a black border at the bottom
-as it will be rendered to a 320*200 frame.<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="How_to_save"></a><span style="font-weight: bold;">How to save</span><br>
-
-<br>
-
-<span style="font-weight: bold;">NOTE:</span>
-Everything is saved to the SD card, saves are stored in the <span style="font-weight: bold;">saves</span> folder under
-your main ScummVM executable unless you set another save location.<br>
-
-<br>
-
-The configiration file for ScummVM (.scummvmrc) is stored in the
-same place as the ScummVM executable.<br>
-
-<br>
-
-The save process below is&nbsp;for Scumm engine games but the
-principle is the same for all.<br>
-
-<br>
-
-In Game.<br>
-
-<br>
-
-1. Right Trigger<br>
-
-2. Select SAVE with B<br>
-
-3. Select a position with B<br>
-
-4. Right trigger puts ? in the name box for some text.<br>
-
-5. Press B to save<br>
-
-<br>
-
-Basically the emulated keys you can use are equivelent to the values
-buttons are mapped to, <br>
-
-<br>
-
-I have a virtual keyboard like the GP32 one (left/right on the stick to
-pick chars) to add in at some point ;-)<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Controller_mappings"></a><span style="font-weight: bold;">Controller mappings</span><br>
-
-<br>
-
-<span style="font-weight: bold;">Mouse emulation:</span><br>
-
-<br>
-
-Stick: Move Pointer<br>
-
-Stick Click: &lsquo;light&rsquo; Left Click<br>
-
-B: Left click<br>
-
-X: Right click<br>
-
-<br>
-
-<span style="font-weight: bold;">Keyboard emulation:</span><br>
-
-<br>
-
-Start: Return<br>
-
-Select: Escape<br>
-
-Y: Space Bar (Pause)<br>
-
-Right Trigger: Game Menu (Save, Load, Quit etc.)<br>
-
-Volume Buttons: Increase and Decrease volume (5% per press)<br>
-
-<br>
-
-<span style="font-weight: bold;">Fancy button combos:</span><br>
-
-<br>
-
-NOTE: To use button combos press and hold the Left Trigger then...<br>
-
-<br>
-
-Y: Toggle "zoom" mode - Try it in larger games like Broken Sword.<br>
-
-Volume Buttons: Increase and Decrease subtitle speed (In SCUMM games)<br>
-
-Right Trigger: 0 (For skipping the copy protection in Monkey Island 2)<br>
-
-Select: Exit ScummVM completely (and gracefully)<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Know_issues"></a><span style="font-weight: bold;">Know issues</span><br>
-
-<br>
-
-Possible random crash (well SegFault). I have had this happen twice and
-have not tracked down the cause. <br>
-
-It happens very infrequently, both times it was in the DOTT CD intro.
-Saving often is never a bad idea anyhow.<br>
-
-<br>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Major_TODOs"></a><span style="font-weight: bold;">Major TODO's</span><br>
-
-<br>
-
-Fix save support when using the Sky engine (Beneath a Steel Sky) - You
-CAN'T save at the moment but auto save works.<br>
-
-Look into inconsistencies with AGOS engine and map Y key to a button
-combination to allow clean quitting (Simon 1/2).<br>
-
-Add splash-screen and pre-ScummVM config menu (CPU speed, LCD timings
-etc.) - Partly done.<br>
-
-Fix TV out, maybe make it an option in the pre-ScummVM config menu.<br>
-
-Any help appreciated :).<br>
-
-<br style="font-weight: bold;">
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Additional_resourceslinks"></a><span style="font-weight: bold;">Additional resources/links<br>
-
-<br>
-
-</span><span style="font-weight: bold;">Note:</span>
-When providing feedback,
-requests, forum posts, bug reports or anything like that always include
-a mention of the version of ScummVM you are using (the build version,
-date and time can be seen in the main game launcher window).<br>
-
-<ul>
-
- <li><a href="http://wiki.scummvm.org/index.php/GP2X">ScummVM
-WiKi GP2X page</a></li>
-
- <li><a href="http://forums.scummvm.org/viewforum.php?f=14">ScummVM
-forums GP2X forum</a></li>
-
- <li><a href="http://www.distant-earth.com/scummvm">My
-own ScummVM page</a> (for SVN/test builds)</li>
-
- <li><a href="http://www.scummvm.org">Main ScummVM
-site</a> (for official supported release builds)</li>
-
-</ul>
-
-<hr style="width: 100%; height: 2px;"><a style="font-weight: bold;" name="Credits"></a><span style="font-weight: bold;">Credits</span><br>
-
-<br>
-
-Core ScummVM code (c) The ScummVM Team<br>
-
-Portions of the GP2X backend (c) John Willis<br>
-
-Detailed (c) information can be found within the source code<br>
-
-<br>
-
-</body>
-</html>
diff --git a/backends/platform/gp2x/build/bundle.sh b/backends/platform/gp2x/build/bundle.sh
index 560f096ed4..c68c62191b 100755
--- a/backends/platform/gp2x/build/bundle.sh
+++ b/backends/platform/gp2x/build/bundle.sh
@@ -19,7 +19,6 @@ echo "Please put your save games in this dir" >> "scummvm-gp2x-`date '+%Y-%m-%d'
cp ./scummvm.gpe ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./scummvm.png ./scummvm-gp2x-`date '+%Y-%m-%d'`/
-cp ./README-GP2X.html ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./README-GP2X ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./mmuhack.o ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../scummvm.gp2x ./scummvm-gp2x-`date '+%Y-%m-%d'`/
diff --git a/backends/platform/gp2x/build/config-alleng.sh b/backends/platform/gp2x/build/config-alleng.sh
index 5724f39dc5..4a3526d50c 100755
--- a/backends/platform/gp2x/build/config-alleng.sh
+++ b/backends/platform/gp2x/build/config-alleng.sh
@@ -18,6 +18,6 @@ export DEFINES=-DNDEBUG
# Edit the configure line to suit.
cd ../../../..
./configure --backend=gp2x --disable-mt32emu --host=gp2x --disable-flac --disable-nasm --disable-hq-scalers --with-sdl-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6/bin --with-mpeg2-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-tremor --with-tremor-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-zlib --with-zlib-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-mad --with-mad-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-all-engines --enable-vkeybd
-# --enable-plugins --default-dynamic
+#--enable-plugins --default-dynamic
echo Generating config for GP2X complete. Check for errors.
diff --git a/backends/platform/gp2x/build/config.sh b/backends/platform/gp2x/build/config.sh
index 55954d6231..2bc49564f7 100755
--- a/backends/platform/gp2x/build/config.sh
+++ b/backends/platform/gp2x/build/config.sh
@@ -18,6 +18,6 @@ export DEFINES=-DNDEBUG
# Edit the configure line to suit.
cd ../../../..
./configure --backend=gp2x --disable-mt32emu --host=gp2x --disable-flac --disable-nasm --disable-hq-scalers --with-sdl-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6/bin --with-mpeg2-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-tremor --with-tremor-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-zlib --with-zlib-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-mad --with-mad-prefix=/opt/open2x/gcc-4.1.1-glibc-2.3.6 --enable-vkeybd
-# --enable-plugins --default-dynamic
+#--enable-plugins --default-dynamic
echo Generating config for GP2X complete. Check for errors.
diff --git a/backends/platform/gp2x/events.cpp b/backends/platform/gp2x/events.cpp
index 9a9a59765d..8cd034d2d5 100644
--- a/backends/platform/gp2x/events.cpp
+++ b/backends/platform/gp2x/events.cpp
@@ -35,7 +35,7 @@
#include "common/events.h"
// FIXME move joystick defines out and replace with confile file options
-// we should really allow users to map any key to a joystick button
+// we should really allow users to map any key to a joystick button using the keymapper.
#define JOY_DEADZONE 2200
#define JOY_XAXIS 0
@@ -273,7 +273,7 @@ bool OSystem_GP2X::pollEvent(Common::Event &event) {
Combos:
- GP2X_BUTTON_VOLUP & GP2X_BUTTON_VOLDOWN 0 (For Monkey 2 CP)
+ GP2X_BUTTON_VOLUP & GP2X_BUTTON_VOLDOWN 0 (For Monkey 2 CP) or Virtual Keyboard if enabled
GP2X_BUTTON_L & GP2X_BUTTON_SELECT Common::EVENT_QUIT (Calls Sync() to make sure SD is flushed)
GP2X_BUTTON_L & GP2X_BUTTON_Y Toggles setZoomOnMouse() for larger then 320*240 games to scale to the point + raduis.
GP2X_BUTTON_L & GP2X_BUTTON_START Common::EVENT_MAINMENU (ScummVM Global Main Menu)
@@ -434,29 +434,22 @@ bool OSystem_GP2X::pollEvent(Common::Event &event) {
}
break;
case GP2X_BUTTON_VOLUP:
- //if (GP2X_BUTTON_STATE_L == TRUE) {
- // displayMessageOnOSD("Setting CPU Speed at 230MHz");
- // GP2X_setCpuspeed(200);
- //event.kbd.keycode = Common::KEYCODE_PLUS;
- //event.kbd.ascii = mapKey(SDLK_PLUS, ev.key.keysym.mod, 0);
- //} else {
- GP2X_mixer_move_volume(1);
+ GP2X_HW::mixerMoveVolume(2);
+ if (GP2X_HW::volumeLevel == 100) {
+ displayMessageOnOSD("Maximum Volume");
+ } else {
displayMessageOnOSD("Increasing Volume");
- //}
+ }
break;
case GP2X_BUTTON_VOLDOWN:
- //if (GP2X_BUTTON_STATE_L == TRUE) {
- // displayMessageOnOSD("Setting CPU Speed at 60MHz");
- // GP2X_setCpuspeed(60);
- //event.kbd.keycode = Common::KEYCODE_MINUS;
- //event.kbd.ascii = mapKey(SDLK_MINUS, ev.key.keysym.mod, 0);
- //} else {
- GP2X_mixer_move_volume(0);
+ GP2X_HW::mixerMoveVolume(1);
+ if (GP2X_HW::volumeLevel == 0) {
+ displayMessageOnOSD("Minimal Volume");
+ } else {
displayMessageOnOSD("Decreasing Volume");
- //}
+ }
break;
-
}
}
return true;
diff --git a/backends/platform/gp2x/gp2x-hw.cpp b/backends/platform/gp2x/gp2x-hw.cpp
index fe02e029f7..38799ea7ad 100644
--- a/backends/platform/gp2x/gp2x-hw.cpp
+++ b/backends/platform/gp2x/gp2x-hw.cpp
@@ -48,6 +48,20 @@
#include <sys/time.h>
#include <unistd.h>
+namespace GP2X_HW {
+
+enum {
+ VOLUME_NOCHG = 0,
+ VOLUME_DOWN = 1,
+ VOLUME_UP = 2,
+ VOLUME_CHANGE_RATE = 8,
+ VOLUME_MIN = 0,
+ VOLUME_INITIAL = 70,
+ VOLUME_MAX = 100
+};
+
+int volumeLevel = VOLUME_INITIAL;
+
/* system registers */
static struct
{
@@ -61,14 +75,14 @@ static volatile unsigned short *MEM_REG;
#define SYS_CLK_FREQ 7372800
-void GP2X_device_init() {
+void deviceInit() {
// Open devices
if (!gp2x_dev[0]) gp2x_dev[0] = open("/dev/mixer", O_RDWR);
if (!gp2x_dev[1]) gp2x_dev[1] = open("/dev/batt", O_RDONLY);
if (!gp2x_dev[2]) gp2x_dev[2] = open("/dev/mem", O_RDWR);
}
-void GP2X_device_deinit() {
+void deviceDeinit() {
// Close devices
{
int i;
@@ -92,68 +106,35 @@ void GP2X_device_deinit() {
unpatchMMU();
}
-// Vairous mixer level fudges.
-// TODO: Clean up and merge quick hacks.
-
-void GP2X_mixer_set_volume(int L /*0..100*/, int R /*0..100*/) {
-
- /* Set an arbitrary percentage value for the hardware mixer volume.
-
- Parameters:
- L (0..100) - volume percentage for the left channel
- R (0..100) - volume percentage for the right channel
-
- Note:
- - A higher percentage than 100 will distort your sound.
- */
-
- unsigned char temp[4];
-
- if (L < 0) L = 0;
- if (L > GP2X_MAXVOL) L = GP2X_MAXVOL;
- if (R < 0) R = 0;
- if (R > GP2X_MAXVOL) R = GP2X_MAXVOL;
-
- temp[0]=(unsigned char)L;
- temp[1]=(unsigned char)R;
- temp[2]=temp[3]=0;
-
- //warning("GP2X_mixer_set_volume is about to set %d %d", L, R);
- ioctl(gp2x_dev[0], SOUND_MIXER_WRITE_PCM, temp);
-}
-
-int GP2X_mixer_get_volume() {
- int vol;
- ioctl(gp2x_dev[0], SOUND_MIXER_READ_PCM, &vol);
- //warning("GP2X_mixer_get_volume returned %d %d", (int)((vol & 0xff)), (int)((vol >> 8) & 0xff));
- return (int)((vol & 0xff));
+void mixerMoveVolume(int direction) {
+ if (volumeLevel <= 10) {
+ if (direction == VOLUME_UP) volumeLevel += VOLUME_CHANGE_RATE/2;
+ if (direction == VOLUME_DOWN) volumeLevel -= VOLUME_CHANGE_RATE/2;
+ } else {
+ if(direction == VOLUME_UP) volumeLevel += VOLUME_CHANGE_RATE;
+ if(direction == VOLUME_DOWN) volumeLevel -= VOLUME_CHANGE_RATE;
+ }
+
+ if (volumeLevel < VOLUME_MIN) volumeLevel = VOLUME_MIN;
+ if (volumeLevel > VOLUME_MAX) volumeLevel = VOLUME_MAX;
+
+ unsigned long soundDev = open("/dev/mixer", O_RDWR);
+
+ if(soundDev) {
+ int vol = ((volumeLevel << 8) | volumeLevel);
+ ioctl(soundDev, SOUND_MIXER_WRITE_PCM, &vol);
+ close(soundDev);
+ }
}
-void GP2X_mixer_move_volume(int UpDown) {
- // Raise volume 5% if 1 passed, lower 5% if 0.
- int curvol, newvol;
- ioctl(gp2x_dev[0], SOUND_MIXER_READ_PCM, &curvol);
- curvol = ((int)((curvol & 0xff)));
- newvol = ((int)((curvol & 0xff)));
- //warning("GP2X_mixer_move_volume got current volume @ %d", curvol);
- if (UpDown == 1) {
- newvol = (curvol + 5);
- } else if (UpDown == 0) {
- newvol = (curvol - 5);
- }
- //warning("GP2X_mixer_move_volume is about to set volume @ %d", newvol);
- GP2X_mixer_set_volume(newvol, newvol);
- return;
-}
-
-void GP2X_setCpuspeed(unsigned int mhz)
+void setCpuspeed(unsigned int mhz)
{
set_FCLK(mhz);
set_DCLK_Div(0);
set_920_Div(0);
}
-int GP2X_getBattLevel() {
+int getBattLevel() {
int devbatt;
unsigned short currentval=0;
devbatt = open("/dev/batt", O_RDONLY);
@@ -213,3 +194,6 @@ void gp2x_video_wait_vsync(void)
MEM_REG[0x2846>>1]=(MEM_REG[0x2846>>1] | 0x20) & ~2;
while (!(MEM_REG[0x2846>>1] & 2));
}
+
+} /* namespace GP2X_HW */
+
diff --git a/backends/platform/gp2x/gp2x-hw.h b/backends/platform/gp2x/gp2x-hw.h
index 89ad1093e4..7e72812cc4 100644
--- a/backends/platform/gp2x/gp2x-hw.h
+++ b/backends/platform/gp2x/gp2x-hw.h
@@ -31,16 +31,18 @@
#ifndef GP2X_HW_H
#define GP2X_HW_H
+namespace GP2X_HW {
+
#define GP2X_MAXVOL 100 // Highest level permitted by GP2X's mixer
#define SYS_CLK_FREQ 7372800 // Clock Frequency
-extern void GP2X_device_init();
-extern void GP2X_device_deinit();
-extern void GP2X_mixer_set_volume(int, int);
-extern int GP2X_mixer_get_volume();
-extern void GP2X_mixer_move_volume(int);
-extern void GP2X_setCpuspeed(unsigned int cpuspeed);
-extern int GP2X_getBattLevel();
+extern int volumeLevel;
+
+extern void deviceInit();
+extern void deviceDeinit();
+extern void mixerMoveVolume(int);
+extern void setCpuspeed(unsigned int cpuspeed);
+extern int getBattLevel();
extern void save_system_regs(void); /* save some registers */
extern void set_display_clock_div(unsigned div);
@@ -50,4 +52,6 @@ extern void set_DCLK_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+di
extern void Disable_940(void); /* 940t down */
extern void gp2x_video_wait_vsync(void);
+} /* namespace GP2X_HW */
+
#endif //GP2X_HW_H
diff --git a/backends/platform/gp2x/gp2x.cpp b/backends/platform/gp2x/gp2x.cpp
index 15b5e19e5d..3d416f8415 100644
--- a/backends/platform/gp2x/gp2x.cpp
+++ b/backends/platform/gp2x/gp2x.cpp
@@ -34,6 +34,7 @@
#include "common/archive.h"
#include "common/config-manager.h"
#include "common/debug.h"
+#include "common/EventRecorder.h"
#include "common/events.h"
#include "common/util.h"
@@ -232,15 +233,16 @@ void OSystem_GP2X::initBackend() {
// switch. Still, it's a potential future change to keep in mind.
_timer = new DefaultTimerManager();
_timerID = SDL_AddTimer(10, &timer_handler, _timer);
+ }
+
+ /* Initialise any GP2X specific stuff we may want (Batt Status, scaler etc.) */
+ GP2X_HW::deviceInit();
- // Initialise any GP2X specific stuff we may want (Volume, Batt Status etc.)
- GP2X_device_init();
+ /* Set Default hardware mixer volume to a preset level (VOLUME_INITIAL). This is done to 'reset' volume level if set by other apps. */
+ GP2X_HW::mixerMoveVolume(0);
// Set Default hardware mixer volume to a plesent level.
// This is done to 'reset' volume level if set by other apps.
- GP2X_mixer_set_volume(70, 70);
-
- }
//if (SDL_GP2X_MouseType() == 0) {
// // No mouse, F100 default state.
@@ -318,7 +320,7 @@ OSystem_GP2X::~OSystem_GP2X() {
uint32 OSystem_GP2X::getMillis() {
uint32 millis = SDL_GetTicks();
- getEventManager()->processMillis(millis);
+ g_eventRec.processMillis(millis);
return millis;
}
@@ -446,8 +448,7 @@ void OSystem_GP2X::quit() {
if (_joystick)
SDL_JoystickClose(_joystick);
- //CloseRam();
- GP2X_device_deinit();
+ GP2X_HW::deviceDeinit();
SDL_RemoveTimer(_timerID);
closeMixer();
diff --git a/backends/platform/gp2x/graphics.cpp b/backends/platform/gp2x/graphics.cpp
index 775c3afb73..a77afd88b7 100644
--- a/backends/platform/gp2x/graphics.cpp
+++ b/backends/platform/gp2x/graphics.cpp
@@ -30,6 +30,7 @@
#include "backends/platform/gp2x/gp2x-common.h"
#include "common/util.h"
+#include "common/mutex.h"
#include "graphics/font.h"
#include "graphics/fontman.h"
#include "graphics/scaler.h"
diff --git a/backends/platform/gp2xwiz/build/README-GP2XWIZ b/backends/platform/gp2xwiz/build/README-GP2XWIZ
index 95ac844a2c..ec8142a6f3 100644
--- a/backends/platform/gp2xwiz/build/README-GP2XWIZ
+++ b/backends/platform/gp2xwiz/build/README-GP2XWIZ
@@ -11,19 +11,27 @@ Contents:
* Recent changes <#Recent_changes>
* How to save <#How_to_save>
* Controller mappings <#Controller_mappings>
- * Know issues <#Know_issues>
- * Major TODO's <#Major_TODOs>
+ * Known issues <#Knonw_issues>
* Additional resources/links <#Additional_resourceslinks>
* Credits <#Credits>
+------------------------------------------------------------------------
+
+Please refer to the:
+
+GP2X/GP2XWiz ScummVM Forum: <http://forums.scummvm.org/viewforum.php?f=14>
+WiKi: <http://wiki.scummvm.org/index.php/GP2XWiz>
+
+for the most current information on the port and any updates to this
+documentation.
------------------------------------------------------------------------
About the backend/port
-This is the readme for the offficial GP2X WIZ ScummVM backend (also known as
-the GP2X WIZ port).
+This is the readme for the official GP2XWiz ScummVM backend (also known as
+the GP2XWiz port).
-This is an SVN test release of ScummVM for the GP2X WIZ, it would be
+This is an SVN test release of ScummVM for the GP2XWiz, 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.
@@ -35,19 +43,12 @@ downloads page <http://www.scummvm.org/downloads.php>.
This build is in an active state of development and as such no
"expected" behavior can be guaranteed ;).
-SVN builds are quickly tested with firmware 1.0.0 for reference.
-
-Please refer to the GP2X/GP2X WIZ ScummVM forum
-<http://forums.scummvm.org/viewforum.php?f=14> and WiKi
-<http://wiki.scummvm.org/index.php/GP2X> for the latest information on
-the port.
-
------------------------------------------------------------------------
Game compatibility
For information on the compatability of a specific game please refer to
-the GP2X compatability section of the ScummVM WiKi
-<http://wiki.scummvm.org/index.php/GP2X#Compatibility_List>.
+the GP2XWiz compatability section of the ScummVM WiKi
+<http://wiki.scummvm.org/index.php/GP2XWiz#Compatibility_List>.
Please note the version and date of the ScummVM build you are running
when reviewing the above list.
@@ -105,22 +106,20 @@ Right Trigger: Return
Select: Escape
Y: Space Bar (Pause)
Menu: Game Menu (Save, Load, Quit etc.)
-Volume Buttons: Increase and Decrease volume (5% per press)
+Volume Buttons: Increase and Decrease volume
Fancy button combos:
NOTE: To use button combos press and hold the Left Trigger then...
-Right Trigger: 0 (For skipping the copy protection in Monkey Island 2)
+Right Trigger: Display Virtual Keyboard
Menu: Bring up the Global main menu for ScummVM
Select: Exit ScummVM completely (and gracefully)
------------------------------------------------------------------------
-Know issues
+Known issues
-Possible random crash (well SegFault). I have had this happen twice and
-have not tracked down the cause.
-It happens very infrequently, both times it was in the DOTT CD intro.
+No major known issues
------------------------------------------------------------------------
Additional resources/links
@@ -128,7 +127,7 @@ Additional resources/links
* ScummVM WiKi GP2X page <http://wiki.scummvm.org/index.php/GP2X>
* ScummVM forums GP2X forum
<http://forums.scummvm.org/viewforum.php?f=14>
- * My own ScummVM page <http://www.distant-earth.com/scummvm> (for
+ * My own ScummVM page <http://scummvm.distant-earth.com/> (for
SVN/test builds)
* Main ScummVM site <http://www.scummvm.org> (for official supported
release builds)
diff --git a/backends/platform/gp2xwiz/build/bundle.sh b/backends/platform/gp2xwiz/build/bundle.sh
index 506dfcb742..492ba9e1c6 100755
--- a/backends/platform/gp2xwiz/build/bundle.sh
+++ b/backends/platform/gp2xwiz/build/bundle.sh
@@ -8,6 +8,8 @@ mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/saves"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/engine-data"
+mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib"
+
echo "Please put your save games in this dir" >> "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
@@ -27,6 +29,13 @@ cp ../../../../dists/pred.dic ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../dists/engine-data/* ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/engine-data
cp ../../../../plugins/* ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins
+# Copy over dynamic libs needed by the app (as the ones in the default filesystem are broken).
+f=`which arm-open2x-linux-g++`
+loc=`dirname "$f"`
+cp $loc/../lib/libz.so.1.2.3 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libz.so.1
+cp $loc/../lib/libvorbisidec.so.1.0.2 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libvorbisidec.so.1
+
+
echo Making Stripped exe.
arm-open2x-linux-strip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/scummvm.wiz
diff --git a/backends/platform/gp2xwiz/build/scummvm.gpe b/backends/platform/gp2xwiz/build/scummvm.gpe
index 037b81d937..42cc00a22a 100755
--- a/backends/platform/gp2xwiz/build/scummvm.gpe
+++ b/backends/platform/gp2xwiz/build/scummvm.gpe
@@ -1,5 +1,9 @@
#!/bin/sh
+# Export the location of any libs ScummVM depends on
+# (to avoid installing to the NAND and overwriting the broken ones there).
+export LD_LIBRARY_PATH=`pwd`/lib:$LD_LIBRARY_PATH
+
# Run ScummVM, important this bit.
./scummvm.wiz --fullscreen --gfx-mode=1x --config=$(pwd)/.scummvmrc
diff --git a/backends/platform/gp2xwiz/gp2xwiz-events.cpp b/backends/platform/gp2xwiz/gp2xwiz-events.cpp
index dfb36742dc..48c9af00ff 100644
--- a/backends/platform/gp2xwiz/gp2xwiz-events.cpp
+++ b/backends/platform/gp2xwiz/gp2xwiz-events.cpp
@@ -81,8 +81,13 @@ static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode) {
}
void OSystem_GP2XWIZ::fillMouseEvent(Common::Event &event, int x, int y) {
- event.mouse.x = x;
- event.mouse.y = y;
+ if(_videoMode.mode == GFX_HALF && !_overlayVisible){
+ event.mouse.x = x*2;
+ event.mouse.y = y*2;
+ } else {
+ event.mouse.x = x;
+ event.mouse.y = y;
+ }
// Update the "keyboard mouse" coords
_km.x = x;
@@ -203,7 +208,7 @@ bool OSystem_GP2XWIZ::pollEvent(Common::Event &event) {
Combos:
- GP2X_BUTTON_VOLUP & GP2X_BUTTON_VOLDOWN 0 (For Monkey 2 CP)
+ GP2X_BUTTON_VOLUP & GP2X_BUTTON_VOLDOWN 0 (For Monkey 2 CP) or Virtual Keyboard if enabled
GP2X_BUTTON_L & GP2X_BUTTON_SELECT Common::EVENT_QUIT (Calls Sync() to make sure SD is flushed)
GP2X_BUTTON_L & GP2X_BUTTON_MENU Common::EVENT_MAINMENU (ScummVM Global Main Menu)
GP2X_BUTTON_L & GP2X_BUTTON_A Common::EVENT_PREDICTIVE_DIALOG for predictive text entry box (AGI games)
diff --git a/backends/platform/gp2xwiz/gp2xwiz-graphics.cpp b/backends/platform/gp2xwiz/gp2xwiz-graphics.cpp
index 2482051286..90f2c821aa 100644
--- a/backends/platform/gp2xwiz/gp2xwiz-graphics.cpp
+++ b/backends/platform/gp2xwiz/gp2xwiz-graphics.cpp
@@ -24,10 +24,433 @@
*/
#include "backends/platform/gp2xwiz/gp2xwiz-sdl.h"
+#include "backends/platform/gp2xwiz/gp2xwiz-scaler.h" // TODO: Make GFX_HALF/HalfScale generic.
+#include "common/mutex.h"
+#include "graphics/font.h"
+#include "graphics/fontman.h"
+#include "graphics/scaler.h"
+#include "graphics/scaler/intern.h"
+#include "graphics/surface.h"
-/* TODO: Add code to ensure that overlay is always 320*240 and maybe invoke some custom scale code. */
+static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+ {"1x", "Fullscreen", GFX_NORMAL},
+// {"½x", "Downscale", GFX_HALF},
+ {0, 0, 0}
+};
+
+
+const OSystem::GraphicsMode *OSystem_GP2XWIZ::getSupportedGraphicsModes() const {
+ return s_supportedGraphicsModes;
+}
+
+int OSystem_GP2XWIZ::getDefaultGraphicsMode() const {
+ return GFX_NORMAL;
+}
+
+bool OSystem_GP2XWIZ::setGraphicsMode(int mode) {
+ Common::StackLock lock(_graphicsMutex);
+
+ assert(_transactionMode == kTransactionActive);
+
+ if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
+ return true;
+
+ int newScaleFactor = 1;
+
+ switch(mode) {
+ case GFX_NORMAL:
+ newScaleFactor = 1;
+ break;
+ case GFX_HALF:
+ newScaleFactor = 1;
+ break;
+ default:
+ warning("unknown gfx mode %d", mode);
+ return false;
+ }
+
+ _transactionDetails.normal1xScaler = (mode == GFX_NORMAL);
+ if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
+ _transactionDetails.needHotswap = true;
+
+ _transactionDetails.needUpdatescreen = true;
+
+ _videoMode.mode = mode;
+ _videoMode.scaleFactor = newScaleFactor;
+
+ return true;
+}
+
+void OSystem_GP2XWIZ::setGraphicsModeIntern() {
+ Common::StackLock lock(_graphicsMutex);
+ ScalerProc *newScalerProc = 0;
+
+ switch (_videoMode.mode) {
+ case GFX_NORMAL:
+ newScalerProc = Normal1x;
+ break;
+ case GFX_HALF:
+ newScalerProc = HalfScale;
+ break;
+
+ default:
+ error("Unknown gfx mode %d", _videoMode.mode);
+ }
+
+ _scalerProc = newScalerProc;
+
+ if (!_screen || !_hwscreen)
+ return;
+
+ // Blit everything to the screen
+ _forceFull = true;
+
+ // Even if the old and new scale factors are the same, we may have a
+ // different scaler for the cursor now.
+ blitCursor();
+}
+
+
+void OSystem_GP2XWIZ::initSize(uint w, uint h) {
+ assert(_transactionMode == kTransactionActive);
+
+ // Avoid redundant res changes
+ if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
+ return;
+
+ _videoMode.screenWidth = w;
+ _videoMode.screenHeight = h;
+ if(w > 320 || h > 240){
+ setGraphicsMode(GFX_HALF);
+ setGraphicsModeIntern();
+ toggleMouseGrab();
+ }
+
+ _cksumNum = (w * h / (8 * 8));
+
+ _transactionDetails.sizeChanged = true;
+
+ free(_dirtyChecksums);
+ _dirtyChecksums = (uint32 *)calloc(_cksumNum * 2, sizeof(uint32));
+}
bool OSystem_GP2XWIZ::loadGFXMode() {
+ _videoMode.overlayWidth = 320;
+ _videoMode.overlayHeight = 240;
+ _videoMode.fullscreen = true;
+
+ if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
+ _videoMode.aspectRatioCorrection = false;
+
OSystem_SDL::loadGFXMode();
}
+
+void OSystem_GP2XWIZ::drawMouse() {
+ if (!_mouseVisible || !_mouseSurface) {
+ _mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
+ return;
+ }
+
+ SDL_Rect dst;
+ int scale;
+ int width, height;
+ int hotX, hotY;
+
+ if(_videoMode.mode == GFX_HALF && !_overlayVisible){
+ dst.x = _mouseCurState.x/2;
+ dst.y = _mouseCurState.y/2;
+ } else {
+ dst.x = _mouseCurState.x;
+ dst.y = _mouseCurState.y;
+ }
+
+ if (!_overlayVisible) {
+ scale = _videoMode.scaleFactor;
+ width = _videoMode.screenWidth;
+ height = _videoMode.screenHeight;
+ dst.w = _mouseCurState.vW;
+ dst.h = _mouseCurState.vH;
+ hotX = _mouseCurState.vHotX;
+ hotY = _mouseCurState.vHotY;
+ } else {
+ scale = 1;
+ width = _videoMode.overlayWidth;
+ height = _videoMode.overlayHeight;
+ dst.w = _mouseCurState.rW;
+ dst.h = _mouseCurState.rH;
+ hotX = _mouseCurState.rHotX;
+ hotY = _mouseCurState.rHotY;
+ }
+
+ // The mouse is undrawn using virtual coordinates, i.e. they may be
+ // scaled and aspect-ratio corrected.
+
+ _mouseBackup.x = dst.x - hotX;
+ _mouseBackup.y = dst.y - hotY;
+ _mouseBackup.w = dst.w;
+ _mouseBackup.h = dst.h;
+
+ // We draw the pre-scaled cursor image, so now we need to adjust for
+ // scaling, shake position and aspect ratio correction manually.
+
+ if (!_overlayVisible) {
+ dst.y += _currentShakePos;
+ }
+
+ if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+ dst.y = real2Aspect(dst.y);
+
+ dst.x = scale * dst.x - _mouseCurState.rHotX;
+ dst.y = scale * dst.y - _mouseCurState.rHotY;
+ dst.w = _mouseCurState.rW;
+ dst.h = _mouseCurState.rH;
+
+ // Note that SDL_BlitSurface() and addDirtyRect() will both perform any
+ // clipping necessary
+
+ if (SDL_BlitSurface(_mouseSurface, NULL, _hwscreen, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+
+ // The screen will be updated using real surface coordinates, i.e.
+ // they will not be scaled or aspect-ratio corrected.
+ addDirtyRect(dst.x, dst.y, dst.w, dst.h, true);
+}
+
+void OSystem_GP2XWIZ::undrawMouse() {
+ const int x = _mouseBackup.x;
+ const int y = _mouseBackup.y;
+
+ // When we switch bigger overlay off mouse jumps. Argh!
+ // This is intended to prevent undrawing offscreen mouse
+ if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight))
+ return;
+
+ if (_mouseBackup.w != 0 && _mouseBackup.h != 0){
+ if(_videoMode.mode == GFX_HALF && !_overlayVisible){
+ addDirtyRect(x*2, y*2, _mouseBackup.w*2, _mouseBackup.h*2);
+ } else {
+ addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h);
+ }
+ }
+}
+
+void OSystem_GP2XWIZ::internUpdateScreen() {
+ SDL_Surface *srcSurf, *origSurf;
+ int height, width;
+ ScalerProc *scalerProc;
+ int scale1;
+
+#if defined (DEBUG) && ! defined(_WIN32_WCE) // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?)
+ assert(_hwscreen != NULL);
+ assert(_hwscreen->map->sw_data != NULL);
+#endif
+
+ // If the shake position changed, fill the dirty area with blackness
+ if (_currentShakePos != _newShakePos) {
+ SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor};
+
+ if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+ blackrect.h = real2Aspect(blackrect.h - 1) + 1;
+
+ SDL_FillRect(_hwscreen, &blackrect, 0);
+
+ _currentShakePos = _newShakePos;
+
+ _forceFull = true;
+ }
+
+ // Check whether the palette was changed in the meantime and update the
+ // screen surface accordingly.
+ if (_screen && _paletteDirtyEnd != 0) {
+ SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,
+ _paletteDirtyStart,
+ _paletteDirtyEnd - _paletteDirtyStart);
+
+ _paletteDirtyEnd = 0;
+
+ _forceFull = true;
+ }
+
+#ifdef USE_OSD
+ // OSD visible (i.e. non-transparent)?
+ if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+ // Updated alpha value
+ const int diff = SDL_GetTicks() - _osdFadeStartTime;
+ if (diff > 0) {
+ if (diff >= kOSDFadeOutDuration) {
+ // Back to full transparency
+ _osdAlpha = SDL_ALPHA_TRANSPARENT;
+ } else {
+ // Do a linear fade out...
+ const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
+ _osdAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
+ }
+ SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha);
+ _forceFull = true;
+ }
+ }
+#endif
+
+ if (!_overlayVisible) {
+ origSurf = _screen;
+ srcSurf = _tmpscreen;
+ width = _videoMode.screenWidth;
+ height = _videoMode.screenHeight;
+ scalerProc = _scalerProc;
+ scale1 = _videoMode.scaleFactor;
+ } else {
+ origSurf = _overlayscreen;
+ srcSurf = _tmpscreen2;
+ width = _videoMode.overlayWidth;
+ height = _videoMode.overlayHeight;
+ scalerProc = Normal1x;
+
+ scale1 = 1;
+ }
+
+ // Add the area covered by the mouse cursor to the list of dirty rects if
+ // we have to redraw the mouse.
+ if (_mouseNeedsRedraw)
+ undrawMouse();
+
+ // Force a full redraw if requested
+ if (_forceFull) {
+ _numDirtyRects = 1;
+ _dirtyRectList[0].x = 0;
+ _dirtyRectList[0].y = 0;
+ _dirtyRectList[0].w = width;
+ _dirtyRectList[0].h = height;
+ }
+
+ // Only draw anything if necessary
+ if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
+ SDL_Rect *r;
+ SDL_Rect dst;
+ uint32 srcPitch, dstPitch;
+ SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects;
+
+ for (r = _dirtyRectList; r != lastRect; ++r) {
+ dst = *r;
+ dst.x++; // Shift rect by one since 2xSai needs to access the data around
+ dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
+
+ if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+
+ SDL_LockSurface(srcSurf);
+ SDL_LockSurface(_hwscreen);
+
+ srcPitch = srcSurf->pitch;
+ dstPitch = _hwscreen->pitch;
+
+ for (r = _dirtyRectList; r != lastRect; ++r) {
+ register int dst_y = r->y + _currentShakePos;
+ register int dst_h = 0;
+ register int dst_w = r->w;
+ register int orig_dst_y = 0;
+ register int dst_x = r->x;
+ register int src_y;
+ register int src_x;
+
+ if (dst_y < height) {
+ dst_h = r->h;
+ if (dst_h > height - dst_y)
+ dst_h = height - dst_y;
+
+ orig_dst_y = dst_y;
+ src_x = dst_x;
+ src_y = dst_y;
+
+ if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+ dst_y = real2Aspect(dst_y);
+
+ assert(scalerProc != NULL);
+
+ if(_videoMode.mode == GFX_HALF && scalerProc == HalfScale){
+ if(dst_x%2==1){
+ dst_x--;
+ dst_w++;
+ }
+ if(dst_y%2==1){
+ dst_y--;
+ dst_h++;
+ }
+ src_x = dst_x;
+ src_y = dst_y;
+ dst_x = dst_x / 2;
+ dst_y = dst_y / 2;
+ }
+ scalerProc((byte *)srcSurf->pixels + (src_x * 2 + 2) + (src_y + 1) * srcPitch, srcPitch,
+ (byte *)_hwscreen->pixels + dst_x * 2 + dst_y * dstPitch, dstPitch, dst_w, dst_h);
+ }
+
+ if(_videoMode.mode == GFX_HALF && scalerProc == HalfScale){
+ r->w = r->w / 2;
+ r->h = dst_h / 2;
+ } else {
+ r->w = r->w;
+ r->h = dst_h;
+ }
+
+ r->x = dst_x;
+ r->y = dst_y;
+
+
+#ifndef DISABLE_SCALERS
+ if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible)
+ r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
+#endif
+ }
+ SDL_UnlockSurface(srcSurf);
+ SDL_UnlockSurface(_hwscreen);
+
+ // Readjust the dirty rect list in case we are doing a full update.
+ // This is necessary if shaking is active.
+ if (_forceFull) {
+ _dirtyRectList[0].y = 0;
+ _dirtyRectList[0].h = (_videoMode.mode == GFX_HALF) ? effectiveScreenHeight()/2 : effectiveScreenHeight();
+ }
+
+ drawMouse();
+
+#ifdef USE_OSD
+ if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+ SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+ }
+#endif
+ // Finally, blit all our changes to the screen
+ SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+ }
+
+ _numDirtyRects = 0;
+ _forceFull = false;
+ _mouseNeedsRedraw = false;
+}
+
+void OSystem_GP2XWIZ::showOverlay() {
+ if(_videoMode.mode == GFX_HALF){
+ _mouseCurState.x = _mouseCurState.x / 2;
+ _mouseCurState.y = _mouseCurState.y / 2;
+ }
+ OSystem_SDL::showOverlay();
+}
+
+void OSystem_GP2XWIZ::hideOverlay() {
+ if(_videoMode.mode == GFX_HALF){
+ _mouseCurState.x = _mouseCurState.x * 2;
+ _mouseCurState.y = _mouseCurState.y * 2;
+ }
+ OSystem_SDL::hideOverlay();
+}
+
+void OSystem_GP2XWIZ::warpMouse(int x, int y) {
+ if (_mouseCurState.x != x || _mouseCurState.y != y) {
+ if(_videoMode.mode == GFX_HALF && !_overlayVisible){
+ x = x / 2;
+ y = y / 2;
+ }
+ }
+ OSystem_SDL::warpMouse(x, y);
+}
diff --git a/backends/platform/gp2xwiz/gp2xwiz-hw.cpp b/backends/platform/gp2xwiz/gp2xwiz-hw.cpp
index 4d69915e27..4a86443aa7 100644
--- a/backends/platform/gp2xwiz/gp2xwiz-hw.cpp
+++ b/backends/platform/gp2xwiz/gp2xwiz-hw.cpp
@@ -48,7 +48,7 @@ enum {
VOLUME_UP = 2,
VOLUME_CHANGE_RATE = 8,
VOLUME_MIN = 0,
- VOLUME_INITIAL = 70,
+ VOLUME_INITIAL = 60,
VOLUME_MAX = 100
};
diff --git a/backends/platform/gp2xwiz/gp2xwiz-main.cpp b/backends/platform/gp2xwiz/gp2xwiz-main.cpp
index 4bd3f98211..394c3090c3 100644
--- a/backends/platform/gp2xwiz/gp2xwiz-main.cpp
+++ b/backends/platform/gp2xwiz/gp2xwiz-main.cpp
@@ -148,9 +148,9 @@ void OSystem_GP2XWIZ::initBackend() {
WIZ_HW::mixerMoveVolume(0);
/* Up default volume values as we use a seperate system level volume anyway. */
- ConfMan.registerDefault("music_volume", 220);
- ConfMan.registerDefault("sfx_volume", 220);
- ConfMan.registerDefault("speech_volume", 220);
+ ConfMan.registerDefault("music_volume", 192);
+ ConfMan.registerDefault("sfx_volume", 192);
+ ConfMan.registerDefault("speech_volume", 192);
/* Trigger autosave every 4 minutes - On low batts 5 mins is about your warning time. */
ConfMan.registerDefault("autosave_period", 4 * 60);
diff --git a/backends/platform/gp2xwiz/gp2xwiz-scaler.cpp b/backends/platform/gp2xwiz/gp2xwiz-scaler.cpp
new file mode 100644
index 0000000000..3a95280eab
--- /dev/null
+++ b/backends/platform/gp2xwiz/gp2xwiz-scaler.cpp
@@ -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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+#include "graphics/scaler/intern.h"
+#include "backends/platform/gp2xwiz/gp2xwiz-sdl.h"
+
+SDL_PixelFormat *screenPixelFormat;
+
+extern "C" {
+ void PocketPCHalfARM(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height, int mask, int round);
+ // Rounding constants and masks used for different pixel formats
+ int roundingconstants[] = { 0x00200802, 0x00201002 };
+ int redbluegreenMasks[] = { 0x03E07C1F, 0x07E0F81F };
+}
+
+void HalfScale(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
+ int maskUsed = (gBitFormat == 565);
+ PocketPCHalfARM(srcPtr, srcPitch, dstPtr, dstPitch, width, height, redbluegreenMasks[maskUsed],roundingconstants[maskUsed]);
+}
diff --git a/backends/platform/gp2xwiz/gp2xwiz-scaler.h b/backends/platform/gp2xwiz/gp2xwiz-scaler.h
new file mode 100644
index 0000000000..5867693dfb
--- /dev/null
+++ b/backends/platform/gp2xwiz/gp2xwiz-scaler.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GP2XWIZ_SCALER_H
+#define GP2XWIZ_SCALER_H
+
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "graphics/scaler.h"
+#include "graphics/scaler/intern.h"
+
+// FIXME: For now keep hacks in this header to save polluting the SDL backend.
+enum {
+ GFX_HALF = 12
+};
+
+// TODO/FIXME: Move this platform specific scaler into /graphics/scaler and properly merge with the WinCE PocketPCHalf that it is based on.
+DECLARE_SCALER(HalfScale);
+
+#endif
diff --git a/backends/platform/gp2xwiz/gp2xwiz-sdl.h b/backends/platform/gp2xwiz/gp2xwiz-sdl.h
index 8811f86edf..1f67624d5c 100644
--- a/backends/platform/gp2xwiz/gp2xwiz-sdl.h
+++ b/backends/platform/gp2xwiz/gp2xwiz-sdl.h
@@ -27,6 +27,7 @@
#define GP2XWIZ_SDL_H
#include "backends/platform/sdl/sdl.h"
+#include "backends/platform/gp2xwiz/gp2xwiz-scaler.h"
#include <SDL.h>
@@ -42,12 +43,24 @@ public:
OSystem_GP2XWIZ() {}
/* Graphics */
- bool loadGFXMode();
+ void initSize(uint w, uint h);
+ void setGraphicsModeIntern();
+ bool setGraphicsMode(int mode);
+ void internUpdateScreen();
+ const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
+ bool setGraphicsMode(const char *name);
+ int getDefaultGraphicsMode() const;
+ bool loadGFXMode();
+ void drawMouse();
+ void undrawMouse();
+ void showOverlay();
+ void hideOverlay();
/* Event Stuff */
bool pollEvent(Common::Event &event);
void moveStick();
void fillMouseEvent(Common::Event&, int, int);
+ void warpMouse(int, int);
bool remapKey(SDL_Event&, Common::Event&);
/* Platform Setup Stuff */
diff --git a/backends/platform/gp2xwiz/module.mk b/backends/platform/gp2xwiz/module.mk
index 03241f7b60..f2e27a7cce 100644
--- a/backends/platform/gp2xwiz/module.mk
+++ b/backends/platform/gp2xwiz/module.mk
@@ -1,6 +1,8 @@
MODULE := backends/platform/gp2xwiz
MODULE_OBJS := \
+ gp2xwiz-scaler.o \
+ ../wince/ARMscaler.o \
gp2xwiz-graphics.o \
gp2xwiz-events.o \
gp2xwiz-hw.o \
diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp
index 6d9f3fc6eb..8768dd90d4 100644
--- a/backends/platform/sdl/graphics.cpp
+++ b/backends/platform/sdl/graphics.cpp
@@ -481,7 +481,7 @@ bool OSystem_SDL::loadGFXMode() {
int hwW, hwH;
-#ifndef __MAEMO__
+#if !defined(__MAEMO__) && !defined(GP2XWIZ)
_videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
_videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
@@ -804,7 +804,7 @@ void OSystem_SDL::internUpdateScreen() {
for (r = _dirtyRectList; r != lastRect; ++r) {
dst = *r;
- dst.x++; // Shift rect by one since 2xSai needs to acces the data around
+ dst.x++; // Shift rect by one since 2xSai needs to access the data around
dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 105206ec07..5abeff3902 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -33,7 +33,7 @@
#include "common/archive.h"
#include "common/config-manager.h"
#include "common/debug.h"
-#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/util.h"
#ifdef UNIX
@@ -261,7 +261,7 @@ OSystem_SDL::~OSystem_SDL() {
uint32 OSystem_SDL::getMillis() {
uint32 millis = SDL_GetTicks();
- getEventManager()->processMillis(millis);
+ g_eventRec.processMillis(millis);
return millis;
}
diff --git a/backends/platform/wince/CEActionsPocket.cpp b/backends/platform/wince/CEActionsPocket.cpp
index 1f6eeb3770..45dbad12cc 100644
--- a/backends/platform/wince/CEActionsPocket.cpp
+++ b/backends/platform/wince/CEActionsPocket.cpp
@@ -133,12 +133,14 @@ void CEActionsPocket::initInstanceGame() {
bool is_tucker = (gameid == "tucker");
bool is_groovie = (gameid == "groovie");
bool is_tinsel = (gameid == "tinsel");
+ bool is_cruise = (gameid == "cruise");
+ bool is_made = (gameid == "made");
GUI_Actions::initInstanceGame();
// See if a right click mapping could be needed
if (is_sword1 || is_sword2 || is_sky || is_queen || is_comi || is_gob || is_tinsel ||
- is_samnmax || is_cine || is_touche || is_parallaction || is_drascula)
+ is_samnmax || is_cine || is_touche || is_parallaction || is_drascula || is_cruise)
_right_click_needed = true;
// See if a "hide toolbar" mapping could be needed
@@ -158,10 +160,10 @@ void CEActionsPocket::initInstanceGame() {
} else if (is_sky) {
_action_enabled[POCKET_ACTION_SAVE] = true;
_key_action[POCKET_ACTION_SAVE].setKey(Common::ASCII_F5, SDLK_F5);
- } else if (is_cine || is_drascula) {
+ } else if (is_cine || is_drascula || is_cruise) {
_action_enabled[POCKET_ACTION_SAVE] = true;
_key_action[POCKET_ACTION_SAVE].setKey(Common::ASCII_F10, SDLK_F10); // F10
- } else if (is_agi) {
+ } else if (is_agi || is_made) {
_action_enabled[POCKET_ACTION_SAVE] = true;
_key_action[POCKET_ACTION_SAVE].setKey(Common::ASCII_ESCAPE, SDLK_ESCAPE);
} else if (is_parallaction) {
@@ -177,7 +179,7 @@ void CEActionsPocket::initInstanceGame() {
// Quit
_action_enabled[POCKET_ACTION_QUIT] = true;
// Skip
- if (!is_cine && !is_parallaction && !is_groovie)
+ if (!is_cine && !is_parallaction && !is_groovie && !is_cruise && !is_made)
_action_enabled[POCKET_ACTION_SKIP] = true;
if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_tinsel ||
is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula || is_tucker)
@@ -214,6 +216,12 @@ void CEActionsPocket::initInstanceGame() {
_key_action[POCKET_ACTION_MULTI].setKey('V', SDLK_v, KMOD_SHIFT); // FT cheat : shift-V
// Key bind method
_action_enabled[POCKET_ACTION_BINDKEYS] = true;
+ // Disable double-tap right-click for convenience
+ if (is_tinsel || is_cruise)
+ if (!ConfMan.hasKey("no_doubletap_rightclick")) {
+ ConfMan.setBool("no_doubletap_rightclick", true);
+ ConfMan.flushToDisk();
+ }
}
diff --git a/backends/platform/wince/CEActionsSmartphone.cpp b/backends/platform/wince/CEActionsSmartphone.cpp
index 99f73bf37d..47733ae317 100644
--- a/backends/platform/wince/CEActionsSmartphone.cpp
+++ b/backends/platform/wince/CEActionsSmartphone.cpp
@@ -123,12 +123,14 @@ void CEActionsSmartphone::initInstanceGame() {
bool is_tucker = (gameid == "tucker");
bool is_groovie = (gameid == "groovie");
bool is_tinsel = (gameid == "tinsel");
+ bool is_cruise = (gameid == "cruise");
+ bool is_made = (gameid == "made");
GUI_Actions::initInstanceGame();
// See if a right click mapping could be needed
if (is_sword1 || is_sword2 || is_sky || is_queen || is_comi || is_gob || is_tinsel ||
- is_samnmax || is_cine || is_touche || is_parallaction || is_drascula)
+ is_samnmax || is_cine || is_touche || is_parallaction || is_drascula || is_cruise)
_right_click_needed = true;
// Initialize keys for different actions
@@ -141,10 +143,10 @@ void CEActionsSmartphone::initInstanceGame() {
} else if (is_sky) {
_action_enabled[SMARTPHONE_ACTION_SAVE] = true;
_key_action[SMARTPHONE_ACTION_SAVE].setKey(Common::ASCII_F5, SDLK_F5);
- } else if (is_cine || is_drascula) {
+ } else if (is_cine || is_drascula || is_cruise) {
_action_enabled[SMARTPHONE_ACTION_SAVE] = true;
_key_action[SMARTPHONE_ACTION_SAVE].setKey(Common::ASCII_F10, SDLK_F10); //F10
- } else if (is_agi) {
+ } else if (is_agi || is_made) {
_action_enabled[SMARTPHONE_ACTION_SAVE] = true;
_key_action[SMARTPHONE_ACTION_SAVE].setKey(Common::ASCII_ESCAPE, SDLK_ESCAPE);
} else if (is_parallaction) {
@@ -160,7 +162,8 @@ void CEActionsSmartphone::initInstanceGame() {
// Skip
_action_enabled[SMARTPHONE_ACTION_SKIP] = true;
if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_tinsel ||
- is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula || is_tucker || is_groovie)
+ is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula || is_tucker ||
+ is_groovie || is_cruise || is_made)
_key_action[SMARTPHONE_ACTION_SKIP].setKey(VK_ESCAPE);
else
_key_action[SMARTPHONE_ACTION_SKIP].setKey(KEY_ALL_SKIP);
@@ -178,6 +181,12 @@ void CEActionsSmartphone::initInstanceGame() {
_key_action[SMARTPHONE_ACTION_MULTI].setKey('V', SDLK_v, KMOD_SHIFT); // FT cheat : shift-V
// Bind keys
_action_enabled[SMARTPHONE_ACTION_BINDKEYS] = true;
+ // Disable double-tap right-click for convenience
+ if (is_tinsel || is_cruise)
+ if (!ConfMan.hasKey("no_doubletap_rightclick")) {
+ ConfMan.setBool("no_doubletap_rightclick", true);
+ ConfMan.flushToDisk();
+ }
}
diff --git a/backends/platform/wince/CEScaler.cpp b/backends/platform/wince/CEScaler.cpp
index bfdb74319d..d26db3190f 100644
--- a/backends/platform/wince/CEScaler.cpp
+++ b/backends/platform/wince/CEScaler.cpp
@@ -53,15 +53,6 @@ void PocketPCPortraitTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPt
}
MAKE_WRAPPER(PocketPCPortrait)
-void PocketPCRawPortrait(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
-
- while (height--) {
- memcpy(dstPtr, srcPtr, width*sizeof(uint16_t));
- srcPtr += srcPitch;
- dstPtr += dstPitch;
- }
-}
-
// Our version of an aspect scaler. Main difference is the out-of-place
// operation, omitting a straight blit step the sdl backend does. Also,
// tests show unaligned access errors with the stock aspect scaler.
@@ -234,8 +225,8 @@ void SmartphoneLandscape(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, ui
SmartphoneLandscapeARM(srcPtr, srcPitch, dstPtr, dstPitch, width, height, redbluegreenMasks[maskUsed]);
#else
if (gBitFormat == 565)
- SmartphoneLandscape<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
+ SmartphoneLandscapeTemplate<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
else
- SmartphoneLandscape<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
+ SmartphoneLandscapeTemplate<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
#endif
}
diff --git a/backends/platform/wince/CEgui/SDL_ImageResource.cpp b/backends/platform/wince/CEgui/SDL_ImageResource.cpp
index e1a9d911de..ce6ebd6382 100644
--- a/backends/platform/wince/CEgui/SDL_ImageResource.cpp
+++ b/backends/platform/wince/CEgui/SDL_ImageResource.cpp
@@ -60,7 +60,7 @@ namespace CEGUI {
_surface = SDL_LoadBMP_RW(surfaceData, 1);
return _surface;
- };
+ }
SDL_Surface* SDL_ImageResource::get() {
return _surface;
diff --git a/backends/platform/wince/Makefile b/backends/platform/wince/Makefile
index 1846029469..acade8ac9a 100644
--- a/backends/platform/wince/Makefile
+++ b/backends/platform/wince/Makefile
@@ -39,12 +39,12 @@ ENABLE_PARALLACTION = STATIC_PLUGIN
ENABLE_DRASCULA = STATIC_PLUGIN
ENABLE_GROOVIE = STATIC_PLUGIN
ENABLE_TUCKER = STATIC_PLUGIN
+ENABLE_TINSEL = STATIC_PLUGIN
+ENABLE_CRUISE = STATIC_PLUGIN
+ENABLE_MADE = STATIC_PLUGIN
#ENABLE_SCI = STATIC_PLUGIN
-#ENABLE_TINSEL = STATIC_PLUGIN
-#ENABLE_CRUISE = STATIC_PLUGIN
#ENABLE_IGOR = STATIC_PLUGIN
#ENABLE_M4 = STATIC_PLUGIN
-#ENABLE_MADE = STATIC_PLUGIN
########################################################################
## Pick which libraries you want to use here
@@ -76,6 +76,7 @@ USE_ARM_SOUND_ASM = 1
USE_ARM_SMUSH_ASM = 1
USE_ARM_GFX_ASM = 1
USE_ARM_COSTUME_ASM = 1
+USE_ARM_SCALER_ASM = 1
########################################################################
## Hopefully you shouldn't need to change anything below here. ##
@@ -167,6 +168,10 @@ ifdef USE_ARM_COSTUME_ASM
DEFINES += -DUSE_ARM_COSTUME_ASM
endif
+ifdef USE_ARM_SCALER_ASM
+DEFINES += -DUSE_ARM_SCALER_ASM
+endif
+
########################################################################
# Targets follow here
diff --git a/backends/platform/wince/README-WinCE.txt b/backends/platform/wince/README-WinCE.txt
index 6a289766a2..5b3215e34e 100644
--- a/backends/platform/wince/README-WinCE.txt
+++ b/backends/platform/wince/README-WinCE.txt
@@ -6,26 +6,19 @@ Release version: 0.13.0
New in this version
-------------------
-0.13.0:
-Important: Two builds for ScummVM CE
+1.0.0rc1:
+This version features optimized ARM assembly versions for the Smartphone,
+Normal2x and Normal2xAspect scalers, courtesy of Robin Watts. There should
+be a speed improvement when using these scalers.
-For this release, two binaries (executables) are provided. The first,
-with file name scummvm1.exe, includes support for the following engines:
- - scumm, sword1, sword2, queen, sky, lure, agi, touche
-while the second, with file name scummvm2.exe:
- - gob, cine, saga, kyra, agos, parallaction, drascula, groovie, tucker
-The user must make sure to execute the correct file for a game. All
-previously detected games will be shown in the launcher. Trying to launch
-a gob engine game with scummvm1.exe will not work.
-Detection also works as implied: scummvm1.exe will detect only the games
-for which it has support; the same holds for scummvm2.exe.
-This change has been done so users with less free memory can play more
-memory hungry games.
-
-Also noted are problems with flac support. Your mileage may vary. Please
-consider using ogg or mp3 for those games (smaller sizes are better for
-handheld devices too!)
+Also new is the aspect 2x upscaling mode, which is auto detected and used
+when the scaler is set to (normal) 2x mode and the panel is hidden. Hence,
+a 320x200 game running on a VGA or higher resolution device will be
+aspect scaled to fill the 640x480 screen.
+Be aware that Discworld 2 tries to allocate a big chunk of memory (10 MB)
+and this will fail on many devices (file under the not enough memory
+category).
------------------------------------------------------------------------
@@ -590,6 +583,20 @@ By default, the double tap to right click action is disabled in this game
as this interferes with the game's controls. This setting can be overridden
(see 'no_doubletap_rightclick' parameter above).
+-----------------
+-- Discworld 2 --
+-----------------
+
+Crashes at startup of this game are usually due to the high memory
+requirements of this game.
+
+-------------------------
+-- Cruise for a Corpse --
+-------------------------
+
+As with Discworld, the double-tap-to-right-click action interferes and will
+be disabled by default.
+
------------------------------------------------------------------------
Support
@@ -637,6 +644,27 @@ http://www.scummvm.org/
Old news follow ...
------------------------------------------------------------------------
+0.13.0:
+Important: Two builds for ScummVM CE
+
+For this release, two binaries (executables) are provided. The first,
+with file name scummvm1.exe, includes support for the following engines:
+ - scumm, sword1, sword2, queen, sky, lure, agi, touche
+while the second, with file name scummvm2.exe:
+ - gob, cine, saga, kyra, agos, parallaction, drascula, groovie, tucker
+The user must make sure to execute the correct file for a game. All
+previously detected games will be shown in the launcher. Trying to launch
+a gob engine game with scummvm1.exe will not work.
+Detection also works as implied: scummvm1.exe will detect only the games
+for which it has support; the same holds for scummvm2.exe.
+This change has been done so users with less free memory can play more
+memory hungry games.
+
+Also noted are problems with flac support. Your mileage may vary. Please
+consider using ogg or mp3 for those games (smaller sizes are better for
+handheld devices too!)
+
+
0.12.0:
- Improved SMUSH support (deprecated 'Smush_force_redraw' option)
No skipped frames in Full Throttle action sequences. The 'Smush_force_redraw'
diff --git a/backends/platform/wince/missing/missing.cpp b/backends/platform/wince/missing/missing.cpp
index f63ad72298..ac93e8f714 100644
--- a/backends/platform/wince/missing/missing.cpp
+++ b/backends/platform/wince/missing/missing.cpp
@@ -135,7 +135,7 @@ EXT_C char *getcwd(char *buffer, int maxlen) {
#endif
EXT_C void GetCurrentDirectory(int len, char *buf) {
getcwd(buf,len);
-};
+}
/*
Windows CE fopen has non-standard behavior -- not
diff --git a/backends/platform/wince/module.mk b/backends/platform/wince/module.mk
new file mode 100644
index 0000000000..5fefe08d79
--- /dev/null
+++ b/backends/platform/wince/module.mk
@@ -0,0 +1,21 @@
+MODULE := backends/platform/wince
+
+MODULE_OBJS := \
+ CEActionsPocket.o CEDevice.o CEScaler.o \
+ CEActionsSmartphone.o CELauncherDialog.o wince-sdl.o \
+ CEgui/GUIElement.o CEgui/Panel.o CEgui/SDL_ImageResource.o \
+ CEgui/ItemAction.o CEgui/PanelItem.o CEgui/Toolbar.o \
+ CEgui/ItemSwitch.o CEgui/PanelKeyboard.o CEgui/ToolbarHandler.o \
+ CEkeys/EventsBuffer.o \
+ ../../../gui/Actions.o ../../../gui/Key.o ../../../gui/KeysDialog.o \
+ ../sdl/sdl.o ../sdl/graphics.o ../sdl/events.o ../sdl/hardwarekeys.o \
+ missing/missing.o \
+ PocketSCUMM.o \
+ ARMscaler.o \
+ smartLandScale.o
+
+MODULE_DIRS += \
+ backends/platform/wince/
+
+# We don't use the rules.mk here on purpose
+OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)
diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp
index 8b2e0848f8..5d75b76805 100644
--- a/backends/platform/wince/wince-sdl.cpp
+++ b/backends/platform/wince/wince-sdl.cpp
@@ -403,9 +403,8 @@ static Uint32 timer_handler_wrapper(Uint32 interval) {
void OSystem_WINCE3::initBackend()
{
// Instantiate our own sound mixer
- // mixer init is postponed until a game engine is selected.
- if (_mixer == 0)
- _mixer = new Audio::MixerImpl(this);
+ // mixer init is rerun when a game engine is selected.
+ setupMixer();
// Create the timer. CE SDL does not support multiple timers (SDL_AddTimer).
// We work around this by using the SetTimer function, since we only use
@@ -792,11 +791,15 @@ void OSystem_WINCE3::setupMixer() {
SDL_AudioSpec desired;
int thread_priority;
+ compute_sample_rate();
if (_sampleRate == 0)
warning("setSoundCallback called with 0 _sampleRate. Audio will not work.");
+ else if (_mixer && _mixer->getOutputRate() == _sampleRate) {
+ debug(1, "Skipping sound mixer re-init: samplerate is good");
+ return;
+ }
memset(&desired, 0, sizeof(desired));
-
desired.freq = _sampleRate;
desired.format = AUDIO_S16SYS;
desired.channels = 2;
@@ -913,7 +916,6 @@ void OSystem_WINCE3::engineInit() {
//update_game_settings();
// finalize mixer init
- compute_sample_rate();
setupMixer();
}
@@ -1080,13 +1082,6 @@ void OSystem_WINCE3::update_game_settings() {
if (ConfMan.hasKey("no_doubletap_rightclick"))
_noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick");
- else if (gameid == "tinsel") {
- _noDoubleTapRMB = true;
- ConfMan.setBool("no_doubletap_rightclick", true);
- ConfMan.flushToDisk();
- }
-
- compute_sample_rate();
}
void OSystem_WINCE3::initSize(uint w, uint h) {
@@ -1147,13 +1142,13 @@ void OSystem_WINCE3::setGraphicsModeIntern() {
}
bool OSystem_WINCE3::update_scalers() {
- if (_videoMode.mode != GFX_NORMAL)
- return false;
-
_videoMode.aspectRatioCorrection = false;
if (CEDevice::hasPocketPCResolution()) {
- if ( (!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth))
+ if (_videoMode.mode != GFX_NORMAL)
+ return false;
+
+ if ((!_orientationLandscape && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth))
|| CEDevice::hasSquareQVGAResolution() ) {
if (getScreenWidth() != 320) {
_scaleFactorXm = 3;
@@ -1204,9 +1199,32 @@ bool OSystem_WINCE3::update_scalers() {
}
return true;
- }
+ } else if (CEDevice::hasWideResolution()) {
+#ifdef USE_ARM_SCALER_ASM
+ if ( _videoMode.mode == GFX_DOUBLESIZE && (_videoMode.screenWidth == 320 || !_videoMode.screenWidth) ) {
+ if ( !_panelVisible && !_overlayVisible && _canBeAspectScaled ) {
+ _scaleFactorXm = 2;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 12;
+ _scaleFactorYd = 5;
+ _scalerProc = Normal2xAspect;
+ _modeFlags = 0;
+ _videoMode.aspectRatioCorrection = true;
+ } else if ( (_panelVisible || _overlayVisible) && _canBeAspectScaled ) {
+ _scaleFactorXm = 2;
+ _scaleFactorXd = 1;
+ _scaleFactorYm = 2;
+ _scaleFactorYd = 1;
+ _scalerProc = Normal2x;
+ _modeFlags = 0;
+ }
+ return true;
+ }
+#endif
+ } else if (CEDevice::hasSmartphoneResolution()) {
+ if (_videoMode.mode != GFX_NORMAL)
+ return false;
- if (CEDevice::hasSmartphoneResolution()) {
if (_videoMode.screenWidth > 320)
error("Game resolution not supported on Smartphone");
#ifdef ARM
@@ -1373,8 +1391,8 @@ bool OSystem_WINCE3::loadGFXMode() {
displayWidth = _videoMode.screenWidth * _scaleFactorXm / _scaleFactorXd;
displayHeight = _videoMode.screenHeight * _scaleFactorYm / _scaleFactorYd;
} else {
- displayWidth = _videoMode.screenWidth;
- displayHeight = _videoMode.screenHeight;
+ displayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+ displayHeight = _videoMode.screenHeight* _videoMode.scaleFactor;
}
switch (_orientationLandscape) {
diff --git a/backends/platform/wince/wince.mk b/backends/platform/wince/wince.mk
new file mode 100644
index 0000000000..5551b27289
--- /dev/null
+++ b/backends/platform/wince/wince.mk
@@ -0,0 +1,5 @@
+all: PocketSCUMM.o
+
+PocketSCUMM.o: $(srcdir)/backends/platform/wince/PocketSCUMM.rc
+ mkdir -p backends/platform/wince
+ $(WINDRES) -I$(srcdir)/backends/platform/wince $(srcdir)/backends/platform/wince/PocketSCUMM.rc backends/platform/wince/PocketSCUMM.o
diff --git a/backends/vkeybd/packs/vkeybd_default.zip b/backends/vkeybd/packs/vkeybd_default.zip
index 9311b2a902..94c4649768 100644
--- a/backends/vkeybd/packs/vkeybd_default.zip
+++ b/backends/vkeybd/packs/vkeybd_default.zip
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/lowercase-symbols320x240.bmp b/backends/vkeybd/packs/vkeybd_default/lowercase-symbols320x240.bmp
index 02254aa3c7..08d40a0373 100644
--- a/backends/vkeybd/packs/vkeybd_default/lowercase-symbols320x240.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/lowercase-symbols320x240.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/lowercase-symbols640x480.bmp b/backends/vkeybd/packs/vkeybd_default/lowercase-symbols640x480.bmp
index 98c602acbe..3496c368f6 100644
--- a/backends/vkeybd/packs/vkeybd_default/lowercase-symbols640x480.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/lowercase-symbols640x480.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/lowercase320x240.bmp b/backends/vkeybd/packs/vkeybd_default/lowercase320x240.bmp
index 3270bf21e4..25579234bb 100644
--- a/backends/vkeybd/packs/vkeybd_default/lowercase320x240.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/lowercase320x240.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/lowercase640x480.bmp b/backends/vkeybd/packs/vkeybd_default/lowercase640x480.bmp
index 610f0844d0..398685618a 100644
--- a/backends/vkeybd/packs/vkeybd_default/lowercase640x480.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/lowercase640x480.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/uppercase-symbols320x240.bmp b/backends/vkeybd/packs/vkeybd_default/uppercase-symbols320x240.bmp
index 8fd645eb22..76a7f51839 100644
--- a/backends/vkeybd/packs/vkeybd_default/uppercase-symbols320x240.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/uppercase-symbols320x240.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/uppercase-symbols640x480.bmp b/backends/vkeybd/packs/vkeybd_default/uppercase-symbols640x480.bmp
index cbdfbf19e9..84d31443a7 100644
--- a/backends/vkeybd/packs/vkeybd_default/uppercase-symbols640x480.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/uppercase-symbols640x480.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/uppercase320x240.bmp b/backends/vkeybd/packs/vkeybd_default/uppercase320x240.bmp
index 6a1132314a..96ce1adbe4 100644
--- a/backends/vkeybd/packs/vkeybd_default/uppercase320x240.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/uppercase320x240.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/uppercase640x480.bmp b/backends/vkeybd/packs/vkeybd_default/uppercase640x480.bmp
index e635a3ccf2..1f938d7c17 100644
--- a/backends/vkeybd/packs/vkeybd_default/uppercase640x480.bmp
+++ b/backends/vkeybd/packs/vkeybd_default/uppercase640x480.bmp
Binary files differ
diff --git a/backends/vkeybd/packs/vkeybd_default/vkeybd_default.xml b/backends/vkeybd/packs/vkeybd_default/vkeybd_default.xml
index 982c4f45ef..86f39d3d4d 100644
--- a/backends/vkeybd/packs/vkeybd_default/vkeybd_default.xml
+++ b/backends/vkeybd/packs/vkeybd_default/vkeybd_default.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<keyboard initial_mode="lowercase" v_align="bottom" h_align="centre">
-
+<!-- coords key = "start x, start y, end x, end y" -->
<!-- Lowercase -->
<mode name="lowercase" resolutions="320x240,640x480">
<layout resolution="320x240" bitmap="lowercase320x240.bmp" transparent_color="255,0,255">
@@ -20,7 +20,8 @@
<area shape="rect" coords="235,26,253,43" target="f11" />
<area shape="rect" coords="255,26,272,45" target="f12" />
<area shape="rect" coords="276,27,310,43" target="del" />
- <area shape="rect" coords="276,47,308,64" target="backspace" />
+ <area shape="rect" coords="276,46,299,65" target="delete" />
+ <area shape="rect" coords="300,46,311,65" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="q" />
<area shape="rect" coords="57,68,75,86" target="w" />
@@ -76,85 +77,86 @@
<area shape="rect" coords="202,110,219,128" target="," />
<area shape="rect" coords="223,110,241,128" target="." />
<area shape="rect" coords="243,110,261,128" target="/" />
- <area shape="rect" coords="277,133,292,148" target="ok" />
- <area shape="rect" coords="292,133,309,148" target="cancel" />
+ <area shape="rect" coords="269,131,288,150" target="ok" />
+ <area shape="rect" coords="292,131,311,150" target="cancel" />
</map>
</layout>
<layout resolution="640x480" bitmap="lowercase640x480.bmp" transparent_color="255,0,255">
<map>
- <area shape="rect" coords="26,23,613,37" target="display_area" />
- <area shape="rect" coords="18,52,51,85" target="esc" />
- <area shape="rect" coords="100,51,135,88" target="f2" />
- <area shape="rect" coords="59,49,94,88" target="f1" />
- <area shape="rect" coords="142,53,176,89" target="f3" />
- <area shape="rect" coords="181,51,216,87" target="f4" />
- <area shape="rect" coords="223,52,258,88" target="f5" />
- <area shape="rect" coords="265,52,299,89" target="f6" />
- <area shape="rect" coords="306,51,341,90" target="f7" />
- <area shape="rect" coords="347,53,382,89" target="f8" />
- <area shape="rect" coords="389,49,424,88" target="f9" />
- <area shape="rect" coords="431,52,464,89" target="f10" />
- <area shape="rect" coords="470,53,506,88" target="f11" />
- <area shape="rect" coords="511,52,546,90" target="f12" />
- <area shape="rect" coords="552,55,620,87" target="del" />
- <area shape="rect" coords="553,94,618,129" target="backspace" />
- <area shape="rect" coords="17,136,66,171" target="tab" />
- <area shape="rect" coords="73,137,108,171" target="q" />
- <area shape="rect" coords="114,136,150,172" target="w" />
- <area shape="rect" coords="157,134,189,171" target="e" />
- <area shape="rect" coords="197,135,232,171" target="r" />
- <area shape="rect" coords="239,135,274,172" target="t" />
- <area shape="rect" coords="282,136,317,173" target="y" />
- <area shape="rect" coords="322,135,359,173" target="u" />
- <area shape="rect" coords="364,134,399,172" target="i" />
- <area shape="rect" coords="404,135,440,171" target="o" />
- <area shape="rect" coords="446,136,480,172" target="p" />
- <area shape="rect" coords="89,177,127,216" target="a" />
- <area shape="rect" coords="131,177,169,214" target="s" />
- <area shape="rect" coords="173,178,209,215" target="d" />
- <area shape="rect" coords="215,178,250,214" target="f" />
- <area shape="rect" coords="256,178,291,214" target="g" />
- <area shape="rect" coords="299,176,332,214" target="h" />
- <area shape="rect" coords="339,178,374,215" target="j" />
- <area shape="rect" coords="379,178,415,215" target="k" />
- <area shape="rect" coords="421,178,457,215" target="l" />
- <area shape="rect" coords="546,179,622,214" target="enter" />
- <area shape="rect" coords="19,221,101,256" target="shift" />
- <area shape="rect" coords="17,179,84,213" target="caps" />
- <area shape="rect" coords="117,220,152,256" target="z" />
- <area shape="rect" coords="158,220,192,256" target="x" />
- <area shape="rect" coords="198,219,233,256" target="c" />
- <area shape="rect" coords="240,220,276,257" target="v" />
- <area shape="rect" coords="283,219,316,255" target="b" />
- <area shape="rect" coords="324,220,359,256" target="n" />
- <area shape="rect" coords="365,220,399,257" target="m" />
- <area shape="rect" coords="542,219,623,257" target="symbols" />
- <area shape="rect" coords="19,260,68,296" target="ctrl" />
- <area shape="rect" coords="76,261,123,295" target="alt" />
- <area shape="rect" coords="135,261,525,297" target="space" />
- <area shape="rect" coords="16,95,53,129" target="|" />
- <area shape="rect" coords="57,95,92,129" target="1" />
- <area shape="rect" coords="100,94,134,130" target="2" />
- <area shape="rect" coords="140,93,174,131" target="3" />
- <area shape="rect" coords="182,93,217,130" target="4" />
- <area shape="rect" coords="222,93,258,132" target="5" />
- <area shape="rect" coords="265,94,299,131" target="6" />
- <area shape="rect" coords="305,94,341,129" target="7" />
- <area shape="rect" coords="348,93,382,128" target="8" />
- <area shape="rect" coords="389,94,423,130" target="9" />
- <area shape="rect" coords="431,93,465,130" target="0" />
- <area shape="rect" coords="471,94,505,131" target="-" />
- <area shape="rect" coords="511,93,546,131" target="=" />
- <area shape="rect" coords="488,136,522,172" target="[" />
- <area shape="rect" coords="529,135,565,173" target="]" />
- <area shape="rect" coords="569,136,620,172" target="#" />
- <area shape="rect" coords="462,177,498,214" target=";" />
- <area shape="rect" coords="503,178,539,214" target="’" />
- <area shape="rect" coords="405,220,440,256" target="," />
- <area shape="rect" coords="447,220,483,256" target="." />
- <area shape="rect" coords="487,220,524,256" target="/" />
- <area shape="rect" coords="555,266,585,298" target="ok" />
- <area shape="rect" coords="585,266,619,298" target="cancel" />
+ <area shape="rect" coords="26,23,613,37" target="display_area" />
+ <area shape="rect" coords="18,52,51,85" target="esc" />
+ <area shape="rect" coords="100,51,135,88" target="f2" />
+ <area shape="rect" coords="59,49,94,88" target="f1" />
+ <area shape="rect" coords="142,53,176,89" target="f3" />
+ <area shape="rect" coords="181,51,216,87" target="f4" />
+ <area shape="rect" coords="223,52,258,88" target="f5" />
+ <area shape="rect" coords="265,52,299,89" target="f6" />
+ <area shape="rect" coords="306,51,341,90" target="f7" />
+ <area shape="rect" coords="347,53,382,89" target="f8" />
+ <area shape="rect" coords="389,49,424,88" target="f9" />
+ <area shape="rect" coords="431,52,464,89" target="f10" />
+ <area shape="rect" coords="470,53,506,88" target="f11" />
+ <area shape="rect" coords="511,52,546,90" target="f12" />
+ <area shape="rect" coords="552,55,620,87" target="del" />
+ <area shape="rect" coords="552,93,598,131" target="delete" />
+ <area shape="rect" coords="601,93,623,131" target="backspace" />
+ <area shape="rect" coords="17,136,66,171" target="tab" />
+ <area shape="rect" coords="73,137,108,171" target="q" />
+ <area shape="rect" coords="114,136,150,172" target="w" />
+ <area shape="rect" coords="157,134,189,171" target="e" />
+ <area shape="rect" coords="197,135,232,171" target="r" />
+ <area shape="rect" coords="239,135,274,172" target="t" />
+ <area shape="rect" coords="282,136,317,173" target="y" />
+ <area shape="rect" coords="322,135,359,173" target="u" />
+ <area shape="rect" coords="364,134,399,172" target="i" />
+ <area shape="rect" coords="404,135,440,171" target="o" />
+ <area shape="rect" coords="446,136,480,172" target="p" />
+ <area shape="rect" coords="89,177,127,216" target="a"/>
+ <area shape="rect" coords="131,177,169,214" target="s" />
+ <area shape="rect" coords="173,178,209,215" target="d" />
+ <area shape="rect" coords="215,178,250,214" target="f" />
+ <area shape="rect" coords="256,178,291,214" target="g" />
+ <area shape="rect" coords="299,176,332,214" target="h" />
+ <area shape="rect" coords="339,178,374,215" target="j" />
+ <area shape="rect" coords="379,178,415,215" target="k" />
+ <area shape="rect" coords="421,178,457,215" target="l" />
+ <area shape="rect" coords="546,179,622,214" target="enter" />
+ <area shape="rect" coords="19,221,101,256" target="shift" />
+ <area shape="rect" coords="17,179,84,213" target="caps" />
+ <area shape="rect" coords="117,220,152,256" target="z" />
+ <area shape="rect" coords="158,220,192,256" target="x" />
+ <area shape="rect" coords="198,219,233,256" target="c" />
+ <area shape="rect" coords="240,220,276,257" target="v" />
+ <area shape="rect" coords="283,219,316,255" target="b" />
+ <area shape="rect" coords="324,220,359,256" target="n" />
+ <area shape="rect" coords="365,220,399,257" target="m" />
+ <area shape="rect" coords="542,219,623,257" target="symbols" />
+ <area shape="rect" coords="19,260,68,296" target="ctrl" />
+ <area shape="rect" coords="76,261,123,295" target="alt" />
+ <area shape="rect" coords="135,261,525,297" target="space" />
+ <area shape="rect" coords="16,95,53,129" target="|" />
+ <area shape="rect" coords="57,95,92,129" target="1" />
+ <area shape="rect" coords="100,94,134,130" target="2" />
+ <area shape="rect" coords="140,93,174,131" target="3" />
+ <area shape="rect" coords="182,93,217,130" target="4" />
+ <area shape="rect" coords="222,93,258,132" target="5" />
+ <area shape="rect" coords="265,94,299,131" target="6" />
+ <area shape="rect" coords="305,94,341,129" target="7" />
+ <area shape="rect" coords="348,93,382,128" target="8" />
+ <area shape="rect" coords="389,94,423,130" target="9" />
+ <area shape="rect" coords="431,93,465,130" target="0" />
+ <area shape="rect" coords="471,94,505,131" target="-" />
+ <area shape="rect" coords="511,93,546,131" target="=" />
+ <area shape="rect" coords="488,136,522,172" target="[" />
+ <area shape="rect" coords="529,135,565,173" target="]" />
+ <area shape="rect" coords="569,136,620,172" target="#" />
+ <area shape="rect" coords="462,177,498,214" target=";" />
+ <area shape="rect" coords="503,178,539,214" target="’" />
+ <area shape="rect" coords="405,220,440,256" target="," />
+ <area shape="rect" coords="447,220,483,256" target="." />
+ <area shape="rect" coords="487,220,524,256" target="/" />
+ <area shape="rect" coords="538,266,576,298" target="ok" />
+ <area shape="rect" coords="585,266,622,298" target="cancel" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
@@ -230,6 +232,7 @@
<event name="ok" type="submit" />
<event name="cancel" type="cancel" />
<event name="quit" type="submit" />
+ <event name="delete" type="delete" />
</mode>
<!-- Uppercase -->
@@ -251,7 +254,8 @@
<area shape="rect" coords="235,26,253,43" target="f11" />
<area shape="rect" coords="255,26,272,45" target="f12" />
<area shape="rect" coords="276,27,310,43" target="del" />
- <area shape="rect" coords="276,47,308,64" target="backspace" />
+ <area shape="rect" coords="276,46,299,65" target="delete" />
+ <area shape="rect" coords="300,46,311,65" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="Q" />
<area shape="rect" coords="57,68,75,86" target="W" />
@@ -307,81 +311,86 @@
<area shape="rect" coords="202,110,219,128" target="," />
<area shape="rect" coords="223,110,241,128" target="." />
<area shape="rect" coords="243,110,261,128" target="/" />
+ <area shape="rect" coords="269,131,288,150" target="ok" />
+ <area shape="rect" coords="292,131,311,150" target="cancel" />
</map>
</layout>
<layout resolution="640x480" bitmap="uppercase640x480.bmp" transparent_color="255,0,255">
<map>
- <area shape="rect" coords="26,23,613,37" target="display_area" />
- <area shape="rect" coords="18,52,51,85" target="esc" />
- <area shape="rect" coords="100,51,135,88" target="f2" />
- <area shape="rect" coords="59,49,94,88" target="f1" />
- <area shape="rect" coords="142,53,176,89" target="f3" />
- <area shape="rect" coords="181,51,216,87" target="f4" />
- <area shape="rect" coords="223,52,258,88" target="f5" />
- <area shape="rect" coords="265,52,299,89" target="f6" />
- <area shape="rect" coords="306,51,341,90" target="f7" />
- <area shape="rect" coords="347,53,382,89" target="f8" />
- <area shape="rect" coords="389,49,424,88" target="f9" />
- <area shape="rect" coords="431,52,464,89" target="f10" />
- <area shape="rect" coords="470,53,506,88" target="f11" />
- <area shape="rect" coords="511,52,546,90" target="f12" />
- <area shape="rect" coords="552,55,620,87" target="del" />
- <area shape="rect" coords="553,94,618,129" target="backspace" />
- <area shape="rect" coords="17,136,66,171" target="tab" />
- <area shape="rect" coords="73,137,108,171" target="Q" />
- <area shape="rect" coords="114,136,150,172" target="W" />
- <area shape="rect" coords="157,134,189,171" target="E" />
- <area shape="rect" coords="197,135,232,171" target="R" />
- <area shape="rect" coords="239,135,274,172" target="T" />
- <area shape="rect" coords="282,136,317,173" target="Y" />
- <area shape="rect" coords="322,135,359,173" target="U" />
- <area shape="rect" coords="364,134,399,172" target="I" />
- <area shape="rect" coords="404,135,440,171" target="O" />
- <area shape="rect" coords="446,136,480,172" target="P" />
- <area shape="rect" coords="89,177,127,216" target="A" />
- <area shape="rect" coords="131,177,169,214" target="S" />
- <area shape="rect" coords="173,178,209,215" target="D" />
- <area shape="rect" coords="215,178,250,214" target="F" />
- <area shape="rect" coords="256,178,291,214" target="G" />
- <area shape="rect" coords="299,176,332,214" target="H" />
- <area shape="rect" coords="339,178,374,215" target="J" />
- <area shape="rect" coords="379,178,415,215" target="K" />
- <area shape="rect" coords="421,178,457,215" target="L" />
- <area shape="rect" coords="546,179,622,214" target="enter" />
- <area shape="rect" coords="19,221,101,256" target="shift" />
- <area shape="rect" coords="17,179,84,213" target="caps" />
- <area shape="rect" coords="117,220,152,256" target="Z" />
- <area shape="rect" coords="158,220,192,256" target="X" />
- <area shape="rect" coords="198,219,233,256" target="C" />
- <area shape="rect" coords="240,220,276,257" target="V" />
- <area shape="rect" coords="283,219,316,255" target="B" />
- <area shape="rect" coords="324,220,359,256" target="N" />
- <area shape="rect" coords="365,220,399,257" target="M" />
- <area shape="rect" coords="542,219,623,257" target="symbols" />
- <area shape="rect" coords="19,260,68,296" target="ctrl" />
- <area shape="rect" coords="76,261,123,295" target="alt" />
- <area shape="rect" coords="135,261,525,297" target="space" />
- <area shape="rect" coords="16,95,53,129" target="|" />
- <area shape="rect" coords="57,95,92,129" target="1" />
- <area shape="rect" coords="100,94,134,130" target="2" />
- <area shape="rect" coords="140,93,174,131" target="3" />
- <area shape="rect" coords="182,93,217,130" target="4" />
- <area shape="rect" coords="222,93,258,132" target="5" />
- <area shape="rect" coords="265,94,299,131" target="6" />
- <area shape="rect" coords="305,94,341,129" target="7" />
- <area shape="rect" coords="348,93,382,128" target="8" />
- <area shape="rect" coords="389,94,423,130" target="9" />
- <area shape="rect" coords="431,93,465,130" target="0" />
- <area shape="rect" coords="471,94,505,131" target="-" />
- <area shape="rect" coords="511,93,546,131" target="=" />
- <area shape="rect" coords="488,136,522,172" target="[" />
- <area shape="rect" coords="529,135,565,173" target="]" />
- <area shape="rect" coords="569,136,620,172" target="#" />
- <area shape="rect" coords="462,177,498,214" target=";" />
- <area shape="rect" coords="503,178,539,214" target="’" />
- <area shape="rect" coords="405,220,440,256" target="," />
- <area shape="rect" coords="447,220,483,256" target="." />
- <area shape="rect" coords="487,220,524,256" target="/" />
+ <area shape="rect" coords="26,23,613,37" target="display_area" />
+ <area shape="rect" coords="18,52,51,85" target="esc" />
+ <area shape="rect" coords="100,51,135,88" target="f2" />
+ <area shape="rect" coords="59,49,94,88" target="f1" />
+ <area shape="rect" coords="142,53,176,89" target="f3" />
+ <area shape="rect" coords="181,51,216,87" target="f4" />
+ <area shape="rect" coords="223,52,258,88" target="f5" />
+ <area shape="rect" coords="265,52,299,89" target="f6" />
+ <area shape="rect" coords="306,51,341,90" target="f7" />
+ <area shape="rect" coords="347,53,382,89" target="f8" />
+ <area shape="rect" coords="389,49,424,88" target="f9" />
+ <area shape="rect" coords="431,52,464,89" target="f10" />
+ <area shape="rect" coords="470,53,506,88" target="f11" />
+ <area shape="rect" coords="511,52,546,90" target="f12" />
+ <area shape="rect" coords="552,55,620,87" target="del" />
+ <area shape="rect" coords="552,93,598,131" target="delete" />
+ <area shape="rect" coords="601,93,623,131" target="backspace" />
+ <area shape="rect" coords="17,136,66,171" target="tab" />
+ <area shape="rect" coords="73,137,108,171" target="Q" />
+ <area shape="rect" coords="114,136,150,172" target="W" />
+ <area shape="rect" coords="157,134,189,171" target="E" />
+ <area shape="rect" coords="197,135,232,171" target="R" />
+ <area shape="rect" coords="239,135,274,172" target="T" />
+ <area shape="rect" coords="282,136,317,173" target="Y" />
+ <area shape="rect" coords="322,135,359,173" target="U" />
+ <area shape="rect" coords="364,134,399,172" target="I" />
+ <area shape="rect" coords="404,135,440,171" target="O" />
+ <area shape="rect" coords="446,136,480,172" target="P" />
+ <area shape="rect" coords="89,177,127,216" target="A" />
+ <area shape="rect" coords="131,177,169,214" target="S" />
+ <area shape="rect" coords="173,178,209,215" target="D" />
+ <area shape="rect" coords="215,178,250,214" target="F" />
+ <area shape="rect" coords="256,178,291,214" target="G" />
+ <area shape="rect" coords="299,176,332,214" target="H" />
+ <area shape="rect" coords="339,178,374,215" target="J" />
+ <area shape="rect" coords="379,178,415,215" target="K" />
+ <area shape="rect" coords="421,178,457,215" target="L" />
+ <area shape="rect" coords="546,179,622,214" target="enter" />
+ <area shape="rect" coords="19,221,101,256" target="shift" />
+ <area shape="rect" coords="17,179,84,213" target="caps" />
+ <area shape="rect" coords="117,220,152,256" target="Z" />
+ <area shape="rect" coords="158,220,192,256" target="X" />
+ <area shape="rect" coords="198,219,233,256" target="C" />
+ <area shape="rect" coords="240,220,276,257" target="V" />
+ <area shape="rect" coords="283,219,316,255" target="B" />
+ <area shape="rect" coords="324,220,359,256" target="N" />
+ <area shape="rect" coords="365,220,399,257" target="M" />
+ <area shape="rect" coords="542,219,623,257" target="symbols" />
+ <area shape="rect" coords="19,260,68,296" target="ctrl" />
+ <area shape="rect" coords="76,261,123,295" target="alt" />
+ <area shape="rect" coords="135,261,525,297" target="space" />
+ <area shape="rect" coords="16,95,53,129" target="|" />
+ <area shape="rect" coords="57,95,92,129" target="1" />
+ <area shape="rect" coords="100,94,134,130" target="2" />
+ <area shape="rect" coords="140,93,174,131" target="3" />
+ <area shape="rect" coords="182,93,217,130" target="4" />
+ <area shape="rect" coords="222,93,258,132" target="5" />
+ <area shape="rect" coords="265,94,299,131" target="6" />
+ <area shape="rect" coords="305,94,341,129" target="7" />
+ <area shape="rect" coords="348,93,382,128" target="8" />
+ <area shape="rect" coords="389,94,423,130" target="9" />
+ <area shape="rect" coords="431,93,465,130" target="0" />
+ <area shape="rect" coords="471,94,505,131" target="-" />
+ <area shape="rect" coords="511,93,546,131" target="=" />
+ <area shape="rect" coords="488,136,522,172" target="[" />
+ <area shape="rect" coords="529,135,565,173" target="]" />
+ <area shape="rect" coords="569,136,620,172" target="#" />
+ <area shape="rect" coords="462,177,498,214" target=";" />
+ <area shape="rect" coords="503,178,539,214" target="’" />
+ <area shape="rect" coords="405,220,440,256" target="," />
+ <area shape="rect" coords="447,220,483,256" target="." />
+ <area shape="rect" coords="487,220,524,256" target="/" />
+ <area shape="rect" coords="538,266,576,298" target="ok" />
+ <area shape="rect" coords="585,266,622,298" target="cancel" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
@@ -454,7 +463,10 @@
<event name="7" type="key" code="55" ascii="55" modifiers="" />
<event name="8" type="key" code="56" ascii="56" modifiers="" />
<event name="9" type="key" code="57" ascii="57" modifiers="" />
+ <event name="ok" type="submit" />
+ <event name="cancel" type="cancel" />
<event name="quit" type="submit" />
+ <event name="delete" type="delete" />
</mode>
<!-- Lowercase Symbols -->
@@ -489,7 +501,8 @@
<area shape="rect" coords="215,46,232,64" target=")" />
<area shape="rect" coords="235,47,252,65" target="_" />
<area shape="rect" coords="255,46,272,65" target="+" />
- <area shape="rect" coords="276,47,308,64" target="backspace" />
+ <area shape="rect" coords="276,46,299,65" target="delete" />
+ <area shape="rect" coords="300,46,311,65" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="q" />
<area shape="rect" coords="57,68,75,86" target="w" />
@@ -532,81 +545,86 @@
<area shape="rect" coords="9,130,33,148" target="ctrl" />
<area shape="rect" coords="38,130,61,147" target="alt" />
<area shape="rect" coords="67,130,262,148" target="space" />
+ <area shape="rect" coords="269,131,288,150" target="ok" />
+ <area shape="rect" coords="292,131,311,150" target="cancel" />
</map>
</layout>
<layout resolution="640x480" bitmap="lowercase-symbols640x480.bmp" transparent_color="255,0,255">
<map>
- <area shape="rect" coords="26,23,613,37" target="display_area" />
- <area shape="rect" coords="18,52,51,85" target="esc" />
- <area shape="rect" coords="100,51,135,88" target="f2" />
- <area shape="rect" coords="59,49,94,88" target="f1" />
- <area shape="rect" coords="142,53,176,89" target="f3" />
- <area shape="rect" coords="181,51,216,87" target="f4" />
- <area shape="rect" coords="223,52,258,88" target="f5" />
- <area shape="rect" coords="265,52,299,89" target="f6" />
- <area shape="rect" coords="306,51,341,90" target="f7" />
- <area shape="rect" coords="347,53,382,89" target="f8" />
- <area shape="rect" coords="389,49,424,88" target="f9" />
- <area shape="rect" coords="431,52,464,89" target="f10" />
- <area shape="rect" coords="470,53,506,88" target="f11" />
- <area shape="rect" coords="511,52,546,90" target="f12" />
- <area shape="rect" coords="552,55,620,87" target="del" />
- <area shape="rect" coords="16,95,53,129" target="¬" />
- <area shape="rect" coords="57,95,92,129" target="!" />
- <area shape="rect" coords="100,94,134,130" target="quote" />
- <area shape="rect" coords="140,93,174,131" target="£" />
- <area shape="rect" coords="182,93,217,130" target="$" />
- <area shape="rect" coords="222,93,258,132" target="%" />
- <area shape="rect" coords="265,94,299,131" target="^" />
- <area shape="rect" coords="305,94,341,129" target="&amp;" />
- <area shape="rect" coords="348,93,382,128" target="*" />
- <area shape="rect" coords="389,94,423,130" target="(" />
- <area shape="rect" coords="431,93,465,130" target=")" />
- <area shape="rect" coords="471,94,505,131" target="_" />
- <area shape="rect" coords="511,93,546,131" target="+" />
- <area shape="rect" coords="553,94,618,129" target="backspace" />
- <area shape="rect" coords="17,136,66,171" target="tab" />
- <area shape="rect" coords="73,137,108,171" target="q" />
- <area shape="rect" coords="114,136,150,172" target="w" />
- <area shape="rect" coords="157,134,189,171" target="e" />
- <area shape="rect" coords="197,135,232,171" target="r" />
- <area shape="rect" coords="239,135,274,172" target="t" />
- <area shape="rect" coords="282,136,317,173" target="y" />
- <area shape="rect" coords="322,135,359,173" target="u" />
- <area shape="rect" coords="364,134,399,172" target="i" />
- <area shape="rect" coords="404,135,440,171" target="o" />
- <area shape="rect" coords="446,136,480,172" target="p" />
- <area shape="rect" coords="488,136,522,172" target="{" />
- <area shape="rect" coords="529,135,565,173" target="}" />
- <area shape="rect" coords="569,136,620,172" target="~" />
- <area shape="rect" coords="17,179,84,213" target="caps" />
- <area shape="rect" coords="89,177,127,216" target="a" />
- <area shape="rect" coords="131,177,169,214" target="s" />
- <area shape="rect" coords="173,178,209,215" target="d" />
- <area shape="rect" coords="215,178,250,214" target="f" />
- <area shape="rect" coords="256,178,291,214" target="g" />
- <area shape="rect" coords="299,176,332,214" target="h" />
- <area shape="rect" coords="339,178,374,215" target="j" />
- <area shape="rect" coords="379,178,415,215" target="k" />
- <area shape="rect" coords="421,178,457,215" target="l" />
- <area shape="rect" coords="462,177,498,214" target=":" />
- <area shape="rect" coords="503,178,539,214" target="@" />
- <area shape="rect" coords="546,179,622,214" target="enter" />
- <area shape="rect" coords="19,221,101,256" target="shift" />
- <area shape="rect" coords="117,220,152,256" target="z" />
- <area shape="rect" coords="158,220,192,256" target="x" />
- <area shape="rect" coords="198,219,233,256" target="c" />
- <area shape="rect" coords="240,220,276,257" target="v" />
- <area shape="rect" coords="283,219,316,255" target="b" />
- <area shape="rect" coords="324,220,359,256" target="n" />
- <area shape="rect" coords="365,220,399,257" target="m" />
- <area shape="rect" coords="405,220,440,256" target="&lt;" />
- <area shape="rect" coords="447,220,483,256" target="&gt;" />
- <area shape="rect" coords="487,220,524,256" target="?" />
- <area shape="rect" coords="542,219,623,257" target="symbols" />
- <area shape="rect" coords="19,260,68,296" target="ctrl" />
- <area shape="rect" coords="76,261,123,295" target="alt" />
- <area shape="rect" coords="135,261,525,297" target="space" />
+ <area shape="rect" coords="26,23,613,37" target="display_area" />
+ <area shape="rect" coords="18,52,51,85" target="esc" />
+ <area shape="rect" coords="100,51,135,88" target="f2" />
+ <area shape="rect" coords="59,49,94,88" target="f1" />
+ <area shape="rect" coords="142,53,176,89" target="f3" />
+ <area shape="rect" coords="181,51,216,87" target="f4" />
+ <area shape="rect" coords="223,52,258,88" target="f5" />
+ <area shape="rect" coords="265,52,299,89" target="f6" />
+ <area shape="rect" coords="306,51,341,90" target="f7" />
+ <area shape="rect" coords="347,53,382,89" target="f8" />
+ <area shape="rect" coords="389,49,424,88" target="f9" />
+ <area shape="rect" coords="431,52,464,89" target="f10" />
+ <area shape="rect" coords="470,53,506,88" target="f11" />
+ <area shape="rect" coords="511,52,546,90" target="f12" />
+ <area shape="rect" coords="552,55,620,87" target="del" />
+ <area shape="rect" coords="16,95,53,129" target="¬" />
+ <area shape="rect" coords="57,95,92,129" target="!" />
+ <area shape="rect" coords="100,94,134,130" target="quote" />
+ <area shape="rect" coords="140,93,174,131" target="£" />
+ <area shape="rect" coords="182,93,217,130" target="$" />
+ <area shape="rect" coords="222,93,258,132" target="%" />
+ <area shape="rect" coords="265,94,299,131" target="^" />
+ <area shape="rect" coords="305,94,341,129" target="&amp;" />
+ <area shape="rect" coords="348,93,382,128" target="*" />
+ <area shape="rect" coords="389,94,423,130" target="(" />
+ <area shape="rect" coords="431,93,465,130" target=")" />
+ <area shape="rect" coords="471,94,505,131" target="_" />
+ <area shape="rect" coords="511,93,546,131" target="+" />
+ <area shape="rect" coords="552,93,598,131" target="delete" />
+ <area shape="rect" coords="601,93,623,131" target="backspace" />
+ <area shape="rect" coords="17,136,66,171" target="tab" />
+ <area shape="rect" coords="73,137,108,171" target="q" />
+ <area shape="rect" coords="114,136,150,172" target="w" />
+ <area shape="rect" coords="157,134,189,171" target="e" />
+ <area shape="rect" coords="197,135,232,171" target="r" />
+ <area shape="rect" coords="239,135,274,172" target="t" />
+ <area shape="rect" coords="282,136,317,173" target="y" />
+ <area shape="rect" coords="322,135,359,173" target="u" />
+ <area shape="rect" coords="364,134,399,172" target="i" />
+ <area shape="rect" coords="404,135,440,171" target="o" />
+ <area shape="rect" coords="446,136,480,172" target="p" />
+ <area shape="rect" coords="488,136,522,172" target="{" />
+ <area shape="rect" coords="529,135,565,173" target="}" />
+ <area shape="rect" coords="569,136,620,172" target="~" />
+ <area shape="rect" coords="17,179,84,213" target="caps" />
+ <area shape="rect" coords="89,177,127,216" target="a" />
+ <area shape="rect" coords="131,177,169,214" target="s" />
+ <area shape="rect" coords="173,178,209,215" target="d" />
+ <area shape="rect" coords="215,178,250,214" target="f" />
+ <area shape="rect" coords="256,178,291,214" target="g" />
+ <area shape="rect" coords="299,176,332,214" target="h" />
+ <area shape="rect" coords="339,178,374,215" target="j" />
+ <area shape="rect" coords="379,178,415,215" target="k" />
+ <area shape="rect" coords="421,178,457,215" target="l" />
+ <area shape="rect" coords="462,177,498,214" target=":" />
+ <area shape="rect" coords="503,178,539,214" target="@" />
+ <area shape="rect" coords="546,179,622,214" target="enter" />
+ <area shape="rect" coords="19,221,101,256" target="shift" />
+ <area shape="rect" coords="117,220,152,256" target="z" />
+ <area shape="rect" coords="158,220,192,256" target="x" />
+ <area shape="rect" coords="198,219,233,256" target="c" />
+ <area shape="rect" coords="240,220,276,257" target="v" />
+ <area shape="rect" coords="283,219,316,255" target="b" />
+ <area shape="rect" coords="324,220,359,256" target="n" />
+ <area shape="rect" coords="365,220,399,257" target="m" />
+ <area shape="rect" coords="405,220,440,256" target="&lt;" />
+ <area shape="rect" coords="447,220,483,256" target="&gt;" />
+ <area shape="rect" coords="487,220,524,256" target="?" />
+ <area shape="rect" coords="542,219,623,257" target="symbols" />
+ <area shape="rect" coords="19,260,68,296" target="ctrl" />
+ <area shape="rect" coords="76,261,123,295" target="alt" />
+ <area shape="rect" coords="135,261,525,297" target="space" />
+ <area shape="rect" coords="538,266,576,298" target="ok" />
+ <area shape="rect" coords="585,266,622,298" target="cancel" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
@@ -679,7 +697,10 @@
<event name="x" type="key" code="120" ascii="120" modifiers="" />
<event name="y" type="key" code="121" ascii="121" modifiers="" />
<event name="z" type="key" code="122" ascii="122" modifiers="" />
+ <event name="ok" type="submit" />
+ <event name="cancel" type="cancel" />
<event name="quit" type="submit" />
+ <event name="delete" type="delete" />
</mode>
<!-- Uppercase Symbols -->
@@ -714,7 +735,8 @@
<area shape="rect" coords="215,46,232,64" target=")" />
<area shape="rect" coords="235,47,252,65" target="_" />
<area shape="rect" coords="255,46,272,65" target="+" />
- <area shape="rect" coords="276,47,308,64" target="backspace" />
+ <area shape="rect" coords="276,46,299,65" target="delete" />
+ <area shape="rect" coords="300,46,311,65" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="Q" />
<area shape="rect" coords="57,68,75,86" target="W" />
@@ -757,81 +779,86 @@
<area shape="rect" coords="9,130,33,148" target="ctrl" />
<area shape="rect" coords="38,130,61,147" target="alt" />
<area shape="rect" coords="67,130,262,148" target="space" />
+ <area shape="rect" coords="269,131,288,150" target="ok" />
+ <area shape="rect" coords="292,131,311,150" target="cancel" />
</map>
</layout>
<layout resolution="640x480" bitmap="uppercase-symbols640x480.bmp" transparent_color="255,0,255">
<map>
- <area shape="rect" coords="26,23,613,37" target="display_area" />
- <area shape="rect" coords="18,52,51,85" target="esc" />
- <area shape="rect" coords="100,51,135,88" target="f2" />
- <area shape="rect" coords="59,49,94,88" target="f1" />
- <area shape="rect" coords="142,53,176,89" target="f3" />
- <area shape="rect" coords="181,51,216,87" target="f4" />
- <area shape="rect" coords="223,52,258,88" target="f5" />
- <area shape="rect" coords="265,52,299,89" target="f6" />
- <area shape="rect" coords="306,51,341,90" target="f7" />
- <area shape="rect" coords="347,53,382,89" target="f8" />
- <area shape="rect" coords="389,49,424,88" target="f9" />
- <area shape="rect" coords="431,52,464,89" target="f10" />
- <area shape="rect" coords="470,53,506,88" target="f11" />
- <area shape="rect" coords="511,52,546,90" target="f12" />
- <area shape="rect" coords="552,55,620,87" target="del" />
- <area shape="rect" coords="16,95,53,129" target="¬" />
- <area shape="rect" coords="57,95,92,129" target="!" />
- <area shape="rect" coords="100,94,134,130" target="quote" />
- <area shape="rect" coords="140,93,174,131" target="£" />
- <area shape="rect" coords="182,93,217,130" target="$" />
- <area shape="rect" coords="222,93,258,132" target="%" />
- <area shape="rect" coords="265,94,299,131" target="^" />
- <area shape="rect" coords="305,94,341,129" target="&amp;" />
- <area shape="rect" coords="348,93,382,128" target="*" />
- <area shape="rect" coords="389,94,423,130" target="(" />
- <area shape="rect" coords="431,93,465,130" target=")" />
- <area shape="rect" coords="471,94,505,131" target="_" />
- <area shape="rect" coords="511,93,546,131" target="+" />
- <area shape="rect" coords="553,94,618,129" target="backspace" />
- <area shape="rect" coords="17,136,66,171" target="tab" />
- <area shape="rect" coords="73,137,108,171" target="Q" />
- <area shape="rect" coords="114,136,150,172" target="W" />
- <area shape="rect" coords="157,134,189,171" target="E" />
- <area shape="rect" coords="197,135,232,171" target="R" />
- <area shape="rect" coords="239,135,274,172" target="T" />
- <area shape="rect" coords="282,136,317,173" target="Y" />
- <area shape="rect" coords="322,135,359,173" target="U" />
- <area shape="rect" coords="364,134,399,172" target="I" />
- <area shape="rect" coords="404,135,440,171" target="O" />
- <area shape="rect" coords="446,136,480,172" target="P" />
- <area shape="rect" coords="488,136,522,172" target="{" />
- <area shape="rect" coords="529,135,565,173" target="}" />
- <area shape="rect" coords="569,136,620,172" target="~" />
- <area shape="rect" coords="17,179,84,213" target="caps" />
- <area shape="rect" coords="89,177,127,216" target="A" />
- <area shape="rect" coords="131,177,169,214" target="S" />
- <area shape="rect" coords="173,178,209,215" target="D" />
- <area shape="rect" coords="215,178,250,214" target="F" />
- <area shape="rect" coords="256,178,291,214" target="G" />
- <area shape="rect" coords="299,176,332,214" target="H" />
- <area shape="rect" coords="339,178,374,215" target="J" />
- <area shape="rect" coords="379,178,415,215" target="K" />
- <area shape="rect" coords="421,178,457,215" target="L" />
- <area shape="rect" coords="462,177,498,214" target=":" />
- <area shape="rect" coords="503,178,539,214" target="@" />
- <area shape="rect" coords="546,179,622,214" target="enter" />
- <area shape="rect" coords="19,221,101,256" target="shift" />
- <area shape="rect" coords="117,220,152,256" target="z" />
- <area shape="rect" coords="158,220,192,256" target="x" />
- <area shape="rect" coords="198,219,233,256" target="c" />
- <area shape="rect" coords="240,220,276,257" target="v" />
- <area shape="rect" coords="283,219,316,255" target="b" />
- <area shape="rect" coords="324,220,359,256" target="n" />
- <area shape="rect" coords="365,220,399,257" target="m" />
- <area shape="rect" coords="405,220,440,256" target="&lt;" />
- <area shape="rect" coords="447,220,483,256" target="&gt;" />
- <area shape="rect" coords="487,220,524,256" target="?" />
- <area shape="rect" coords="542,219,623,257" target="symbols" />
- <area shape="rect" coords="19,260,68,296" target="ctrl" />
- <area shape="rect" coords="76,261,123,295" target="alt" />
- <area shape="rect" coords="135,261,525,297" target="space" />
+ <area shape="rect" coords="26,23,613,37" target="display_area" />
+ <area shape="rect" coords="18,52,51,85" target="esc" />
+ <area shape="rect" coords="100,51,135,88" target="f2" />
+ <area shape="rect" coords="59,49,94,88" target="f1" />
+ <area shape="rect" coords="142,53,176,89" target="f3" />
+ <area shape="rect" coords="181,51,216,87" target="f4" />
+ <area shape="rect" coords="223,52,258,88" target="f5" />
+ <area shape="rect" coords="265,52,299,89" target="f6" />
+ <area shape="rect" coords="306,51,341,90" target="f7" />
+ <area shape="rect" coords="347,53,382,89" target="f8" />
+ <area shape="rect" coords="389,49,424,88" target="f9" />
+ <area shape="rect" coords="431,52,464,89" target="f10" />
+ <area shape="rect" coords="470,53,506,88" target="f11" />
+ <area shape="rect" coords="511,52,546,90" target="f12" />
+ <area shape="rect" coords="552,55,620,87" target="del" />
+ <area shape="rect" coords="16,95,53,129" target="¬" />
+ <area shape="rect" coords="57,95,92,129" target="!" />
+ <area shape="rect" coords="100,94,134,130" target="quote" />
+ <area shape="rect" coords="140,93,174,131" target="£" />
+ <area shape="rect" coords="182,93,217,130" target="$" />
+ <area shape="rect" coords="222,93,258,132" target="%" />
+ <area shape="rect" coords="265,94,299,131" target="^" />
+ <area shape="rect" coords="305,94,341,129" target="&amp;" />
+ <area shape="rect" coords="348,93,382,128" target="*" />
+ <area shape="rect" coords="389,94,423,130" target="(" />
+ <area shape="rect" coords="431,93,465,130" target=")" />
+ <area shape="rect" coords="471,94,505,131" target="_" />
+ <area shape="rect" coords="511,93,546,131" target="+" />
+ <area shape="rect" coords="552,93,598,131" target="delete" />
+ <area shape="rect" coords="601,93,623,131" target="backspace" />
+ <area shape="rect" coords="17,136,66,171" target="tab" />
+ <area shape="rect" coords="73,137,108,171" target="Q" />
+ <area shape="rect" coords="114,136,150,172" target="W" />
+ <area shape="rect" coords="157,134,189,171" target="E" />
+ <area shape="rect" coords="197,135,232,171" target="R" />
+ <area shape="rect" coords="239,135,274,172" target="T" />
+ <area shape="rect" coords="282,136,317,173" target="Y" />
+ <area shape="rect" coords="322,135,359,173" target="U" />
+ <area shape="rect" coords="364,134,399,172" target="I" />
+ <area shape="rect" coords="404,135,440,171" target="O" />
+ <area shape="rect" coords="446,136,480,172" target="P" />
+ <area shape="rect" coords="488,136,522,172" target="{" />
+ <area shape="rect" coords="529,135,565,173" target="}" />
+ <area shape="rect" coords="569,136,620,172" target="~" />
+ <area shape="rect" coords="17,179,84,213" target="caps" />
+ <area shape="rect" coords="89,177,127,216" target="A" />
+ <area shape="rect" coords="131,177,169,214" target="S" />
+ <area shape="rect" coords="173,178,209,215" target="D" />
+ <area shape="rect" coords="215,178,250,214" target="F" />
+ <area shape="rect" coords="256,178,291,214" target="G" />
+ <area shape="rect" coords="299,176,332,214" target="H" />
+ <area shape="rect" coords="339,178,374,215" target="J" />
+ <area shape="rect" coords="379,178,415,215" target="K" />
+ <area shape="rect" coords="421,178,457,215" target="L" />
+ <area shape="rect" coords="462,177,498,214" target=":" />
+ <area shape="rect" coords="503,178,539,214" target="@" />
+ <area shape="rect" coords="546,179,622,214" target="enter" />
+ <area shape="rect" coords="19,221,101,256" target="shift" />
+ <area shape="rect" coords="117,220,152,256" target="z" />
+ <area shape="rect" coords="158,220,192,256" target="x" />
+ <area shape="rect" coords="198,219,233,256" target="c" />
+ <area shape="rect" coords="240,220,276,257" target="v" />
+ <area shape="rect" coords="283,219,316,255" target="b" />
+ <area shape="rect" coords="324,220,359,256" target="n" />
+ <area shape="rect" coords="365,220,399,257" target="m" />
+ <area shape="rect" coords="405,220,440,256" target="&lt;" />
+ <area shape="rect" coords="447,220,483,256" target="&gt;" />
+ <area shape="rect" coords="487,220,524,256" target="?" />
+ <area shape="rect" coords="542,219,623,257" target="symbols" />
+ <area shape="rect" coords="19,260,68,296" target="ctrl" />
+ <area shape="rect" coords="76,261,123,295" target="alt" />
+ <area shape="rect" coords="135,261,525,297" target="space" />
+ <area shape="rect" coords="538,266,576,298" target="ok" />
+ <area shape="rect" coords="585,266,622,298" target="cancel" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
@@ -914,7 +941,9 @@
<event name="7" type="key" code="55" ascii="55" modifiers="" />
<event name="8" type="key" code="56" ascii="56" modifiers="" />
<event name="9" type="key" code="57" ascii="57" modifiers="" />
+ <event name="ok" type="submit" />
+ <event name="cancel" type="cancel" />
<event name="quit" type="submit" />
+ <event name="delete" type="delete" />
</mode>
-
</keyboard>
diff --git a/base/internal_version.h b/base/internal_version.h
index 0838e8ad2a..68e3127020 100644
--- a/base/internal_version.h
+++ b/base/internal_version.h
@@ -2,4 +2,4 @@
#define SCUMMVM_SVN_REVISION
#endif
-#define SCUMMVM_VERSION "1.0.0svn" SCUMMVM_SVN_REVISION
+#define SCUMMVM_VERSION "1.1.0svn" SCUMMVM_SVN_REVISION
diff --git a/base/main.cpp b/base/main.cpp
index 2d4091c0d5..d108512416 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -41,6 +41,7 @@
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/system.h"
@@ -168,9 +169,9 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
// Set the window caption to the game name
Common::String caption(ConfMan.get("description"));
- Common::String desc = EngineMan.findGame(ConfMan.get("gameid")).description();
- if (caption.empty() && !desc.empty())
- caption = desc;
+ if (caption.empty()) {
+ caption = EngineMan.findGame(ConfMan.get("gameid")).description();
+ }
if (caption.empty())
caption = ConfMan.getActiveDomainName(); // Use the domain (=target) name
if (!caption.empty()) {
@@ -355,6 +356,14 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// take place after the backend is initiated and the screen has been setup
system.getEventManager()->init();
+ // Directly after initializing the event manager, we will initialize our
+ // event recorder.
+ //
+ // TODO: This is just to match the current behavior, when we further extend
+ // our event recorder, we might do this at another place. Or even change
+ // the whole API for that ;-).
+ g_eventRec.init();
+
// Now as the event manager is created, setup the keymapper
setupKeymapper(system);
diff --git a/common/EventDispatcher.cpp b/common/EventDispatcher.cpp
new file mode 100644
index 0000000000..57765f9d13
--- /dev/null
+++ b/common/EventDispatcher.cpp
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/events.h"
+
+namespace Common {
+
+EventDispatcher::EventDispatcher() : _mapper(0) {
+}
+
+EventDispatcher::~EventDispatcher() {
+ for (Common::List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
+ if (i->autoFree)
+ delete i->source;
+ }
+
+ for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+ if (i->autoFree)
+ delete i->observer;
+ }
+
+ delete _mapper;
+ _mapper = 0;
+}
+
+void EventDispatcher::dispatch() {
+ Common::Event event;
+
+ for (Common::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;
+ }
+ }
+
+ dispatchEvent(event);
+ }
+ }
+}
+
+void EventDispatcher::registerMapper(EventMapper *mapper) {
+ if (_mapper)
+ delete _mapper;
+ _mapper = mapper;
+}
+
+void EventDispatcher::registerSource(EventSource *source, bool autoFree) {
+ SourceEntry newEntry;
+
+ newEntry.source = source;
+ newEntry.autoFree = autoFree;
+
+ _sources.push_back(newEntry);
+}
+
+void EventDispatcher::unregisterSource(EventSource *source) {
+ for (Common::List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
+ if (i->source == source) {
+ if (i->autoFree)
+ delete source;
+
+ _sources.erase(i);
+ return;
+ }
+ }
+}
+
+void EventDispatcher::registerObserver(EventObserver *obs, uint priority, bool autoFree) {
+ ObserverEntry newEntry;
+
+ newEntry.observer = obs;
+ newEntry.priority = priority;
+ newEntry.autoFree = autoFree;
+
+ for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+ if (i->priority < priority) {
+ _observers.insert(i, newEntry);
+ return;
+ }
+ }
+
+ _observers.push_back(newEntry);
+}
+
+void EventDispatcher::unregisterObserver(EventObserver *obs) {
+ for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+ if (i->observer == obs) {
+ if (i->autoFree)
+ delete obs;
+
+ _observers.erase(i);
+ return;
+ }
+ }
+}
+
+void EventDispatcher::dispatchEvent(const Event &event) {
+ for (Common::List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+ if (i->observer->notifyEvent(event))
+ break;
+ }
+}
+
+} // end of namespace Common
+
diff --git a/common/EventRecorder.cpp b/common/EventRecorder.cpp
new file mode 100644
index 0000000000..3d5eee3e52
--- /dev/null
+++ b/common/EventRecorder.cpp
@@ -0,0 +1,366 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/EventRecorder.h"
+
+#include "common/config-manager.h"
+
+DECLARE_SINGLETON(Common::EventRecorder);
+
+namespace Common {
+
+#define RECORD_SIGNATURE 0x54455354
+#define RECORD_VERSION 1
+
+void readRecord(Common::InSaveFile *inFile, uint32 &diff, Common::Event &event) {
+ diff = inFile->readUint32LE();
+
+ event.type = (Common::EventType)inFile->readUint32LE();
+
+ switch(event.type) {
+ case Common::EVENT_KEYDOWN:
+ case Common::EVENT_KEYUP:
+ event.kbd.keycode = (Common::KeyCode)inFile->readSint32LE();
+ event.kbd.ascii = inFile->readUint16LE();
+ event.kbd.flags = inFile->readByte();
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONDOWN:
+ case Common::EVENT_RBUTTONUP:
+ case Common::EVENT_WHEELUP:
+ case Common::EVENT_WHEELDOWN:
+ event.mouse.x = inFile->readSint16LE();
+ event.mouse.y = inFile->readSint16LE();
+ break;
+ default:
+ break;
+ }
+}
+
+void writeRecord(Common::OutSaveFile *outFile, uint32 diff, const Common::Event &event) {
+ outFile->writeUint32LE(diff);
+
+ outFile->writeUint32LE((uint32)event.type);
+
+ switch(event.type) {
+ case Common::EVENT_KEYDOWN:
+ case Common::EVENT_KEYUP:
+ outFile->writeSint32LE(event.kbd.keycode);
+ outFile->writeUint16LE(event.kbd.ascii);
+ outFile->writeByte(event.kbd.flags);
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONDOWN:
+ case Common::EVENT_RBUTTONUP:
+ case Common::EVENT_WHEELUP:
+ case Common::EVENT_WHEELDOWN:
+ outFile->writeSint16LE(event.mouse.x);
+ outFile->writeSint16LE(event.mouse.y);
+ break;
+ default:
+ break;
+ }
+}
+
+EventRecorder::EventRecorder() {
+ _recordFile = NULL;
+ _recordTimeFile = NULL;
+ _playbackFile = NULL;
+ _playbackTimeFile = NULL;
+ _timeMutex = g_system->createMutex();
+ _recorderMutex = g_system->createMutex();
+
+ _eventCount = 0;
+ _lastEventCount = 0;
+ _lastMillis = 0;
+
+}
+
+EventRecorder::~EventRecorder() {
+ deinit();
+}
+
+void EventRecorder::init() {
+ Common::String recordModeString = ConfMan.get("record_mode");
+ if (recordModeString.compareToIgnoreCase("record") == 0) {
+ _recordMode = kRecorderRecord;
+ } else {
+ if (recordModeString.compareToIgnoreCase("playback") == 0) {
+ _recordMode = kRecorderPlayback;
+ } else {
+ _recordMode = kPassthrough;
+ }
+ }
+
+ _recordFileName = ConfMan.get("record_file_name");
+ if (_recordFileName.empty()) {
+ _recordFileName = "record.bin";
+ }
+ _recordTempFileName = ConfMan.get("record_temp_file_name");
+ if (_recordTempFileName.empty()) {
+ _recordTempFileName = "record.tmp";
+ }
+ _recordTimeFileName = ConfMan.get("record_time_file_name");
+ if (_recordTimeFileName.empty()) {
+ _recordTimeFileName = "record.time";
+ }
+
+ // recorder stuff
+ if (_recordMode == kRecorderRecord) {
+ _recordCount = 0;
+ _recordTimeCount = 0;
+ _recordFile = g_system->getSavefileManager()->openForSaving(_recordTempFileName);
+ _recordTimeFile = g_system->getSavefileManager()->openForSaving(_recordTimeFileName);
+ _recordSubtitles = ConfMan.getBool("subtitles");
+ }
+
+ uint32 sign;
+ uint32 version;
+ uint32 randomSourceCount;
+ if (_recordMode == kRecorderPlayback) {
+ _playbackCount = 0;
+ _playbackTimeCount = 0;
+ _playbackFile = g_system->getSavefileManager()->openForLoading(_recordFileName);
+ _playbackTimeFile = g_system->getSavefileManager()->openForLoading(_recordTimeFileName);
+
+ if (!_playbackFile) {
+ warning("Cannot open playback file %s. Playback was switched off", _recordFileName.c_str());
+ _recordMode = kPassthrough;
+ }
+
+ if (!_playbackTimeFile) {
+ warning("Cannot open playback time file %s. Playback was switched off", _recordTimeFileName.c_str());
+ _recordMode = kPassthrough;
+ }
+ }
+
+ if (_recordMode == kRecorderPlayback) {
+ sign = _playbackFile->readUint32LE();
+ if (sign != RECORD_SIGNATURE) {
+ error("Unknown record file signature");
+ }
+ version = _playbackFile->readUint32LE();
+
+ // conf vars
+ ConfMan.setBool("subtitles", _playbackFile->readByte() != 0);
+
+ _recordCount = _playbackFile->readUint32LE();
+ _recordTimeCount = _playbackFile->readUint32LE();
+ randomSourceCount = _playbackFile->readUint32LE();
+ for (uint i = 0; i < randomSourceCount; ++i) {
+ RandomSourceRecord rec;
+ rec.name = "";
+ uint32 sLen = _playbackFile->readUint32LE();
+ for (uint j = 0; j < sLen; ++j) {
+ char c = _playbackFile->readSByte();
+ rec.name += c;
+ }
+ rec.seed = _playbackFile->readUint32LE();
+ _randomSourceRecords.push_back(rec);
+ }
+
+ _hasPlaybackEvent = false;
+ }
+
+ g_system->getEventManager()->getEventDispatcher()->registerSource(this, false);
+ g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 1, false);
+}
+
+void EventRecorder::deinit() {
+ g_system->getEventManager()->getEventDispatcher()->unregisterSource(this);
+ g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
+
+ g_system->lockMutex(_timeMutex);
+ g_system->lockMutex(_recorderMutex);
+ _recordMode = kPassthrough;
+ g_system->unlockMutex(_timeMutex);
+ g_system->unlockMutex(_recorderMutex);
+
+ if (_playbackFile != NULL) {
+ delete _playbackFile;
+ }
+ if (_playbackTimeFile != NULL) {
+ delete _playbackTimeFile;
+ }
+
+ if (_recordFile != NULL) {
+ _recordFile->finalize();
+ delete _recordFile;
+ _recordTimeFile->finalize();
+ delete _recordTimeFile;
+
+ _playbackFile = g_system->getSavefileManager()->openForLoading(_recordTempFileName);
+
+ assert(_playbackFile);
+
+ _recordFile = g_system->getSavefileManager()->openForSaving(_recordFileName);
+ _recordFile->writeUint32LE(RECORD_SIGNATURE);
+ _recordFile->writeUint32LE(RECORD_VERSION);
+
+ // conf vars
+ _recordFile->writeByte(_recordSubtitles ? 1 : 0);
+
+ _recordFile->writeUint32LE(_recordCount);
+ _recordFile->writeUint32LE(_recordTimeCount);
+
+ _recordFile->writeUint32LE(_randomSourceRecords.size());
+ for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
+ _recordFile->writeUint32LE(_randomSourceRecords[i].name.size());
+ _recordFile->writeString(_randomSourceRecords[i].name);
+ _recordFile->writeUint32LE(_randomSourceRecords[i].seed);
+ }
+
+ for (uint i = 0; i < _recordCount; ++i) {
+ uint32 tempDiff;
+ Common::Event tempEvent;
+ readRecord(_playbackFile, tempDiff, tempEvent);
+ writeRecord(_recordFile, tempDiff, tempEvent);
+ }
+
+ _recordFile->finalize();
+ delete _recordFile;
+ delete _playbackFile;
+
+ //TODO: remove recordTempFileName'ed file
+ }
+
+ g_system->deleteMutex(_timeMutex);
+ g_system->deleteMutex(_recorderMutex);
+}
+
+void EventRecorder::registerRandomSource(Common::RandomSource &rnd, const char *name) {
+ if (_recordMode == kRecorderRecord) {
+ RandomSourceRecord rec;
+ rec.name = name;
+ rec.seed = rnd.getSeed();
+ _randomSourceRecords.push_back(rec);
+ }
+
+ if (_recordMode == kRecorderPlayback) {
+ for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
+ if (_randomSourceRecords[i].name == name) {
+ rnd.setSeed(_randomSourceRecords[i].seed);
+ _randomSourceRecords.remove_at(i);
+ break;
+ }
+ }
+ }
+}
+
+void EventRecorder::processMillis(uint32 &millis) {
+ uint32 d;
+ if (_recordMode == kPassthrough) {
+ return;
+ }
+
+ g_system->lockMutex(_timeMutex);
+ if (_recordMode == kRecorderRecord) {
+ //Simple RLE compression
+ d = millis - _lastMillis;
+ if (d >= 0xff) {
+ _recordTimeFile->writeByte(0xff);
+ _recordTimeFile->writeUint32LE(d);
+ } else {
+ _recordTimeFile->writeByte(d);
+ }
+ _recordTimeCount++;
+ }
+
+ if (_recordMode == kRecorderPlayback) {
+ if (_recordTimeCount > _playbackTimeCount) {
+ d = _playbackTimeFile->readByte();
+ if (d == 0xff) {
+ d = _playbackTimeFile->readUint32LE();
+ }
+ millis = _lastMillis + d;
+ _playbackTimeCount++;
+ }
+ }
+
+ _lastMillis = millis;
+ g_system->unlockMutex(_timeMutex);
+}
+
+bool EventRecorder::notifyEvent(const Common::Event &ev) {
+ if (_recordMode != kRecorderRecord)
+ return false;
+
+ Common::StackLock lock(_recorderMutex);
+ ++_eventCount;
+
+ writeRecord(_recordFile, _eventCount - _lastEventCount, ev);
+
+ _recordCount++;
+ _lastEventCount = _eventCount;
+
+ return false;
+}
+
+bool EventRecorder::pollEvent(Common::Event &ev) {
+ if (_recordMode != kRecorderPlayback)
+ return false;
+
+ Common::StackLock lock(_recorderMutex);
+ ++_eventCount;
+
+ if (!_hasPlaybackEvent) {
+ if (_recordCount > _playbackCount) {
+ readRecord(_playbackFile, const_cast<uint32&>(_playbackDiff), _playbackEvent);
+ _playbackCount++;
+ _hasPlaybackEvent = true;
+ }
+ }
+
+ if (_hasPlaybackEvent) {
+ if (_playbackDiff <= (_eventCount - _lastEventCount)) {
+ switch(_playbackEvent.type) {
+ case Common::EVENT_MOUSEMOVE:
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONDOWN:
+ case Common::EVENT_RBUTTONUP:
+ case Common::EVENT_WHEELUP:
+ case Common::EVENT_WHEELDOWN:
+ g_system->warpMouse(_playbackEvent.mouse.x, _playbackEvent.mouse.y);
+ break;
+ default:
+ break;
+ }
+ ev = _playbackEvent;
+ _hasPlaybackEvent = false;
+ _lastEventCount = _eventCount;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // end of namespace Common
+
diff --git a/common/EventRecorder.h b/common/EventRecorder.h
new file mode 100644
index 0000000000..e6ea961737
--- /dev/null
+++ b/common/EventRecorder.h
@@ -0,0 +1,106 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef COMMON_EVENTRECORDER_H
+#define COMMON_EVENTRECORDER_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "common/singleton.h"
+#include "common/savefile.h"
+#include "common/mutex.h"
+#include "common/array.h"
+
+#define g_eventRec (Common::EventRecorder::instance())
+
+namespace Common {
+
+/**
+ * Our generic event recorder.
+ *
+ * TODO: Add more documentation.
+ */
+class EventRecorder : private EventSource, private EventObserver, public Singleton<EventRecorder> {
+ friend class Common::Singleton<SingletonBaseType>;
+ EventRecorder();
+ ~EventRecorder();
+public:
+ void init();
+ void deinit();
+
+ /** Register random source so it can be serialized in game test purposes */
+ void registerRandomSource(Common::RandomSource &rnd, const char *name);
+
+ /** TODO: Add documentation, this is only used by the backend */
+ void processMillis(uint32 &millis);
+
+private:
+ bool notifyEvent(const Common::Event &ev);
+ bool pollEvent(Common::Event &ev);
+ bool allowMapping() const { return false; }
+
+ class RandomSourceRecord {
+ public:
+ Common::String name;
+ uint32 seed;
+ };
+ Common::Array<RandomSourceRecord> _randomSourceRecords;
+
+ bool _recordSubtitles;
+ volatile uint32 _recordCount;
+ volatile uint32 _lastRecordEvent;
+ volatile uint32 _recordTimeCount;
+ Common::OutSaveFile *_recordFile;
+ Common::OutSaveFile *_recordTimeFile;
+ Common::MutexRef _timeMutex;
+ Common::MutexRef _recorderMutex;
+ volatile uint32 _lastMillis;
+
+ volatile uint32 _playbackCount;
+ volatile uint32 _playbackDiff;
+ volatile bool _hasPlaybackEvent;
+ volatile uint32 _playbackTimeCount;
+ Common::Event _playbackEvent;
+ Common::InSaveFile *_playbackFile;
+ Common::InSaveFile *_playbackTimeFile;
+
+ volatile uint32 _eventCount;
+ volatile uint32 _lastEventCount;
+
+ enum RecordMode {
+ kPassthrough = 0,
+ kRecorderRecord = 1,
+ kRecorderPlayback = 2
+ };
+ volatile RecordMode _recordMode;
+ Common::String _recordFileName;
+ Common::String _recordTempFileName;
+ Common::String _recordTimeFileName;
+};
+
+} // end of namespace Common
+
+#endif
+
diff --git a/common/events.h b/common/events.h
index 82b85e60ea..34769729ea 100644
--- a/common/events.h
+++ b/common/events.h
@@ -31,6 +31,9 @@
#include "common/rect.h"
#include "common/noncopyable.h"
+#include "common/list.h"
+#include "common/singleton.h"
+
namespace Common {
/**
@@ -126,6 +129,190 @@ struct Event {
Event() : type(EVENT_INVALID), synthetic(false) {}
};
+/**
+ * A source of Events.
+ *
+ * An example for this is OSystem, it provides events created by the system
+ * and or user.
+ */
+class EventSource {
+public:
+ virtual ~EventSource() {}
+
+ /**
+ * Queries a event from the source.
+ *
+ * @param event a reference to the event struct, where the event should be stored.
+ * @return true if an event was polled, false otherwise.
+ */
+ virtual bool pollEvent(Event &event) = 0;
+
+ /**
+ * Checks whether events from this source are allowed to be mapped.
+ *
+ * Possible event sources not allowing mapping are: the event recorder/player and/or
+ * the EventManager, which allows user events to be pushed.
+ *
+ * By default we allow mapping for every event source.
+ */
+ virtual bool allowMapping() const { return true; }
+};
+
+/**
+ * An artificial event source. This is class is used as an event source, which is
+ * made up by client specific events.
+ *
+ * Example usage cases for this are the Keymapper or the DefaultEventManager.
+ */
+class ArtificialEventSource : public EventSource {
+protected:
+ Common::Queue<Common::Event> _artificialEventQueue;
+public:
+ void addEvent(const Common::Event &ev) {
+ _artificialEventQueue.push(ev);
+ }
+
+ bool pollEvent(Common::Event &ev) {
+ if (!_artificialEventQueue.empty()) {
+ ev = _artificialEventQueue.pop();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * By default an artificial event source prevents its events
+ * from being mapped.
+ */
+ virtual bool allowMapping() const { return false; }
+};
+
+/**
+ * Object which catches and processes Events.
+ *
+ * An example for this is the Engine object, it is catching events and processing them.
+ */
+class EventObserver {
+public:
+ virtual ~EventObserver() {}
+
+ /**
+ * Notifies the source of an incoming event.
+ *
+ * An obeser is supposed to eat the event, with returning true, when
+ * it might want prevent other observers from preventing to receive
+ * the event. An 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.
+ *
+ * @param event the event, which is incoming.
+ * @return true if this observer uses this event, false otherwise.
+ */
+ virtual bool notifyEvent(const Event &event) = 0;
+};
+
+/**
+ * A event mapper, which will map events to others.
+ *
+ * An example for this is the Keymapper.
+ */
+class EventMapper : public EventSource, public EventObserver {
+public:
+ /** For event mappers resulting events should never be mapped */
+ bool allowMapping() const { return false; }
+};
+
+/**
+ * Dispatches events from various sources to various observers.
+ *
+ * EventDispatcher is using a priority based approach. Observers
+ * with higher priority will be notified before observers with
+ * lower priority. Because of the possibility that oberservers
+ * might 'eat' events, not all observers might be notified.
+ *
+ * Another speciality is the support for a event mapper, which
+ * will catch events and create new events out of them. This
+ * mapper will be processed before an event is sent to the
+ * observers.
+ */
+class EventDispatcher {
+public:
+ EventDispatcher();
+ ~EventDispatcher();
+
+ /**
+ * Tries to catch events from the registered event
+ * sources and dispatch them to the observers.
+ *
+ * This dispatches *all* events the sources offer.
+ */
+ void dispatch();
+
+ /**
+ * Registers an event mapper with the dispatcher.
+ *
+ * The ownership of the "mapper" variable will pass
+ * to the EventDispatcher, thus it will be deleted
+ * with "delete", when EventDispatcher is destroyed.
+ *
+ * Note there is only one mapper per EventDispatcher
+ * possible, thus when this method is called twice,
+ * the former mapper will be destroied.
+ */
+ void registerMapper(EventMapper *mapper);
+
+ /**
+ * Queries the setup event mapper.
+ */
+ EventMapper *queryMapper() const { return _mapper; }
+
+ /**
+ * Registers a new EventSource with the Dispatcher.
+ */
+ void registerSource(EventSource *source, bool autoFree);
+
+ /**
+ * Unregisters a EventSource.
+ *
+ * This takes the "autoFree" flag passed to registerSource into account.
+ */
+ void unregisterSource(EventSource *source);
+
+ /**
+ * Registers a new EventObserver with the Dispatcher.
+ */
+ void registerObserver(EventObserver *obs, uint priority, bool autoFree);
+
+ /**
+ * Unregisters a EventObserver.
+ *
+ * This takes the "autoFree" flag passed to registerObserver into account.
+ */
+ void unregisterObserver(EventObserver *obs);
+private:
+ EventMapper *_mapper;
+
+ struct Entry {
+ bool autoFree;
+ };
+
+ struct SourceEntry : public Entry {
+ EventSource *source;
+ };
+
+ Common::List<SourceEntry> _sources;
+
+ struct ObserverEntry : public Entry {
+ uint priority;
+ EventObserver *observer;
+ };
+
+ Common::List<ObserverEntry> _observers;
+
+ void dispatchEvent(const Event &event);
+};
+
class Keymapper;
/**
@@ -161,11 +348,6 @@ public:
*/
virtual void pushEvent(const Common::Event &event) = 0;
- /** Register random source so it can be serialized in game test purposes **/
- virtual void registerRandomSource(Common::RandomSource &rnd, const char *name) = 0;
-
- virtual void processMillis(uint32 &millis) = 0;
-
/** Return the current mouse position */
virtual Common::Point getMousePos() const = 0;
@@ -209,9 +391,21 @@ public:
virtual Common::Keymapper *getKeymapper() = 0;
#endif
-protected:
+ enum {
+ /**
+ * Priority of the event manager, for now it's lowest since it eats
+ * *all* events, we might to change that in the future though.
+ */
+ kEventManPriority = 0
+ };
- Common::Queue<Common::Event> artificialEventQueue;
+ /**
+ * Returns the underlying EventDispatcher.
+ */
+ EventDispatcher *getEventDispatcher() { return &_dispatcher; }
+
+protected:
+ EventDispatcher _dispatcher;
};
} // End of namespace Common
diff --git a/common/file.cpp b/common/file.cpp
index 7836a7d4a8..dd4281bd03 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -120,15 +120,6 @@ bool File::isOpen() const {
return _handle != NULL;
}
-bool File::ioFailed() const {
- return !_handle || (eos() || err());
-}
-
-void File::clearIOFailed() {
- if (_handle)
- _handle->clearErr();
-}
-
bool File::err() const {
assert(_handle);
return _handle->err();
diff --git a/common/file.h b/common/file.h
index a98d23a96a..6ac633c462 100644
--- a/common/file.h
+++ b/common/file.h
@@ -126,19 +126,6 @@ public:
*/
const char *getName() const { return _name.c_str(); }
- /**
- * DEPRECATED: Use err() or eos() instead.
- * Returns true if any I/O failure occurred or the end of the
- * stream was reached while reading.
- */
- bool ioFailed() const;
-
- /**
- * DEPRECATED: Don't use this unless you are still using ioFailed().
- * Reset the I/O error status.
- */
- void clearIOFailed();
-
bool err() const; // implement abstract Stream method
void clearErr(); // implement abstract Stream method
bool eos() const; // implement abstract SeekableReadStream method
diff --git a/common/module.mk b/common/module.mk
index bdf9590962..d4f92f0791 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -5,6 +5,8 @@ MODULE_OBJS := \
config-file.o \
config-manager.o \
debug.o \
+ EventDispatcher.o \
+ EventRecorder.o \
file.o \
fs.o \
hashmap.o \
diff --git a/common/str.cpp b/common/str.cpp
index 0d24f2edac..b422a34c3c 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -28,6 +28,8 @@
#include "common/memorypool.h"
+#include <stdarg.h>
+
#if !defined(__SYMBIAN32__)
#include <new>
#endif
@@ -435,6 +437,33 @@ uint String::hash() const {
return hashit(c_str());
}
+// static
+String String::printf(const char *fmt, ...) {
+ String output;
+ assert(output.isStorageIntern());
+
+ va_list va;
+ va_start(va, fmt);
+ int len = vsnprintf(output._str, _builtinCapacity, fmt, va);
+ va_end(va);
+
+ if (len < (int)_builtinCapacity) {
+ // vsnprintf succeeded
+ output._size = len;
+ } else {
+ // vsnprintf didn't have enough space, so grow buffer
+ output.ensureCapacity(len, false);
+ va_start(va, fmt);
+ int len2 = vsnprintf(output._str, len+1, fmt, va);
+ va_end(va);
+ assert(len == len2);
+ output._size = len2;
+ }
+
+ return output;
+}
+
+
#pragma mark -
bool String::operator ==(const String &x) const {
diff --git a/common/str.h b/common/str.h
index b7dbd6535a..2fc88e9c91 100644
--- a/common/str.h
+++ b/common/str.h
@@ -218,6 +218,11 @@ public:
uint hash() const;
+ /**
+ * Printf-like function. Returns a formatted String.
+ */
+ static Common::String printf(const char *fmt, ...) GCC_PRINTF(1,2);
+
public:
typedef char * iterator;
typedef const char * const_iterator;
diff --git a/common/stream.h b/common/stream.h
index 80e2978fb9..9b03c20bd2 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -179,7 +179,7 @@ public:
* DEPRECATED
* Default implementation for backward compatibility
*/
- virtual bool ioFailed() { return (eos() || err()); }
+ inline bool ioFailed() { return (eos() || err()); }
/**
* Read an unsigned byte from the stream and return it.
diff --git a/common/unarj.cpp b/common/unarj.cpp
index 428b4a426e..0312cc5b08 100644
--- a/common/unarj.cpp
+++ b/common/unarj.cpp
@@ -105,7 +105,7 @@ public:
void decode(int32 origsize);
void decode_f(int32 origsize);
- MemoryReadStream *_compressed;
+ BufferedReadStream *_compressed;
MemoryWriteStream *_outstream;
//protected:
@@ -360,6 +360,9 @@ bool ArjFile::open(const Common::String &filename) {
return false;
ArjHeader *hdr = _headers[_fileMap[filename]];
+
+ // TODO: It would be good if ArjFile could decompress files in a streaming
+ // mode, so it would not need to pre-allocate the entire output.
byte *uncompressedData = (byte *)malloc(hdr->origSize);
File archiveFile;
@@ -372,10 +375,11 @@ bool ArjFile::open(const Common::String &filename) {
} else {
ArjDecoder *decoder = new ArjDecoder(hdr);
- byte *compressedData = (byte *)malloc(hdr->compSize);
- archiveFile.read(compressedData, hdr->compSize);
-
- decoder->_compressed = new MemoryReadStream(compressedData, hdr->compSize, true);
+ // TODO: It might not be appropriate to use this wrapper inside ArjFile.
+ // If reading from archiveFile directly is too slow to be usable,
+ // maybe the filesystem code should instead wrap its files
+ // in a BufferedReadStream.
+ decoder->_compressed = new BufferedReadStream(&archiveFile, 4096, false);
decoder->_outstream = new MemoryWriteStream(uncompressedData, hdr->origSize);
if (hdr->method == 1 || hdr->method == 2 || hdr->method == 3)
diff --git a/configure b/configure
index 6e4356d376..b3b1e57ae8 100755
--- a/configure
+++ b/configure
@@ -88,7 +88,7 @@ add_engine queen "Flight of the Amazon Queen" yes
add_engine saga "SAGA" yes "ihnm saga2"
add_engine ihnm "IHNM" yes
add_engine saga2 "SAGA 2 games" no
-add_engine sci "SCI" no "sci32"
+add_engine sci "SCI" yes "sci32"
add_engine sci32 "SCI32 games" no
add_engine sky "Beneath a Steel Sky" yes
add_engine sword1 "Broken Sword 1" yes
@@ -111,8 +111,10 @@ _zlib=auto
_mpeg2=no
_fluidsynth=auto
_16bit=yes
-_mt32emu=yes
+_readline=auto
# Default option behaviour yes/no
+_text_console=no
+_mt32emu=yes
_build_hq_scalers=yes
_build_scalers=yes
# Default vkeybd/keymapper options
@@ -266,7 +268,7 @@ find_sdlconfig() {
#
get_system_exe_extension() {
case $1 in
- mingw* | *os2-emx)
+ mingw* | *os2-emx | wince)
_exeext=".exe"
;;
arm-riscos)
@@ -278,7 +280,7 @@ get_system_exe_extension() {
gp2x-linux)
_exeext=".gp2x"
;;
- dreamcast | wii | gamecube | psp)
+ dreamcast | wii | gamecube | nds | psp)
_exeext=".elf"
;;
*)
@@ -552,7 +554,7 @@ Usage: $0 [OPTIONS]...
Configuration:
-h, --help display this help and exit
- --backend=BACKEND backend to build (sdl, morphos, dc, gp2x, gp2xwiz, iphone, wii, psp, null) [sdl]
+ --backend=BACKEND backend to build (sdl, dc, gp2x, gp2xwiz, iphone, morphos, nds, psp, wii, wince, null) [sdl]
Installation directories:
--prefix=DIR use this prefix for installing ScummVM [/usr/local]
@@ -567,7 +569,9 @@ Special configuration feature:
dreamcast for Sega Dreamcast
wii for Nintendo Wii
gamecube for Nintendo Gamecube
+ nds for Nintendo DS
iphone for Apple iPhone
+ wince for Windows CE
psp for PlayStation Portable
Optional Features:
@@ -581,6 +585,7 @@ $engines_help
--disable-mt32emu don't enable the integrated MT-32 emulator
--disable-hq-scalers exclude HQ2x and HQ3x scalers
--disable-scalers exclude scalers
+ --enable-text-console use text console instead of graphical console
Optional Libraries:
--with-alsa-prefix=DIR Prefix where alsa is installed (optional)
@@ -613,6 +618,9 @@ Optional Libraries:
--with-nasm-prefix=DIR Prefix where nasm executable is installed (optional)
--disable-nasm disable assembly language optimizations [autodetect]
+ --with-readline-prefix=DIR Prefix where readline is installed (optional)
+ --disable-readline disable readline support in text console [autodetect]
+
Some influential environment variables:
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
@@ -650,6 +658,8 @@ for ac_option in $@; do
--disable-nasm) _nasm=no ;;
--enable-mpeg2) _mpeg2=yes ;;
--disable-fluidsynth) _fluidsynth=no ;;
+ --enable-readline) _readline=yes ;;
+ --disable-readline) _readline=no ;;
--enable-plugins) _dynamic_modules=yes ;;
--default-dynamic) _plugins_default=dynamic ;;
--enable-mt32emu) _mt32emu=yes ;;
@@ -658,6 +668,8 @@ for ac_option in $@; do
--disable-vkeybd) _vkeybd=no ;;
--enable-keymapper) _keymapper=yes ;;
--disable-keymapper) _keymapper=no ;;
+ --enable-text-console) _text_console=yes ;;
+ --disable-text-console) _text_console=no ;;
--with-fluidsynth-prefix=*)
arg=`echo $ac_option | cut -d '=' -f 2`
FLUIDSYNTH_CFLAGS="-I$arg/include"
@@ -703,6 +715,11 @@ for ac_option in $@; do
ZLIB_CFLAGS="-I$arg/include"
ZLIB_LIBS="-L$arg/lib"
;;
+ --with-readline-prefix=*)
+ arg=`echo $ac_option | cut -d '=' -f 2`
+ READLINE_CFLAGS="-I$arg/include"
+ READLINE_LIBS="-L$arg/lib"
+ ;;
--backend=*)
_backend=`echo $ac_option | cut -d '=' -f 2`
;;
@@ -807,6 +824,11 @@ iphone)
_host_cpu=arm
_host_alias=arm-apple-darwin9
;;
+wince)
+ _host_os=wince
+ _host_cpu=arm
+ _host_alias=arm-wince-mingw32ce
+ ;;
neuros)
_host_os=linux
_host_cpu=arm
@@ -823,17 +845,22 @@ wii)
_host_cpu=ppc
_host_alias=powerpc-gekko
;;
+gamecube)
+ _host_os=gamecube
+ _host_cpu=ppc
+ _host_alias=powerpc-gekko
+ ;;
+nds)
+ _host_os=nds
+ _host_cpu=arm
+ _host_alias=arm-eabi
+ ;;
psp)
_host_os=psp
_host_cpu=mipsallegrexel
_host_alias=psp
LDFLAGS="$LDFLAGS -L$PSPDEV/psp/sdk/lib -specs=$_srcdir/backends/platform/psp/psp.spec"
;;
-gamecube)
- _host_os=gamecube
- _host_cpu=ppc
- _host_alias=powerpc-gekko
- ;;
*)
if test -n "$_host"; then
guessed_host=`$_srcdir/config.sub $_host`
@@ -870,7 +897,7 @@ esac
# Platform specific sanity checks
#
case $_host_os in
-wii | gamecube)
+wii | gamecube | nds)
if test -z "$DEVKITPRO"; then
echo "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to devkitPRO>"
exit 1
@@ -1150,9 +1177,16 @@ case $_host_os in
CXXFLAGS="$CXXFLAGS -I$DEVKITPRO/libogc/include"
LDFLAGS="$LDFLAGS -mogc -mcpu=750 -L$DEVKITPRO/libogc/lib/cube"
;;
+ nds)
+ # TODO nds
+ ;;
psp)
CXXFLAGS="$CXXFLAGS -O2 -G0 -I$PSPDEV/psp/sdk/include -D_PSP_FW_VERSION=150"
;;
+ wince)
+ CXXFLAGS="$CXXFLAGS -O3 -march=armv4 -mtune=xscale -D_WIN32_WCE=300 -D__ARM__ -D_ARM_ -DUNICODE -DFPM_DEFAULT -DNONSTANDARD_PORT"
+ CXXFLAGS="$CXXFLAGS -DWIN32 -Dcdecl= -D__cdecl__= -Wno-multichar"
+ ;;
# given this is a shell script assume some type of unix
*)
echo "WARNING: could not establish system type, assuming unix like"
@@ -1194,7 +1228,7 @@ if test -n "$_host"; then
;;
gp2xwiz)
echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
- DEFINES="$DEFINES -DUNIX -DGP2XWIZ -DNDEBUG -DUSE_ARM_SMUSH_ASM"
+ DEFINES="$DEFINES -DUNIX -DGP2XWIZ -DNDEBUG -DUSE_ARM_SMUSH_ASM -DUSE_ARM_GFX_ASM -DUSE_ARM_SCALER_ASM -DUSE_ARM_COSTUME_ASM"
CXXFLAGS="$CXXFLAGS -mcpu=arm926ej-s -mtune=arm926ej-s"
LDFLAGS="$LDFLAGS"
_endian=little
@@ -1206,13 +1240,16 @@ if test -n "$_host"; then
_ranlib=$_host_alias-ranlib
add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1'
add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_GFX_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1'
_backend="gp2xwiz"
_build_hq_scalers="no"
_mt32emu="no"
;;
gp2x)
echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
- DEFINES="$DEFINES -DUNIX -DGP2X -DNDEBUG -DUSE_ARM_SMUSH_ASM"
+ DEFINES="$DEFINES -DUNIX -DGP2X -DNDEBUG -DUSE_ARM_SMUSH_ASM -DUSE_ARM_GFX_ASM -DUSE_ARM_SCALER_ASM -DUSE_ARM_COSTUME_ASM"
CXXFLAGS="$CXXFLAGS -march=armv4t"
LDFLAGS="$LDFLAGS -static"
_endian=little
@@ -1224,6 +1261,9 @@ if test -n "$_host"; then
_ranlib=$_host_alias-ranlib
add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1'
add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_GFX_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1'
_backend="gp2x"
_build_hq_scalers="no"
_mt32emu="no"
@@ -1287,6 +1327,28 @@ if test -n "$_host"; then
_ranlib=$_host_alias-ranlib
_strip=$_host_alias-strip
;;
+ wince)
+ echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
+ LDFLAGS="$LDFLAGS -Wl,-Map,scummvm.exe.map -Wl,--stack,65536"
+ _endian=little
+ _need_memalign=yes
+ type_1_byte='char'
+ type_2_byte='short'
+ type_4_byte='int'
+ add_line_to_config_mk 'USE_TREMOLO = 1'
+ add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_GFX_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1'
+ _backend="wince"
+ _ar="$_host_alias-ar cru"
+ _ranlib=$_host_alias-ranlib
+ _strip=$_host_alias-strip
+ _windres=$_host_alias-windres
+ _mt32emu="no"
+ add_line_to_config_mk 'include $(srcdir)/backends/platform/wince/wince.mk'
+ ;;
dreamcast)
echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE"
@@ -1345,6 +1407,24 @@ if test -n "$_host"; then
add_line_to_config_h "/* #define DEBUG_WII_MEMSTATS */"
add_line_to_config_h "/* #define DEBUG_WII_GDB */"
;;
+ nds)
+ echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
+ # TODO: complete this
+ # TODO: Maybe rename nds -> ds (would be more consistent with other backends)
+ DEFINES="$DEFINES -DUSE_ARM_SMUSH_ASM"
+ _endian=little
+ _need_memalign=yes
+ type_1_byte='char'
+ type_2_byte='short'
+ type_4_byte='int'
+ _backend="nds"
+ _build_hq_scalers="no"
+ _mt32emu="no"
+ add_line_to_config_mk 'include $(srcdir)/backends/platform/ds/ds.mk'
+ # TODO: Enable more ARM optimizations -- requires testing!
+ add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1'
+ add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1'
+ ;;
psp)
echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
_endian=little
@@ -1810,6 +1890,45 @@ echo "$_fluidsynth"
rm -rf $TMPC $TMPO$HOSTEXEEXT $TMPO.dSYM
#
+# Check for readline if text_console is enabled
+#
+echocheck "readline"
+if test "$_text_console" = yes ; then
+ if test "$_readline" = auto ; then
+ _readline=no
+ cat > $TMPC << EOF
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
+int main(void) {
+ char *x = readline("");
+}
+EOF
+ cc_check $LDFLAGS $CXXFLAGS $READLINE_CFLAGS $READLINE_LIBS -lreadline && _readline=yes
+ fi
+ echo "$_readline"
+ rm -rf $TMPC $TMPO$HOSTEXEEXT $TMPO.dSYM
+else
+ _readline=no
+ echo "skipping (text console disabled)"
+fi
+
+if test "$_readline" = yes ; then
+ _def_readline='#define USE_READLINE'
+ LIBS="$LIBS $READLINE_LIBS -lreadline"
+ INCLUDES="$INCLUDES $READLINE_CFLAGS"
+else
+ _def_readline='#undef USE_READLINE'
+fi
+
+if test "$_text_console" = yes ; then
+ _def_text_console='#define USE_TEXT_CONSOLE'
+else
+ _def_text_console='#undef USE_TEXT_CONSOLE'
+fi
+
+#
# Check for nasm
#
if test "$_have_x86" = yes ; then
@@ -1896,6 +2015,10 @@ if test "$_mt32emu" = yes ; then
echo_n ", MT-32 emu"
fi
+if test "$_text_console" = yes ; then
+ echo_n ", text console"
+fi
+
if test "$_vkeybd" = yes ; then
echo_n ", virtual keyboard"
fi
@@ -1937,6 +2060,10 @@ case $_backend in
OBJCFLAGS="$OBJCFLAGS --std=c99"
LIBS="$LIBS -lobjc -framework UIKit -framework CoreGraphics -framework OpenGLES -framework QuartzCore -framework GraphicsServices -framework CoreFoundation -framework Foundation -framework AudioToolbox -framework CoreAudio"
;;
+ wince)
+ INCLUDES="$INCLUDES "'-I$(srcdir) -I$(srcdir)/backends/platform/wince -I$(srcdir)/engines -I$(srcdir)/backends/platform/wince/missing/gcc -I$(srcdir)/backends/platform/wince/CEgui -I$(srcdir)/backends/platform/wince/CEkeys'
+ LIBS="$LIBS -static -lSDL"
+ ;;
dc)
INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/dc -isystem $(ronindir)/include'
LDFLAGS="$LDFLAGS -Wl,-Ttext,0x8c010000 -nostartfiles "'$(ronindir)/lib/crt0.o -L$(ronindir)/lib'
@@ -1953,6 +2080,9 @@ case $_backend in
;;
esac
;;
+ nds)
+ # TODO nds
+ ;;
psp)
DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE"
INCLUDES="$INCLUDES -I$PSPDEV/psp/include/SDL"
@@ -1972,7 +2102,7 @@ if test "$_cxx_major" -ge "3" ; then
case $_host_os in
# newlib-based system include files suppress non-C89 function
# declarations under __STRICT_ANSI__
- mingw* | dreamcast | wii | gamecube | psp | amigaos*)
+ mingw* | dreamcast | wii | gamecube | psp | wince | amigaos*)
CXXFLAGS="$CXXFLAGS -W -Wno-unused-parameter"
;;
*)
@@ -2107,6 +2237,10 @@ $_def_alsa
$_def_zlib
$_def_mpeg2
$_def_fluidsynth
+$_def_readline
+
+/* Options */
+$_def_text_console
$_def_mt32emu
/* Plugin settings */
diff --git a/dists/msvc8/gob.vcproj b/dists/msvc8/gob.vcproj
index 22e7cba5fb..c691aae742 100644
--- a/dists/msvc8/gob.vcproj
+++ b/dists/msvc8/gob.vcproj
@@ -15,6 +15,33 @@
<Configuration Name="Release|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Release.vsprops" />
</Configurations>
<Files>
+ <Filter Name="demos">
+ <File RelativePath="..\..\engines\gob\demos\batplayer.cpp" />
+ <File RelativePath="..\..\engines\gob\demos\batplayer.h" />
+ <File RelativePath="..\..\engines\gob\demos\demoplayer.cpp" />
+ <File RelativePath="..\..\engines\gob\demos\demoplayer.h" />
+ <File RelativePath="..\..\engines\gob\demos\scnplayer.cpp" />
+ <File RelativePath="..\..\engines\gob\demos\scnplayer.h" />
+ </Filter>
+ <Filter Name="save">
+ <File RelativePath="..\..\engines\gob\save\saveconverter.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter.h" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp" />
+ <File RelativePath="..\..\engines\gob\save\savefile.cpp" />
+ <File RelativePath="..\..\engines\gob\save\savefile.h" />
+ <File RelativePath="..\..\engines\gob\save\savehandler.cpp" />
+ <File RelativePath="..\..\engines\gob\save\savehandler.h" />
+ <File RelativePath="..\..\engines\gob\save\saveload.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload.h" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v2.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v3.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v4.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v6.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp" />
+ </Filter>
<Filter Name="sound">
<File RelativePath="..\..\engines\gob\sound\adlib.cpp" />
<File RelativePath="..\..\engines\gob\sound\adlib.h" />
@@ -37,12 +64,8 @@
<File RelativePath="..\..\engines\gob\sound\soundmixer.cpp" />
<File RelativePath="..\..\engines\gob\sound\soundmixer.h" />
</Filter>
- <File RelativePath="..\..\engines\gob\demos\batplayer.cpp" />
- <File RelativePath="..\..\engines\gob\demos\batplayer.h" />
<File RelativePath="..\..\engines\gob\dataio.cpp" />
<File RelativePath="..\..\engines\gob\dataio.h" />
- <File RelativePath="..\..\engines\gob\demos\demoplayer.cpp" />
- <File RelativePath="..\..\engines\gob\demos\demoplayer.h" />
<File RelativePath="..\..\engines\gob\detection.cpp" />
<File RelativePath="..\..\engines\gob\draw.cpp" />
<File RelativePath="..\..\engines\gob\draw.h" />
@@ -74,6 +97,7 @@
<File RelativePath="..\..\engines\gob\init_v1.cpp" />
<File RelativePath="..\..\engines\gob\init_v2.cpp" />
<File RelativePath="..\..\engines\gob\init_v3.cpp" />
+ <File RelativePath="..\..\engines\gob\init_v4.cpp" />
<File RelativePath="..\..\engines\gob\init_v6.cpp" />
<File RelativePath="..\..\engines\gob\inter.cpp" />
<File RelativePath="..\..\engines\gob\inter.h" />
@@ -89,7 +113,6 @@
<File RelativePath="..\..\engines\gob\map.h" />
<File RelativePath="..\..\engines\gob\map_v1.cpp" />
<File RelativePath="..\..\engines\gob\map_v2.cpp" />
- <File RelativePath="..\..\engines\gob\map_v4.cpp" />
<File RelativePath="..\..\engines\gob\mult.cpp" />
<File RelativePath="..\..\engines\gob\mult.h" />
<File RelativePath="..\..\engines\gob\mult_v1.cpp" />
@@ -98,29 +121,10 @@
<File RelativePath="..\..\engines\gob\palanim.h" />
<File RelativePath="..\..\engines\gob\resources.cpp" />
<File RelativePath="..\..\engines\gob\resources.h" />
- <File RelativePath="..\..\engines\gob\save\saveconverter.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter.h" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp" />
- <File RelativePath="..\..\engines\gob\save\savefile.cpp" />
- <File RelativePath="..\..\engines\gob\save\savefile.h" />
- <File RelativePath="..\..\engines\gob\save\savehandler.cpp" />
- <File RelativePath="..\..\engines\gob\save\savehandler.h" />
- <File RelativePath="..\..\engines\gob\save\saveload.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload.h" />
- <File RelativePath="..\..\engines\gob\save\saveload_v2.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_v3.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_v4.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_v6.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp" />
<File RelativePath="..\..\engines\gob\scenery.cpp" />
<File RelativePath="..\..\engines\gob\scenery.h" />
<File RelativePath="..\..\engines\gob\scenery_v1.cpp" />
<File RelativePath="..\..\engines\gob\scenery_v2.cpp" />
- <File RelativePath="..\..\engines\gob\demos\scnplayer.cpp" />
- <File RelativePath="..\..\engines\gob\demos\scnplayer.h" />
<File RelativePath="..\..\engines\gob\script.cpp" />
<File RelativePath="..\..\engines\gob\script.h" />
<File RelativePath="..\..\engines\gob\totfile.cpp" />
diff --git a/dists/msvc9/gob.vcproj b/dists/msvc9/gob.vcproj
index 8852e59fa3..984c153e35 100644
--- a/dists/msvc9/gob.vcproj
+++ b/dists/msvc9/gob.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="gob"
ProjectGUID="{976D947A-A45F-4437-991E-412F695C64C7}"
RootNamespace="gob"
@@ -16,6 +16,33 @@
<Configuration Name="Release|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Release.vsprops" />
</Configurations>
<Files>
+ <Filter Name="demos">
+ <File RelativePath="..\..\engines\gob\demos\batplayer.cpp" />
+ <File RelativePath="..\..\engines\gob\demos\batplayer.h" />
+ <File RelativePath="..\..\engines\gob\demos\demoplayer.cpp" />
+ <File RelativePath="..\..\engines\gob\demos\demoplayer.h" />
+ <File RelativePath="..\..\engines\gob\demos\scnplayer.cpp" />
+ <File RelativePath="..\..\engines\gob\demos\scnplayer.h" />
+ </Filter>
+ <Filter Name="save">
+ <File RelativePath="..\..\engines\gob\save\saveconverter.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter.h" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp" />
+ <File RelativePath="..\..\engines\gob\save\savefile.cpp" />
+ <File RelativePath="..\..\engines\gob\save\savefile.h" />
+ <File RelativePath="..\..\engines\gob\save\savehandler.cpp" />
+ <File RelativePath="..\..\engines\gob\save\savehandler.h" />
+ <File RelativePath="..\..\engines\gob\save\saveload.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload.h" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v2.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v3.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v4.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_v6.cpp" />
+ <File RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp" />
+ </Filter>
<Filter Name="sound">
<File RelativePath="..\..\engines\gob\sound\adlib.cpp" />
<File RelativePath="..\..\engines\gob\sound\adlib.h" />
@@ -38,12 +65,8 @@
<File RelativePath="..\..\engines\gob\sound\soundmixer.cpp" />
<File RelativePath="..\..\engines\gob\sound\soundmixer.h" />
</Filter>
- <File RelativePath="..\..\engines\gob\demos\batplayer.cpp" />
- <File RelativePath="..\..\engines\gob\demos\batplayer.h" />
<File RelativePath="..\..\engines\gob\dataio.cpp" />
<File RelativePath="..\..\engines\gob\dataio.h" />
- <File RelativePath="..\..\engines\gob\demos\demoplayer.cpp" />
- <File RelativePath="..\..\engines\gob\demos\demoplayer.h" />
<File RelativePath="..\..\engines\gob\detection.cpp" />
<File RelativePath="..\..\engines\gob\draw.cpp" />
<File RelativePath="..\..\engines\gob\draw.h" />
@@ -75,6 +98,7 @@
<File RelativePath="..\..\engines\gob\init_v1.cpp" />
<File RelativePath="..\..\engines\gob\init_v2.cpp" />
<File RelativePath="..\..\engines\gob\init_v3.cpp" />
+ <File RelativePath="..\..\engines\gob\init_v4.cpp" />
<File RelativePath="..\..\engines\gob\init_v6.cpp" />
<File RelativePath="..\..\engines\gob\inter.cpp" />
<File RelativePath="..\..\engines\gob\inter.h" />
@@ -90,7 +114,6 @@
<File RelativePath="..\..\engines\gob\map.h" />
<File RelativePath="..\..\engines\gob\map_v1.cpp" />
<File RelativePath="..\..\engines\gob\map_v2.cpp" />
- <File RelativePath="..\..\engines\gob\map_v4.cpp" />
<File RelativePath="..\..\engines\gob\mult.cpp" />
<File RelativePath="..\..\engines\gob\mult.h" />
<File RelativePath="..\..\engines\gob\mult_v1.cpp" />
@@ -99,29 +122,10 @@
<File RelativePath="..\..\engines\gob\palanim.h" />
<File RelativePath="..\..\engines\gob\resources.cpp" />
<File RelativePath="..\..\engines\gob\resources.h" />
- <File RelativePath="..\..\engines\gob\save\saveconverter.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter.h" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp" />
- <File RelativePath="..\..\engines\gob\save\savefile.cpp" />
- <File RelativePath="..\..\engines\gob\save\savefile.h" />
- <File RelativePath="..\..\engines\gob\save\savehandler.cpp" />
- <File RelativePath="..\..\engines\gob\save\savehandler.h" />
- <File RelativePath="..\..\engines\gob\save\saveload.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload.h" />
- <File RelativePath="..\..\engines\gob\save\saveload_v2.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_v3.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_v4.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_v6.cpp" />
- <File RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp" />
<File RelativePath="..\..\engines\gob\scenery.cpp" />
<File RelativePath="..\..\engines\gob\scenery.h" />
<File RelativePath="..\..\engines\gob\scenery_v1.cpp" />
<File RelativePath="..\..\engines\gob\scenery_v2.cpp" />
- <File RelativePath="..\..\engines\gob\demos\scnplayer.cpp" />
- <File RelativePath="..\..\engines\gob\demos\scnplayer.h" />
<File RelativePath="..\..\engines\gob\script.cpp" />
<File RelativePath="..\..\engines\gob\script.h" />
<File RelativePath="..\..\engines\gob\totfile.cpp" />
diff --git a/dists/msvc9/scummvm.vcproj b/dists/msvc9/scummvm.vcproj
index de625cd8d9..9282f7a096 100644
--- a/dists/msvc9/scummvm.vcproj
+++ b/dists/msvc9/scummvm.vcproj
@@ -9,209 +9,861 @@
TargetFrameworkVersion="131072"
>
<Platforms>
- <Platform Name="Win32" />
+ <Platform
+ Name="Win32"
+ />
</Platforms>
+ <ToolFiles>
+ </ToolFiles>
<Configurations>
- <Configuration Name="Debug|Win32" ConfigurationType="1" InheritedPropertySheets=".\ScummVM_Debug.vsprops">
- <Tool Name="VCLinkerTool" OutputFile="$(OutDir)/scummvm.exe"
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\ScummVM_Debug.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib $(OutDir)/*.lib"
+ OutputFile="$(OutDir)/scummvm.exe"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
/>
</Configuration>
- <Configuration Name="Release|Win32" ConfigurationType="1" InheritedPropertySheets=".\ScummVM_Release.vsprops">
- <Tool Name="VCLinkerTool" OutputFile="$(OutDir)/scummvm.exe"
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\ScummVM_Release.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib $(OutDir)/*.lib"
+ OutputFile="$(OutDir)/scummvm.exe"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
+ <References>
+ </References>
<Files>
- <Filter Name="base">
- <File RelativePath="..\..\base\commandLine.cpp" />
- <File RelativePath="..\..\base\commandLine.h" />
- <File RelativePath="..\..\base\internal_version.h" />
- <File RelativePath="..\..\base\main.cpp" />
- <File RelativePath="..\..\base\main.h" />
- <File RelativePath="..\..\base\plugins.cpp" />
- <File RelativePath="..\..\base\plugins.h" />
- <File RelativePath="..\..\base\version.cpp" />
- <File RelativePath="..\..\base\version.h" />
+ <Filter
+ Name="base"
+ >
+ <File
+ RelativePath="..\..\base\commandLine.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\commandLine.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\internal_version.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\main.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\main.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\plugins.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\plugins.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\version.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\base\version.h"
+ >
+ </File>
</Filter>
- <Filter Name="common">
- <File RelativePath="..\..\common\algorithm.h" />
- <File RelativePath="..\..\common\archive.cpp" />
- <File RelativePath="..\..\common\archive.h" />
- <File RelativePath="..\..\common\array.h" />
- <File RelativePath="..\..\common\config-file.cpp" />
- <File RelativePath="..\..\common\config-file.h" />
- <File RelativePath="..\..\common\config-manager.cpp" />
- <File RelativePath="..\..\common\config-manager.h" />
- <File RelativePath="..\..\common\debug.cpp" />
- <File RelativePath="..\..\common\debug.h" />
- <File RelativePath="..\..\common\endian.h" />
- <File RelativePath="..\..\common\error.h" />
- <File RelativePath="..\..\common\events.h" />
- <File RelativePath="..\..\common\file.cpp" />
- <File RelativePath="..\..\common\file.h" />
- <File RelativePath="..\..\common\frac.h" />
- <File RelativePath="..\..\common\fs.cpp" />
- <File RelativePath="..\..\common\fs.h" />
- <File RelativePath="..\..\common\func.h" />
- <File RelativePath="..\..\common\hash-str.h" />
- <File RelativePath="..\..\common\hashmap.cpp" />
- <File RelativePath="..\..\common\hashmap.h" />
- <File RelativePath="..\..\common\iff_container.h" />
- <File RelativePath="..\..\common\keyboard.h" />
- <File RelativePath="..\..\common\list.h" />
- <File RelativePath="..\..\common\list_intern.h" />
- <File RelativePath="..\..\common\md5.cpp" />
- <File RelativePath="..\..\common\md5.h" />
- <File RelativePath="..\..\common\memorypool.cpp" />
- <File RelativePath="..\..\common\memorypool.h" />
- <File RelativePath="..\..\common\mutex.cpp" />
- <File RelativePath="..\..\common\mutex.h" />
- <File RelativePath="..\..\common\noncopyable.h" />
- <File RelativePath="..\..\common\pack-end.h" />
- <File RelativePath="..\..\common\pack-start.h" />
- <File RelativePath="..\..\common\ptr.h" />
- <File RelativePath="..\..\common\queue.h" />
- <File RelativePath="..\..\common\rect.h" />
- <File RelativePath="..\..\common\savefile.h" />
- <File RelativePath="..\..\common\scummsys.h" />
- <File RelativePath="..\..\common\serializer.h" />
- <File RelativePath="..\..\common\singleton.h" />
- <File RelativePath="..\..\common\stack.h" />
- <File RelativePath="..\..\common\str.cpp" />
- <File RelativePath="..\..\common\str.h" />
- <File RelativePath="..\..\common\stream.cpp" />
- <File RelativePath="..\..\common\stream.h" />
- <File RelativePath="..\..\common\system.cpp" />
- <File RelativePath="..\..\common\system.h" />
- <File RelativePath="..\..\common\timer.h" />
- <File RelativePath="..\..\common\unarj.cpp" />
- <File RelativePath="..\..\common\unarj.h" />
- <File RelativePath="..\..\common\unzip.cpp" />
- <File RelativePath="..\..\common\unzip.h" />
- <File RelativePath="..\..\common\util.cpp" />
- <File RelativePath="..\..\common\util.h" />
- <File RelativePath="..\..\common\xmlparser.cpp" />
- <File RelativePath="..\..\common\xmlparser.h" />
- <File RelativePath="..\..\common\zlib.cpp" />
- <File RelativePath="..\..\common\zlib.h" />
+ <Filter
+ Name="common"
+ >
+ <File
+ RelativePath="..\..\common\algorithm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\archive.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\archive.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\array.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\config-file.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\config-file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\config-manager.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\config-manager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\debug.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\debug.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\endian.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\error.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\EventDispatcher.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\EventRecorder.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\EventRecorder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\events.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\file.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\frac.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\fs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\fs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\func.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\hash-str.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\hashmap.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\hashmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\iff_container.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\keyboard.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\list.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\list_intern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\md5.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\md5.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\memorypool.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\memorypool.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\mutex.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\mutex.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\noncopyable.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\pack-end.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\pack-start.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\ptr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\queue.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\rect.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\savefile.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\scummsys.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\serializer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\singleton.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\stack.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\str.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\str.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\stream.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\stream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\system.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\system.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\timer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\unarj.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\unarj.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\unzip.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\unzip.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\util.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\xmlparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\xmlparser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\zlib.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\zlib.h"
+ >
+ </File>
</Filter>
- <Filter Name="sound">
- <File RelativePath="..\..\sound\adpcm.cpp" />
- <File RelativePath="..\..\sound\adpcm.h" />
- <File RelativePath="..\..\sound\aiff.cpp" />
- <File RelativePath="..\..\sound\aiff.h" />
- <File RelativePath="..\..\sound\audiocd.cpp" />
- <File RelativePath="..\..\sound\audiocd.h" />
- <File RelativePath="..\..\sound\audiostream.cpp" />
- <File RelativePath="..\..\sound\audiostream.h" />
- <File RelativePath="..\..\sound\flac.cpp" />
- <File RelativePath="..\..\sound\flac.h" />
- <File RelativePath="..\..\sound\fmopl.cpp" />
- <File RelativePath="..\..\sound\fmopl.h" />
- <File RelativePath="..\..\sound\iff_sound.cpp" />
- <File RelativePath="..\..\sound\iff_sound.h" />
- <File RelativePath="..\..\sound\mididrv.cpp" />
- <File RelativePath="..\..\sound\mididrv.h" />
- <File RelativePath="..\..\sound\midiparser.cpp" />
- <File RelativePath="..\..\sound\midiparser.h" />
- <File RelativePath="..\..\sound\midiparser_smf.cpp" />
- <File RelativePath="..\..\sound\midiparser_xmidi.cpp" />
- <File RelativePath="..\..\sound\mixer.cpp" />
- <File RelativePath="..\..\sound\mixer.h" />
- <File RelativePath="..\..\sound\mixer_intern.h" />
- <File RelativePath="..\..\sound\mp3.cpp" />
- <File RelativePath="..\..\sound\mp3.h" />
- <File RelativePath="..\..\sound\mpu401.cpp" />
- <File RelativePath="..\..\sound\mpu401.h" />
- <File RelativePath="..\..\sound\musicplugin.cpp" />
- <File RelativePath="..\..\sound\musicplugin.h" />
- <File RelativePath="..\..\sound\null.cpp" />
- <File RelativePath="..\..\sound\rate.cpp" />
- <File RelativePath="..\..\sound\rate.h" />
- <File RelativePath="..\..\sound\shorten.cpp" />
- <File RelativePath="..\..\sound\shorten.h" />
- <File RelativePath="..\..\sound\timestamp.cpp" />
- <File RelativePath="..\..\sound\timestamp.h" />
- <File RelativePath="..\..\sound\vag.cpp" />
- <File RelativePath="..\..\sound\vag.h" />
- <File RelativePath="..\..\sound\voc.cpp" />
- <File RelativePath="..\..\sound\voc.h" />
- <File RelativePath="..\..\sound\vorbis.cpp" />
- <File RelativePath="..\..\sound\vorbis.h" />
- <File RelativePath="..\..\sound\wave.cpp" />
- <File RelativePath="..\..\sound\wave.h" />
- <Filter Name="softhsynth">
- <File RelativePath="..\..\sound\softsynth\adlib.cpp" />
- <File RelativePath="..\..\sound\softsynth\emumidi.h" />
- <File RelativePath="..\..\sound\softsynth\fluidsynth.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32.cpp" />
- <File RelativePath="..\..\sound\softsynth\pcspk.cpp" />
- <File RelativePath="..\..\sound\softsynth\pcspk.h" />
- <File RelativePath="..\..\sound\softsynth\ym2612.cpp" />
- <File RelativePath="..\..\sound\softsynth\ym2612.h" />
- <Filter Name="mt32">
- <File RelativePath="..\..\sound\softsynth\mt32\freeverb.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\freeverb.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\i386.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\i386.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\mt32_file.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\mt32_file.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\mt32emu.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\part.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\part.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\partial.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\partial.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\partialManager.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\partialManager.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\structures.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\synth.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\synth.h" />
- <File RelativePath="..\..\sound\softsynth\mt32\tables.cpp" />
- <File RelativePath="..\..\sound\softsynth\mt32\tables.h" />
+ <Filter
+ Name="sound"
+ >
+ <File
+ RelativePath="..\..\sound\adpcm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\adpcm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\aiff.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\aiff.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\audiocd.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\audiocd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\audiostream.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\audiostream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\flac.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\flac.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\fmopl.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\fmopl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\iff_sound.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\iff_sound.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mididrv.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mididrv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\midiparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\midiparser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\midiparser_smf.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\midiparser_xmidi.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mixer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mixer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mixer_intern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mp3.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mp3.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mpu401.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mpu401.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\musicplugin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\musicplugin.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\null.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\rate.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\rate.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\shorten.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\shorten.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\timestamp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\timestamp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\vag.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\vag.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\voc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\voc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\vorbis.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\vorbis.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\wave.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\wave.h"
+ >
+ </File>
+ <Filter
+ Name="softhsynth"
+ >
+ <File
+ RelativePath="..\..\sound\softsynth\adlib.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\emumidi.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\fluidsynth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\pcspk.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\pcspk.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\ym2612.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\ym2612.h"
+ >
+ </File>
+ <Filter
+ Name="mt32"
+ >
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\freeverb.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\freeverb.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\i386.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\i386.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\mt32_file.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\mt32_file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\mt32emu.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\part.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\part.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\partial.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\partial.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\partialManager.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\partialManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\structures.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\synth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\synth.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\tables.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\mt32\tables.h"
+ >
+ </File>
</Filter>
- <Filter Name="opl">
- <File RelativePath="..\..\sound\softsynth\opl\dosbox.cpp" />
- <File RelativePath="..\..\sound\softsynth\opl\dosbox.h" />
- <File RelativePath="..\..\sound\softsynth\opl\mame.cpp" />
- <File RelativePath="..\..\sound\softsynth\opl\mame.h" />
- <File RelativePath="..\..\sound\softsynth\opl\opl_impl.h" />
- <File RelativePath="..\..\sound\softsynth\opl\opl_inc.h" />
+ <Filter
+ Name="opl"
+ >
+ <File
+ RelativePath="..\..\sound\softsynth\opl\dosbox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\opl\dosbox.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\opl\mame.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\opl\mame.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\opl\opl_impl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\softsynth\opl\opl_inc.h"
+ >
+ </File>
</Filter>
</Filter>
- <Filter Name="mods">
- <File RelativePath="..\..\sound\mods\infogrames.cpp" />
- <File RelativePath="..\..\sound\mods\infogrames.h" />
- <File RelativePath="..\..\sound\mods\module.cpp" />
- <File RelativePath="..\..\sound\mods\module.h" />
- <File RelativePath="..\..\sound\mods\paula.cpp" />
- <File RelativePath="..\..\sound\mods\paula.h" />
- <File RelativePath="..\..\sound\mods\protracker.cpp" />
- <File RelativePath="..\..\sound\mods\protracker.h" />
- <File RelativePath="..\..\sound\mods\rjp1.cpp" />
- <File RelativePath="..\..\sound\mods\rjp1.h" />
- <File RelativePath="..\..\sound\mods\soundfx.cpp" />
- <File RelativePath="..\..\sound\mods\soundfx.h" />
+ <Filter
+ Name="mods"
+ >
+ <File
+ RelativePath="..\..\sound\mods\infogrames.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\infogrames.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\module.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\module.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\paula.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\paula.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\protracker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\protracker.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\rjp1.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\rjp1.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\soundfx.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\soundfx.h"
+ >
+ </File>
</Filter>
</Filter>
- <Filter Name="txt">
- <File RelativePath="..\..\COPYING" />
- <File RelativePath="..\..\NEWS" />
- <File RelativePath="..\..\README" />
- <File RelativePath="..\..\TODO" />
+ <Filter
+ Name="txt"
+ >
+ <File
+ RelativePath="..\..\COPYING"
+ >
+ </File>
+ <File
+ RelativePath="..\..\NEWS"
+ >
+ </File>
+ <File
+ RelativePath="..\..\README"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TODO"
+ >
+ </File>
</Filter>
- <Filter Name="rsc">
- <File RelativePath="..\..\icons\scummvm.ico" />
- <File RelativePath="..\..\dists\scummvm.rc" />
+ <Filter
+ Name="rsc"
+ >
+ <File
+ RelativePath="..\..\icons\scummvm.ico"
+ >
+ </File>
+ <File
+ RelativePath="..\..\dists\scummvm.rc"
+ >
+ </File>
</Filter>
- <Filter Name="backends">
- <File RelativePath="..\..\backends\base-backend.cpp" />
- <File RelativePath="..\..\backends\base-backend.h" />
- <Filter Name="sdl">
- <File RelativePath="..\..\backends\platform\sdl\events.cpp" />
- <File RelativePath="..\..\backends\platform\sdl\graphics.cpp" />
- <File RelativePath="..\..\backends\platform\sdl\hardwarekeys.cpp" />
+ <Filter
+ Name="backends"
+ >
+ <File
+ RelativePath="..\..\backends\base-backend.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\base-backend.h"
+ >
+ </File>
+ <Filter
+ Name="sdl"
+ >
+ <File
+ RelativePath="..\..\backends\platform\sdl\events.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\platform\sdl\graphics.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\platform\sdl\hardwarekeys.cpp"
+ >
+ </File>
<File
RelativePath="..\..\backends\platform\sdl\main.cpp"
>
@@ -234,156 +886,562 @@
/>
</FileConfiguration>
</File>
- <File RelativePath="..\..\backends\platform\sdl\sdl.cpp" />
- <File RelativePath="..\..\backends\platform\sdl\sdl.h" />
+ <File
+ RelativePath="..\..\backends\platform\sdl\sdl.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\platform\sdl\sdl.h"
+ >
+ </File>
</Filter>
- <Filter Name="fs">
- <File RelativePath="..\..\backends\fs\abstract-fs.cpp" />
- <File RelativePath="..\..\backends\fs\abstract-fs.h" />
- <File RelativePath="..\..\backends\fs\fs-factory.h" />
- <File RelativePath="..\..\backends\fs\stdiostream.cpp" />
- <File RelativePath="..\..\backends\fs\stdiostream.h" />
- <Filter Name="windows">
- <File RelativePath="..\..\backends\fs\windows\windows-fs-factory.cpp" />
- <File RelativePath="..\..\backends\fs\windows\windows-fs-factory.h" />
+ <Filter
+ Name="fs"
+ >
+ <File
+ RelativePath="..\..\backends\fs\abstract-fs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\fs\abstract-fs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\fs\fs-factory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\fs\stdiostream.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\fs\stdiostream.h"
+ >
+ </File>
+ <Filter
+ Name="windows"
+ >
+ <File
+ RelativePath="..\..\backends\fs\windows\windows-fs-factory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\fs\windows\windows-fs-factory.h"
+ >
+ </File>
</Filter>
</Filter>
- <Filter Name="midi">
- <File RelativePath="..\..\backends\midi\windows.cpp" />
+ <Filter
+ Name="midi"
+ >
+ <File
+ RelativePath="..\..\backends\midi\windows.cpp"
+ >
+ </File>
</Filter>
- <Filter Name="timer">
- <File RelativePath="..\..\backends\timer\default\default-timer.cpp" />
- <File RelativePath="..\..\backends\timer\default\default-timer.h" />
+ <Filter
+ Name="timer"
+ >
+ <File
+ RelativePath="..\..\backends\timer\default\default-timer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\timer\default\default-timer.h"
+ >
+ </File>
</Filter>
- <Filter Name="saves">
- <File RelativePath="..\..\backends\saves\default\default-saves.cpp" />
- <File RelativePath="..\..\backends\saves\default\default-saves.h" />
- <File RelativePath="..\..\backends\saves\savefile.cpp" />
+ <Filter
+ Name="saves"
+ >
+ <File
+ RelativePath="..\..\backends\saves\default\default-saves.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\saves\default\default-saves.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\saves\savefile.cpp"
+ >
+ </File>
</Filter>
- <Filter Name="events">
- <Filter Name="default">
- <File RelativePath="..\..\backends\events\default\default-events.cpp" />
- <File RelativePath="..\..\backends\events\default\default-events.h" />
+ <Filter
+ Name="events"
+ >
+ <Filter
+ Name="default"
+ >
+ <File
+ RelativePath="..\..\backends\events\default\default-events.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\events\default\default-events.h"
+ >
+ </File>
</Filter>
</Filter>
- <Filter Name="keymapper">
- <File RelativePath="..\..\backends\keymapper\action.cpp" />
- <File RelativePath="..\..\backends\keymapper\action.h" />
- <File RelativePath="..\..\backends\keymapper\hardware-key.h" />
- <File RelativePath="..\..\backends\keymapper\keymap.cpp" />
- <File RelativePath="..\..\backends\keymapper\keymap.h" />
- <File RelativePath="..\..\backends\keymapper\keymapper.cpp" />
- <File RelativePath="..\..\backends\keymapper\keymapper.h" />
- <File RelativePath="..\..\backends\keymapper\remap-dialog.cpp" />
- <File RelativePath="..\..\backends\keymapper\remap-dialog.h" />
- <File RelativePath="..\..\backends\keymapper\types.h" />
+ <Filter
+ Name="keymapper"
+ >
+ <File
+ RelativePath="..\..\backends\keymapper\action.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\action.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\hardware-key.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\keymap.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\keymap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\keymapper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\keymapper.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\remap-dialog.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\remap-dialog.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\keymapper\types.h"
+ >
+ </File>
</Filter>
- <Filter Name="vkeybd">
- <File RelativePath="..\..\backends\vkeybd\image-map.cpp" />
- <File RelativePath="..\..\backends\vkeybd\image-map.h" />
- <File RelativePath="..\..\backends\vkeybd\keycode-descriptions.h" />
- <File RelativePath="..\..\backends\vkeybd\polygon.cpp" />
- <File RelativePath="..\..\backends\vkeybd\polygon.h" />
- <File RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.cpp" />
- <File RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.h" />
- <File RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.cpp" />
- <File RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.h" />
- <File RelativePath="..\..\backends\vkeybd\virtual-keyboard.cpp" />
- <File RelativePath="..\..\backends\vkeybd\virtual-keyboard.h" />
+ <Filter
+ Name="vkeybd"
+ >
+ <File
+ RelativePath="..\..\backends\vkeybd\image-map.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\image-map.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\keycode-descriptions.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\polygon.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\polygon.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\virtual-keyboard.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\backends\vkeybd\virtual-keyboard.h"
+ >
+ </File>
</Filter>
</Filter>
- <Filter Name="gui">
- <File RelativePath="..\..\gui\about.cpp" />
- <File RelativePath="..\..\gui\about.h" />
- <File RelativePath="..\..\gui\browser.cpp" />
- <File RelativePath="..\..\gui\browser.h" />
- <File RelativePath="..\..\gui\chooser.cpp" />
- <File RelativePath="..\..\gui\chooser.h" />
- <File RelativePath="..\..\gui\console.cpp" />
- <File RelativePath="..\..\gui\console.h" />
- <File RelativePath="..\..\gui\credits.h" />
- <File RelativePath="..\..\gui\debugger.cpp" />
- <File RelativePath="..\..\gui\debugger.h" />
- <File RelativePath="..\..\gui\dialog.cpp" />
- <File RelativePath="..\..\gui\dialog.h" />
- <File RelativePath="..\..\gui\editable.cpp" />
- <File RelativePath="..\..\gui\editable.h" />
- <File RelativePath="..\..\gui\EditTextWidget.cpp" />
- <File RelativePath="..\..\gui\EditTextWidget.h" />
- <File RelativePath="..\..\gui\GuiManager.cpp" />
- <File RelativePath="..\..\gui\GuiManager.h" />
- <File RelativePath="..\..\gui\Key.cpp" />
- <File RelativePath="..\..\gui\Key.h" />
- <File RelativePath="..\..\gui\launcher.cpp" />
- <File RelativePath="..\..\gui\launcher.h" />
- <File RelativePath="..\..\gui\ListWidget.cpp" />
- <File RelativePath="..\..\gui\ListWidget.h" />
- <File RelativePath="..\..\gui\massadd.cpp" />
- <File RelativePath="..\..\gui\massadd.h" />
- <File RelativePath="..\..\gui\message.cpp" />
- <File RelativePath="..\..\gui\message.h" />
- <File RelativePath="..\..\gui\object.cpp" />
- <File RelativePath="..\..\gui\object.h" />
- <File RelativePath="..\..\gui\options.cpp" />
- <File RelativePath="..\..\gui\options.h" />
- <File RelativePath="..\..\gui\PopUpWidget.cpp" />
- <File RelativePath="..\..\gui\PopUpWidget.h" />
- <File RelativePath="..\..\gui\saveload.cpp" />
- <File RelativePath="..\..\gui\saveload.h" />
- <File RelativePath="..\..\gui\ScrollBarWidget.cpp" />
- <File RelativePath="..\..\gui\ScrollBarWidget.h" />
- <File RelativePath="..\..\gui\TabWidget.cpp" />
- <File RelativePath="..\..\gui\TabWidget.h" />
- <File RelativePath="..\..\gui\themebrowser.cpp" />
- <File RelativePath="..\..\gui\themebrowser.h" />
- <File RelativePath="..\..\gui\ThemeEngine.cpp" />
- <File RelativePath="..\..\gui\ThemeEngine.h" />
- <File RelativePath="..\..\gui\ThemeEval.cpp" />
- <File RelativePath="..\..\gui\ThemeLayout.cpp" />
- <File RelativePath="..\..\gui\ThemeLayout.h" />
- <File RelativePath="..\..\gui\ThemeParser.cpp" />
- <File RelativePath="..\..\gui\ThemeParser.h" />
- <File RelativePath="..\..\gui\widget.cpp" />
- <File RelativePath="..\..\gui\widget.h" />
+ <Filter
+ Name="gui"
+ >
+ <File
+ RelativePath="..\..\gui\about.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\about.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\browser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\browser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\chooser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\chooser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\console.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\console.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\credits.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\debugger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\debugger.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\dialog.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\dialog.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\editable.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\editable.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\EditTextWidget.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\EditTextWidget.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\GuiManager.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\GuiManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\Key.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\Key.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\launcher.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\launcher.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ListWidget.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ListWidget.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\massadd.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\massadd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\message.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\message.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\object.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\object.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\options.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\options.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\PopUpWidget.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\PopUpWidget.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\saveload.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\saveload.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ScrollBarWidget.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ScrollBarWidget.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\TabWidget.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\TabWidget.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\themebrowser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\themebrowser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ThemeEngine.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ThemeEngine.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ThemeEval.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ThemeLayout.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ThemeLayout.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ThemeParser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\ThemeParser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\widget.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\gui\widget.h"
+ >
+ </File>
</Filter>
- <Filter Name="graphics">
- <File RelativePath="..\..\graphics\colormasks.h" />
- <File RelativePath="..\..\graphics\conversion.cpp" />
- <File RelativePath="..\..\graphics\conversion.h" />
- <File RelativePath="..\..\graphics\cursorman.cpp" />
- <File RelativePath="..\..\graphics\cursorman.h" />
- <File RelativePath="..\..\graphics\dither.cpp" />
- <File RelativePath="..\..\graphics\dither.h" />
- <File RelativePath="..\..\graphics\font.cpp" />
- <File RelativePath="..\..\graphics\font.h" />
- <File RelativePath="..\..\graphics\fontman.cpp" />
- <File RelativePath="..\..\graphics\fontman.h" />
- <File RelativePath="..\..\graphics\iff.cpp" />
- <File RelativePath="..\..\graphics\iff.h" />
- <File RelativePath="..\..\graphics\imagedec.cpp" />
- <File RelativePath="..\..\graphics\imagedec.h" />
- <File RelativePath="..\..\graphics\jpeg.cpp" />
- <File RelativePath="..\..\graphics\jpeg.h" />
- <File RelativePath="..\..\graphics\pixelformat.h" />
- <File RelativePath="..\..\graphics\primitives.cpp" />
- <File RelativePath="..\..\graphics\primitives.h" />
- <File RelativePath="..\..\graphics\scaler.cpp" />
- <File RelativePath="..\..\graphics\scaler.h" />
- <File RelativePath="..\..\graphics\sjis.cpp" />
- <File RelativePath="..\..\graphics\sjis.h" />
- <File RelativePath="..\..\graphics\surface.cpp" />
- <File RelativePath="..\..\graphics\surface.h" />
- <File RelativePath="..\..\graphics\thumbnail.cpp" />
- <File RelativePath="..\..\graphics\thumbnail.h" />
- <File RelativePath="..\..\graphics\VectorRenderer.cpp" />
- <File RelativePath="..\..\graphics\VectorRenderer.h" />
- <File RelativePath="..\..\graphics\VectorRendererSpec.cpp" />
- <File RelativePath="..\..\graphics\VectorRendererSpec.h" />
- <Filter Name="scaler">
- <File RelativePath="..\..\graphics\scaler\2xsai.cpp" />
- <File RelativePath="..\..\graphics\scaler\aspect.cpp" />
- <File RelativePath="..\..\graphics\scaler\hq2x.cpp" />
- <File RelativePath="..\..\graphics\scaler\hq2x.h" />
+ <Filter
+ Name="graphics"
+ >
+ <File
+ RelativePath="..\..\graphics\colormasks.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\conversion.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\conversion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\cursorman.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\cursorman.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\dither.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\dither.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\font.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\font.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\fontman.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\fontman.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\iff.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\iff.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\imagedec.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\imagedec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\font.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\font.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\jpeg.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\jpeg.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\pixelformat.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\primitives.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\sjis.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\sjis.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\surface.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\surface.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\thumbnail.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\thumbnail.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\VectorRenderer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\VectorRenderer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\VectorRendererSpec.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\VectorRendererSpec.h"
+ >
+ </File>
+ <Filter
+ Name="scaler"
+ >
+ <File
+ RelativePath="..\..\graphics\scaler\2xsai.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\aspect.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\hq2x.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\hq2x.h"
+ >
+ </File>
<File
RelativePath="..\..\graphics\scaler\hq2x_i386.asm"
>
@@ -406,8 +1464,14 @@
/>
</FileConfiguration>
</File>
- <File RelativePath="..\..\graphics\scaler\hq3x.cpp" />
- <File RelativePath="..\..\graphics\scaler\hq3x.h" />
+ <File
+ RelativePath="..\..\graphics\scaler\hq3x.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\hq3x.h"
+ >
+ </File>
<File
RelativePath="..\..\graphics\scaler\hq3x_i386.asm"
>
@@ -430,51 +1494,169 @@
/>
</FileConfiguration>
</File>
- <File RelativePath="..\..\graphics\scaler\intern.h" />
- <File RelativePath="..\..\graphics\scaler\scale2x.cpp" />
- <File RelativePath="..\..\graphics\scaler\scale2x.h" />
- <File RelativePath="..\..\graphics\scaler\scale3x.cpp" />
- <File RelativePath="..\..\graphics\scaler\scale3x.h" />
- <File RelativePath="..\..\graphics\scaler\scalebit.cpp" />
- <File RelativePath="..\..\graphics\scaler\scalebit.h" />
- <File RelativePath="..\..\graphics\scaler\thumbnail_intern.cpp" />
+ <File
+ RelativePath="..\..\graphics\scaler\intern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\scale2x.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\scale2x.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\scale3x.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\scale3x.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\scalebit.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\scalebit.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\scaler\thumbnail_intern.cpp"
+ >
+ </File>
</Filter>
- <Filter Name="fonts">
- <File RelativePath="..\..\graphics\fonts\consolefont.cpp" />
- <File RelativePath="..\..\graphics\fonts\newfont.cpp" />
- <File RelativePath="..\..\graphics\fonts\newfont_big.cpp" />
- <File RelativePath="..\..\graphics\fonts\scummfont.cpp" />
+ <Filter
+ Name="fonts"
+ >
+ <File
+ RelativePath="..\..\graphics\fonts\consolefont.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\fonts\newfont.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\fonts\newfont_big.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\fonts\scummfont.cpp"
+ >
+ </File>
</Filter>
- <Filter Name="video">
- <File RelativePath="..\..\graphics\video\dxa_decoder.cpp" />
- <File RelativePath="..\..\graphics\video\dxa_decoder.h" />
- <File RelativePath="..\..\graphics\video\flic_decoder.cpp" />
- <File RelativePath="..\..\graphics\video\flic_decoder.h" />
- <File RelativePath="..\..\graphics\video\mpeg_player.cpp" />
- <File RelativePath="..\..\graphics\video\mpeg_player.h" />
- <File RelativePath="..\..\graphics\video\smk_decoder.cpp" />
- <File RelativePath="..\..\graphics\video\smk_decoder.h" />
- <File RelativePath="..\..\graphics\video\video_player.cpp" />
- <File RelativePath="..\..\graphics\video\video_player.h" />
- <Filter Name="coktelvideo">
- <File RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.cpp" />
- <File RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.h" />
- <File RelativePath="..\..\graphics\video\coktelvideo\indeo3.cpp" />
- <File RelativePath="..\..\graphics\video\coktelvideo\indeo3.h" />
- <File RelativePath="..\..\graphics\video\coktelvideo\indeo3data.h" />
+ <Filter
+ Name="video"
+ >
+ <File
+ RelativePath="..\..\graphics\video\dxa_decoder.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\dxa_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\flic_decoder.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\flic_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\mpeg_player.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\mpeg_player.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\smk_decoder.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\smk_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\video_player.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\video_player.h"
+ >
+ </File>
+ <Filter
+ Name="coktelvideo"
+ >
+ <File
+ RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\coktelvideo\indeo3.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\coktelvideo\indeo3.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\video\coktelvideo\indeo3data.h"
+ >
+ </File>
</Filter>
</Filter>
</Filter>
- <Filter Name="engines">
- <File RelativePath="..\..\engines\advancedDetector.cpp" />
- <File RelativePath="..\..\engines\advancedDetector.h" />
- <File RelativePath="..\..\engines\dialogs.cpp" />
- <File RelativePath="..\..\engines\dialogs.h" />
- <File RelativePath="..\..\engines\engine.cpp" />
- <File RelativePath="..\..\engines\engine.h" />
- <File RelativePath="..\..\engines\game.cpp" />
- <File RelativePath="..\..\engines\game.h" />
- <File RelativePath="..\..\engines\metaengine.h" />
+ <Filter
+ Name="engines"
+ >
+ <File
+ RelativePath="..\..\engines\advancedDetector.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\advancedDetector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\dialogs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\dialogs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\engine.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\engine.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\game.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\game.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\metaengine.h"
+ >
+ </File>
</Filter>
</Files>
+ <Globals>
+ </Globals>
</VisualStudioProject>
diff --git a/dists/redhat/scummvm.spec b/dists/redhat/scummvm.spec
index 9981940678..2a4383c17b 100644
--- a/dists/redhat/scummvm.spec
+++ b/dists/redhat/scummvm.spec
@@ -7,7 +7,7 @@
# Prologue information
#------------------------------------------------------------------------------
Name : scummvm
-Version : 1.0.0svn
+Version : 1.1.0svn
Release : 1
Summary : Graphic adventure game interpreter
Group : Interpreters
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index 2b794fdded..31e4b8bacb 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -7,8 +7,8 @@ IDI_ICON ICON DISCARDABLE "../../icons/scummvm.ico"
#endif
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,0
- PRODUCTVERSION 1,0,0,0
+ FILEVERSION 1,1,0,0
+ PRODUCTVERSION 1,1,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -25,13 +25,13 @@ BEGIN
BEGIN
VALUE "Comments", "Look! A three headed monkey (TM)! .. Nice use of the TM!\0"
VALUE "FileDescription", "http://www.scummvm.org/\0"
- VALUE "FileVersion", "1.0.0svn\0"
+ VALUE "FileVersion", "1.1.0svn\0"
VALUE "InternalName", "scummvm\0"
VALUE "LegalCopyright", "Copyright © 2001-2009 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"
- VALUE "ProductVersion", "1.0.0svn\0"
+ VALUE "ProductVersion", "1.1.0svn\0"
END
END
BLOCK "VarFileInfo"
diff --git a/dists/slackware/scummvm.SlackBuild b/dists/slackware/scummvm.SlackBuild
index 095581bf52..4ca5a7c662 100755
--- a/dists/slackware/scummvm.SlackBuild
+++ b/dists/slackware/scummvm.SlackBuild
@@ -8,7 +8,7 @@ if [ "$TMP" = "" ]; then
fi
PKG=$TMP/package-scummvm
-VERSION=1.0.0svn
+VERSION=1.1.0svn
ARCH=i486
BUILD=1
diff --git a/dists/wii/meta.xml b/dists/wii/meta.xml
index a0cb6838fc..99d96e7f01 100644
--- a/dists/wii/meta.xml
+++ b/dists/wii/meta.xml
@@ -2,7 +2,7 @@
<app version="1">
<name>ScummVM</name>
<coder>The ScummVM Team</coder>
- <version>1.0.0svn@REVISION@</version>
+ <version>1.1.0svn@REVISION@</version>
<release_date>@TIMESTAMP@</release_date>
<short_description>Point &amp; Click Adventures</short_description>
<long_description>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!
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index e373dd3e6d..69b27e10f9 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -25,6 +25,7 @@
#include "common/md5.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -271,19 +272,6 @@ void AgiEngine::processEvents() {
}
}
-void AgiEngine::checkQuickLoad() {
- if (ConfMan.hasKey("save_slot")) {
- char saveNameBuffer[256];
-
- snprintf (saveNameBuffer, 256, "%s.%03d", _targetName.c_str(), ConfMan.getInt("save_slot"));
-
- if (loadGame(saveNameBuffer, false) == errOK) { // Do not check game id
- _game.exitAllLogics = 1;
- _menu->enableAll();
- }
- }
-}
-
void AgiEngine::pollTimer(void) {
static uint32 m = 0;
uint32 dm;
@@ -301,40 +289,10 @@ void AgiEngine::pollTimer(void) {
m = g_tickTimer;
}
-bool AgiEngine::isKeypress(void) {
- processEvents();
- return _keyQueueStart != _keyQueueEnd;
-}
-
-int AgiEngine::getKeypress(void) {
- int k;
-
- while (_keyQueueStart == _keyQueueEnd) // block
- pollTimer();
-
- keyDequeue(k);
-
- return k;
-}
-
-void AgiEngine::clearKeyQueue(void) {
- while (isKeypress()) {
- getKeypress();
- }
-}
-
void AgiEngine::agiTimerFunctionLow(void *refCon) {
g_tickTimer++;
}
-void AgiEngine::clearImageStack(void) {
- _imageStack.clear();
-}
-
-void AgiEngine::releaseImageStack(void) {
- _imageStack.clear();
-}
-
void AgiEngine::pause(uint32 msec) {
uint32 endTime = _system->getMillis() + msec;
@@ -348,38 +306,6 @@ void AgiEngine::pause(uint32 msec) {
_gfx->setCursor(_renderMode == Common::kRenderAmiga);
}
-void AgiEngine::recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
- int16 p4, int16 p5, int16 p6, int16 p7) {
- ImageStackElement pnew;
-
- pnew.type = type;
- pnew.pad = 0;
- pnew.parm1 = p1;
- pnew.parm2 = p2;
- pnew.parm3 = p3;
- pnew.parm4 = p4;
- pnew.parm5 = p5;
- pnew.parm6 = p6;
- pnew.parm7 = p7;
-
- _imageStack.push(pnew);
-}
-
-void AgiEngine::replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
- int16 p4, int16 p5, int16 p6, int16 p7) {
- switch (type) {
- case ADD_PIC:
- debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1);
- agiLoadResource(rPICTURE, p1);
- _picture->decodePicture(p1, p2, p3 != 0);
- break;
- case ADD_VIEW:
- agiLoadResource(rVIEW, p1);
- _sprites->addToPic(p1, p2, p3, p4, p5, p6, p7);
- break;
- }
-}
-
void AgiEngine::initPriTable() {
int i, p, y = 0;
@@ -489,11 +415,6 @@ int AgiEngine::agiInit() {
_game.mouseFence.setWidth(0); // Reset
- _game.lastController = 0;
- for (i = 0; i < MAX_DIRS; i++)
- _game.controllerOccured[i] = false;
-
-
return ec;
}
@@ -530,21 +451,6 @@ int AgiEngine::agiDeinit() {
return ec;
}
-int AgiEngine::agiDetectGame() {
- int ec = errOK;
-
- assert(_gameDescription != NULL);
-
- if (getVersion() <= 0x2999) {
- _loader = new AgiLoader_v2(this);
- } else {
- _loader = new AgiLoader_v3(this);
- }
- ec = _loader->detectGame();
-
- return ec;
-}
-
int AgiEngine::agiLoadResource(int r, int n) {
int i;
@@ -587,67 +493,6 @@ static const GameSettings agiSettings[] = {
{NULL, NULL, 0, 0, NULL}
};
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, bool positive) const {
- if (_amigaStyle) {
- if (positive) {
- if (pressed) { // Positive pressed Amiga-style button
- if (_olderAgi) {
- return AgiTextColor(amigaBlack, amigaOrange);
- } else {
- return AgiTextColor(amigaBlack, amigaPurple);
- }
- } else { // Positive unpressed Amiga-style button
- return AgiTextColor(amigaWhite, amigaGreen);
- }
- } else { // _amigaStyle && !positive
- if (pressed) { // Negative pressed Amiga-style button
- return AgiTextColor(amigaBlack, amigaCyan);
- } else { // Negative unpressed Amiga-style button
- return AgiTextColor(amigaWhite, amigaRed);
- }
- }
- } else { // PC-style button
- if (hasFocus || pressed) { // A pressed or in focus PC-style button
- return AgiTextColor(pcWhite, pcBlack);
- } else { // An unpressed PC-style button without focus
- return AgiTextColor(pcBlack, pcWhite);
- }
- }
-}
-
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const {
- return getColor(hasFocus, pressed, AgiTextColor(baseFgColor, baseBgColor));
-}
-
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const {
- if (hasFocus || pressed)
- return baseColor.swap();
- else
- return baseColor;
-}
-
-int AgiButtonStyle::getTextOffset(bool hasFocus, bool pressed) const {
- return (pressed && !_amigaStyle) ? 1 : 0;
-}
-
-bool AgiButtonStyle::getBorder(bool hasFocus, bool pressed) const {
- return _amigaStyle && !_authenticAmiga && (hasFocus || pressed);
-}
-
-void AgiButtonStyle::setAmigaStyle(bool amigaStyle, bool olderAgi, bool authenticAmiga) {
- _amigaStyle = amigaStyle;
- _olderAgi = olderAgi;
- _authenticAmiga = authenticAmiga;
-}
-
-void AgiButtonStyle::setPcStyle(bool pcStyle) {
- setAmigaStyle(!pcStyle);
-}
-
-AgiButtonStyle::AgiButtonStyle(Common::RenderMode renderMode) {
- setAmigaStyle(renderMode == Common::kRenderAmiga);
-}
-
AgiBase::AgiBase(OSystem *syst, const AGIGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
_noSaveLoadAllowed = false;
@@ -671,7 +516,7 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
parseFeatures();
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "agi");
+ g_eventRec.registerRandomSource(*_rnd, "agi");
Common::addDebugChannel(kDebugLevelMain, "Main", "Generic debug level");
Common::addDebugChannel(kDebugLevelResources, "Resources", "Resources debugging");
@@ -718,6 +563,12 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_predictiveDictLine = NULL;
_predictiveDictLineCount = 0;
_firstSlot = 0;
+
+ // NOTE: On game reload the keys do not get set again,
+ // thus it is incorrect to reset it in agiInit(). Fixes bug #2823762
+ _game.lastController = 0;
+ for (int i = 0; i < MAX_DIRS; i++)
+ _game.controllerOccured[i] = false;
}
void AgiEngine::initialize() {
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 14e1fd448b..ab572b0dd0 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -760,8 +760,6 @@ public:
void initVersion(void);
void setVersion(uint16 version);
- Common::Error loadGameState(int slot);
- Common::Error saveGameState(int slot, const char *desc);
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
};
@@ -785,6 +783,8 @@ public:
return _gameId;
}
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const char *desc);
private:
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp
index bf4622bc08..d212f8c2e0 100644
--- a/engines/agi/cycle.cpp
+++ b/engines/agi/cycle.cpp
@@ -328,7 +328,7 @@ int AgiEngine::playGame() {
_game.vars[vKey] = 0;
debugC(2, kDebugLevelMain, "Entering main loop");
- bool firstLoop = true;
+ bool firstLoop = !getflag(fRestartGame); // Do not restore on game restart
do {
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 910f6e0e55..553e42f88e 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -1290,20 +1290,6 @@ const ADGameDescription *AgiMetaEngine::fallbackDetect(const Common::FSList &fsl
namespace Agi {
-Common::Error AgiBase::loadGameState(int slot) {
- static char saveLoadSlot[12];
- sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
- loadGame(saveLoadSlot);
- return Common::kNoError; // TODO: return success/failure
-}
-
-Common::Error AgiBase::saveGameState(int slot, const char *desc) {
- static char saveLoadSlot[12];
- sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
- saveGame(saveLoadSlot, desc);
- return Common::kNoError; // TODO: return success/failure
-}
-
bool AgiBase::canLoadGameStateCurrently() {
return (!(getGameType() == GType_PreAGI) && getflag(fMenusWork) && !_noSaveLoadAllowed);
}
@@ -1312,4 +1298,19 @@ bool AgiBase::canSaveGameStateCurrently() {
return (!(getGameType() == GType_PreAGI) && getflag(fMenusWork) && !_noSaveLoadAllowed && _game.inputEnabled);
}
+int AgiEngine::agiDetectGame() {
+ int ec = errOK;
+
+ assert(_gameDescription != NULL);
+
+ if (getVersion() <= 0x2999) {
+ _loader = new AgiLoader_v2(this);
+ } else {
+ _loader = new AgiLoader_v3(this);
+ }
+ ec = _loader->detectGame();
+
+ return ec;
+}
+
} // End of namespace Agi
diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp
index 6604587051..b47a39e592 100644
--- a/engines/agi/keyboard.cpp
+++ b/engines/agi/keyboard.cpp
@@ -393,6 +393,11 @@ int AgiEngine::waitKey() {
_gfx->doUpdate();
}
+
+ // Have to clear it as original did not set this variable, and we do it in doPollKeyboard()
+ // Fixes bug #2823759
+ _game.keypress = 0;
+
return key;
}
@@ -409,7 +414,33 @@ int AgiEngine::waitAnyKey() {
break;
_gfx->doUpdate();
}
+
+ // Have to clear it as original did not set this variable, and we do it in doPollKeyboard()
+ _game.keypress = 0;
+
return key;
}
+bool AgiEngine::isKeypress(void) {
+ processEvents();
+ return _keyQueueStart != _keyQueueEnd;
+}
+
+int AgiEngine::getKeypress(void) {
+ int k;
+
+ while (_keyQueueStart == _keyQueueEnd) // block
+ pollTimer();
+
+ keyDequeue(k);
+
+ return k;
+}
+
+void AgiEngine::clearKeyQueue(void) {
+ while (isKeypress()) {
+ getKeypress();
+ }
+}
+
} // End of namespace Agi
diff --git a/engines/agi/menu.cpp b/engines/agi/menu.cpp
index 27e234ebc9..5d30eda81d 100644
--- a/engines/agi/menu.cpp
+++ b/engines/agi/menu.cpp
@@ -493,4 +493,66 @@ void Menu::enableAll() {
}
}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, bool positive) const {
+ if (_amigaStyle) {
+ if (positive) {
+ if (pressed) { // Positive pressed Amiga-style button
+ if (_olderAgi) {
+ return AgiTextColor(amigaBlack, amigaOrange);
+ } else {
+ return AgiTextColor(amigaBlack, amigaPurple);
+ }
+ } else { // Positive unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaGreen);
+ }
+ } else { // _amigaStyle && !positive
+ if (pressed) { // Negative pressed Amiga-style button
+ return AgiTextColor(amigaBlack, amigaCyan);
+ } else { // Negative unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaRed);
+ }
+ }
+ } else { // PC-style button
+ if (hasFocus || pressed) { // A pressed or in focus PC-style button
+ return AgiTextColor(pcWhite, pcBlack);
+ } else { // An unpressed PC-style button without focus
+ return AgiTextColor(pcBlack, pcWhite);
+ }
+ }
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const {
+ return getColor(hasFocus, pressed, AgiTextColor(baseFgColor, baseBgColor));
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const {
+ if (hasFocus || pressed)
+ return baseColor.swap();
+ else
+ return baseColor;
+}
+
+int AgiButtonStyle::getTextOffset(bool hasFocus, bool pressed) const {
+ return (pressed && !_amigaStyle) ? 1 : 0;
+}
+
+bool AgiButtonStyle::getBorder(bool hasFocus, bool pressed) const {
+ return _amigaStyle && !_authenticAmiga && (hasFocus || pressed);
+}
+
+void AgiButtonStyle::setAmigaStyle(bool amigaStyle, bool olderAgi, bool authenticAmiga) {
+ _amigaStyle = amigaStyle;
+ _olderAgi = olderAgi;
+ _authenticAmiga = authenticAmiga;
+}
+
+void AgiButtonStyle::setPcStyle(bool pcStyle) {
+ setAmigaStyle(!pcStyle);
+}
+
+AgiButtonStyle::AgiButtonStyle(Common::RenderMode renderMode) {
+ setAmigaStyle(renderMode == Common::kRenderAmiga);
+}
+
} // End of namespace Agi
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index e728f2f695..7a6608d0d0 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -1267,7 +1267,7 @@ void Mickey::pressOB(int iButton) {
}
// print pressed buttons
- printLine("MICKEY HAS PRESSED: ");
+ printLine("MICKEY HAS PRESSED: ");
_vm->drawStr(20, 22, IDA_DEFAULT, szButtons);
waitAnyKey();
}
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 7c84f1dd72..50b329c0b6 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -32,6 +32,7 @@
#include "common/file.h"
#include "graphics/thumbnail.h"
+#include "common/config-manager.h"
#include "agi/agi.h"
#include "agi/graphics.h"
@@ -925,4 +926,85 @@ int AgiEngine::loadGameSimple() {
return rc;
}
+void AgiEngine::recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
+ int16 p4, int16 p5, int16 p6, int16 p7) {
+ ImageStackElement pnew;
+
+ pnew.type = type;
+ pnew.pad = 0;
+ pnew.parm1 = p1;
+ pnew.parm2 = p2;
+ pnew.parm3 = p3;
+ pnew.parm4 = p4;
+ pnew.parm5 = p5;
+ pnew.parm6 = p6;
+ pnew.parm7 = p7;
+
+ _imageStack.push(pnew);
+}
+
+void AgiEngine::replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
+ int16 p4, int16 p5, int16 p6, int16 p7) {
+ switch (type) {
+ case ADD_PIC:
+ debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1);
+ agiLoadResource(rPICTURE, p1);
+ _picture->decodePicture(p1, p2, p3 != 0);
+ break;
+ case ADD_VIEW:
+ agiLoadResource(rVIEW, p1);
+ _sprites->addToPic(p1, p2, p3, p4, p5, p6, p7);
+ break;
+ }
+}
+
+void AgiEngine::clearImageStack(void) {
+ _imageStack.clear();
+}
+
+void AgiEngine::releaseImageStack(void) {
+ _imageStack.clear();
+}
+
+void AgiEngine::checkQuickLoad() {
+ if (ConfMan.hasKey("save_slot")) {
+ char saveNameBuffer[256];
+
+ snprintf (saveNameBuffer, 256, "%s.%03d", _targetName.c_str(), ConfMan.getInt("save_slot"));
+
+ _sprites->eraseBoth();
+ _sound->stopSound();
+
+ if (loadGame(saveNameBuffer, false) == errOK) { // Do not check game id
+ _game.exitAllLogics = 1;
+ _menu->enableAll();
+ }
+ }
+}
+
+Common::Error AgiEngine::loadGameState(int slot) {
+ static char saveLoadSlot[12];
+ sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
+
+ _sprites->eraseBoth();
+ _sound->stopSound();
+
+ if (loadGame(saveLoadSlot) == errOK) {
+ _game.exitAllLogics = 1;
+ _menu->enableAll();
+ return Common::kNoError;
+ } else {
+ return Common::kUnknownError;
+ }
+}
+
+Common::Error AgiEngine::saveGameState(int slot, const char *desc) {
+ static char saveLoadSlot[12];
+ sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
+ if (saveGame(saveLoadSlot, desc) == errOK)
+ return Common::kNoError;
+ else
+ return Common::kUnknownError;
+}
+
} // End of namespace Agi
diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp
index f3c0b7365c..63ac880267 100644
--- a/engines/agi/sprite.cpp
+++ b/engines/agi/sprite.cpp
@@ -56,9 +56,10 @@ struct Sprite {
void *SpritesMgr::poolAlloc(int size) {
uint8 *x;
- // Adjust size to 32-bit boundary to prevent data misalignment
+ // Adjust size to sizeof(void *) boundary to prevent data misalignment
// errors.
- size = (size + 3) & ~3;
+ const int alignPadding = sizeof(void*) - 1;
+ size = (size + alignPadding) & ~alignPadding;
x = _poolTop;
_poolTop += size;
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 9903952577..0e53698b59 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -27,6 +27,7 @@
#include "common/file.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "agos/debugger.h"
#include "agos/intern.h"
@@ -528,7 +529,7 @@ AGOSEngine::AGOSEngine(OSystem *syst)
File::addDefaultDirectory(_gameDataDir.getChild("speech"));
File::addDefaultDirectory(_gameDataDir.getChild("SPEECH"));
- syst->getEventManager()->registerRandomSource(_rnd, "agos");
+ g_eventRec.registerRandomSource(_rnd, "agos");
}
Common::Error AGOSEngine::init() {
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 263811b78a..ac1f33428b 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -1248,6 +1248,7 @@ protected:
void hitarea_stuff_helper_2();
void fastFadeIn();
void slowFadeIn();
+ void fullFade();
virtual void vcStopAnimation(uint16 zone, uint16 sprite);
@@ -1265,20 +1266,6 @@ protected:
#ifdef ENABLE_PN
class AGOSEngine_PN : public AGOSEngine {
- struct StackFrame {
- StackFrame *nextframe;
- int16 flag[6];
- int16 param[8];
- int16 classnum;
- uint8 *linpos;
- uint8 *lbase;
- int16 ll;
- int16 linenum;
- int16 process;
- jmp_buf *savearea;
- StackFrame() { memset(this, 0, sizeof(*this)); }
- };
-
virtual Common::Error go();
void demoSeq();
@@ -1358,8 +1345,30 @@ public:
void opn_opcode62();
void opn_opcode63();
+protected:
+ struct StackFrame {
+ StackFrame *nextframe;
+ int16 flag[6];
+ int16 param[8];
+ int16 classnum;
+ uint8 *linpos;
+ uint8 *lbase;
+ int16 ll;
+ int16 linenum;
+ int16 process;
+ int tagOfParentDoline; ///< tag of the doline "instance" to which this StackFrame belongs
+ StackFrame() { memset(this, 0, sizeof(*this)); }
+ };
+
+
StackFrame *_stackbase;
+ int _tagOfActiveDoline; ///< tag of the active doline "instance"
+ int _dolineReturnVal;
+
+ jmp_buf _loadfail;
+
+
byte *_dataBase, *_textBase;
uint32 _dataBaseSize, _textBaseSize;
@@ -1404,8 +1413,6 @@ public:
int _linembr;
uint8 *_linebase;
uint8 *_workptr;
- jmp_buf *_cjmpbuff;
- jmp_buf _loadfail;
uint16 getptr(uint32 pos);
uint32 getlong(uint32 pos);
@@ -1429,7 +1436,6 @@ public:
void addstack(int type);
void dumpstack();
- void junkstack();
void popstack(int type);
void funccpy(int *store);
void funcentry(int *storestore, int procn);
@@ -1465,8 +1471,8 @@ public:
virtual void windowPutChar(WindowBlock *window, byte c, byte b = 0);
bool badload(int8 errorNum);
- int loadfl(char *name);
- int savfl(char *name);
+ int loadFile(char *name);
+ int saveFile(char *name);
void getFilename();
void sysftodb();
void dbtosysf();
diff --git a/engines/agos/debug.h b/engines/agos/debug.h
index 375878a4bc..38674de765 100644
--- a/engines/agos/debug.h
+++ b/engines/agos/debug.h
@@ -2549,7 +2549,7 @@ const char *const ww_videoOpcodeNameTable[] = {
"j|IF_EGA",
/* 60 */
"d|STOP_ANIMATE",
- "d|VC_61",
+ "d|INTRO",
"|FASTFADEOUT",
"|FASTFADEIN",
};
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index ec21acc0a1..0c672aef52 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -26,6 +26,8 @@
namespace AGOS {
using Common::GUIO_NONE;
+using Common::GUIO_NOMIDI;
+using Common::GUIO_NOMUSIC;
using Common::GUIO_NOSPEECH;
using Common::GUIO_NOSUBTITLES;
@@ -45,7 +47,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_PN,
@@ -68,7 +70,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_PN,
@@ -91,7 +93,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_PN,
@@ -137,7 +139,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -158,7 +160,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -179,7 +181,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -200,7 +202,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -223,7 +225,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -246,7 +248,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -269,7 +271,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -410,7 +412,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -436,7 +438,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -462,7 +464,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -488,7 +490,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -514,7 +516,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -540,7 +542,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -566,7 +568,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -802,7 +804,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_WW,
@@ -829,7 +831,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_WW,
@@ -992,7 +994,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAcorn,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1017,7 +1019,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAcorn,
ADGF_DEMO,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1042,7 +1044,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAcorn,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1066,7 +1068,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1090,7 +1092,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1114,7 +1116,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1138,7 +1140,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1162,7 +1164,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1186,7 +1188,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1210,7 +1212,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1234,7 +1236,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1523,7 +1525,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1548,7 +1550,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1573,7 +1575,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1598,7 +1600,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1623,7 +1625,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1648,7 +1650,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1673,7 +1675,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::HB_ISR,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1698,7 +1700,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1724,7 +1726,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1749,7 +1751,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1774,7 +1776,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1799,7 +1801,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1824,7 +1826,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSPEECH
},
GType_SIMON2,
@@ -1949,7 +1951,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -1974,7 +1976,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -1999,7 +2001,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2024,7 +2026,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2049,7 +2051,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2074,7 +2076,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2099,7 +2101,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2124,7 +2126,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2175,7 +2177,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2200,7 +2202,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2225,7 +2227,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::CZ_CZE,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2250,7 +2252,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2275,7 +2277,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2300,7 +2302,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2325,7 +2327,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2346,7 +2348,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2367,7 +2369,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2391,7 +2393,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2415,7 +2417,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2439,7 +2441,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2463,7 +2465,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2487,7 +2489,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2511,7 +2513,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2534,7 +2536,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2557,7 +2559,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2580,7 +2582,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2603,7 +2605,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2626,7 +2628,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2649,7 +2651,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2672,7 +2674,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2693,7 +2695,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_PP,
@@ -2714,7 +2716,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2735,7 +2737,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2756,7 +2758,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2777,7 +2779,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2798,7 +2800,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index 45443aa335..368da5db83 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -871,13 +871,11 @@ void AGOSEngine::slowFadeIn() {
_fastFadeInFlag &= ~0x8000;
_paletteFlag = false;
- memset(_videoBuf1, 0, 1024);
- memcpy(_currentPalette, _displayPalette, 1024);
- memcpy(_videoBuf1 + 1024, _displayPalette, 1024);
+ memset(_currentPalette, 0, sizeof(_currentPalette));
for (c = 255; c >= 0; c -= 4) {
- src = _videoBuf1 + 1024;
- dst = _videoBuf1;
+ src = _displayPalette;
+ dst = _currentPalette;
for (p = _fastFadeInFlag; p !=0 ; p -= 3) {
if (src[0] >= c)
@@ -889,7 +887,7 @@ void AGOSEngine::slowFadeIn() {
src += 4;
dst += 4;
}
- _system->setPalette(_videoBuf1, 0, _fastFadeCount);
+ _system->setPalette(_currentPalette, 0, _fastFadeCount);
delay(5);
}
_fastFadeInFlag = 0;
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
index cf6e808384..5c37fe620a 100644
--- a/engines/agos/input.cpp
+++ b/engines/agos/input.cpp
@@ -664,10 +664,11 @@ void AGOSEngine_PN::handleKeyboard() {
}
}
if (chr == -1) {
- chr = _keyPressed.ascii;
- if (chr == 8 || chr == 13) {
+ if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE || _keyPressed.keycode == Common::KEYCODE_RETURN) {
+ chr = _keyPressed.keycode;
addChar(chr);
} else if (!(_videoLockOut & 0x10)) {
+ chr = _keyPressed.ascii;
if (chr >= 32)
addChar(chr);
}
diff --git a/engines/agos/midiparser_s1d.cpp b/engines/agos/midiparser_s1d.cpp
index d77621cc7b..568135ef8c 100644
--- a/engines/agos/midiparser_s1d.cpp
+++ b/engines/agos/midiparser_s1d.cpp
@@ -126,6 +126,10 @@ void MidiParser_S1D::parseNextEvent(EventInfo &info) {
switch (info.event & 0x0F) {
case 0x0:
// Trigged by MOD2/MOD6/MOD15 in Waxworks
+ // Pure guesswork
+ info.ext.type = *(_position._play_pos++);
+ info.length = readVLQ(_position._play_pos);
+ info.ext.data = _position._play_pos;
break;
case 0x3: // Not sure, Song Select?
diff --git a/engines/agos/pn.cpp b/engines/agos/pn.cpp
index d92efa9077..e8135f56cd 100644
--- a/engines/agos/pn.cpp
+++ b/engines/agos/pn.cpp
@@ -35,6 +35,10 @@ namespace AGOS {
AGOSEngine_PN::AGOSEngine_PN(OSystem *system)
: AGOSEngine(system) {
+ _stackbase = 0;
+ _tagOfActiveDoline = 0;
+ _dolineReturnVal = 0;
+
_dataBase = 0;
_dataBaseSize = 0;
_textBase = 0;
@@ -70,7 +74,7 @@ AGOSEngine_PN::AGOSEngine_PN(OSystem *system)
_objects = 0;
_objectCountS = 0;
- _bp = 0;
+ _bp = 0;
_xofs = 0;
_havinit = 0;
_seed = 0;
@@ -84,16 +88,12 @@ AGOSEngine_PN::AGOSEngine_PN(OSystem *system)
_linebase = 0;
_workptr = 0;
-
- _cjmpbuff = NULL;
}
AGOSEngine_PN::~AGOSEngine_PN() {
free(_dataBase);
free(_textBase);
- free(_cjmpbuff);
- free(_stackbase);
}
const byte egaPalette[48] = {
@@ -251,29 +251,33 @@ void AGOSEngine_PN::setupBoxes() {
}
void AGOSEngine_PN::processor() {
- int q;
-
setqptrs();
- q = setjmp(_loadfail);
- _variableArray[6] = 0;
+ _tagOfActiveDoline = 0;
+ int q = 0;
+ do {
+ assert(_tagOfActiveDoline == 0);
+ _dolineReturnVal = 0;
- if (getPlatform() == Common::kPlatformAtariST) {
- _variableArray[21] = 2;
- } else if (getPlatform() == Common::kPlatformAmiga) {
- _variableArray[21] = 0;
- } else {
- _variableArray[21] = 1;
- }
+ _variableArray[6] = 0;
+
+ if (getPlatform() == Common::kPlatformAtariST) {
+ _variableArray[21] = 2;
+ } else if (getPlatform() == Common::kPlatformAmiga) {
+ _variableArray[21] = 0;
+ } else {
+ _variableArray[21] = 1;
+ }
- _variableArray[16] = _quickshort[6];
- _variableArray[17] = _quickshort[7];
- _variableArray[19] = getptr(55L);
+ _variableArray[16] = _quickshort[6];
+ _variableArray[17] = _quickshort[7];
+ _variableArray[19] = getptr(55L);
- // q indicates the process to run and is 0 the first time,
- // but 1 later on (i.e., when we are "called" from badload()).
- setposition(q, 0);
- doline(0);
+ // q indicates the process to run and is 0 the first time,
+ // but 1 later on (i.e., when we are "called" from badload()).
+ setposition(0, 0);
+ q = doline(0);
+ } while (q);
}
void AGOSEngine_PN::setqptrs() {
diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp
index e85440d8e1..4f3582b55d 100644
--- a/engines/agos/res_snd.cpp
+++ b/engines/agos/res_snd.cpp
@@ -285,10 +285,6 @@ void AGOSEngine_Simon1::playMusic(uint16 music, uint16 track) {
void AGOSEngine::playMusic(uint16 music, uint16 track) {
stopMusic();
- // FIXME: Music too unstable, when switching locations.
- if (getPlatform() == Common::kPlatformPC && getGameType() == GType_WW)
- return;
-
if (getPlatform() == Common::kPlatformAmiga) {
playModule(music);
} else if (getPlatform() == Common::kPlatformAtariST) {
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 16bde0097b..3787617be7 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/savefile.h"
#include "common/system.h"
@@ -231,7 +229,7 @@ bool AGOSEngine::confirmOverWrite(WindowBlock *window) {
break;
case Common::DE_DEU:
message1 = "\rDatei existiert bereits.\r\r";
- message2 = " berschreiben ?\r\r";
+ message2 = " Ueberschreiben ?\r\r";
message3 = " Ja Nein";
break;
default:
@@ -1555,13 +1553,16 @@ bool AGOSEngine_Elvira2::saveGame(uint slot, const char *caption) {
bool AGOSEngine_PN::badload(int8 errorNum) {
if (errorNum == -2)
return 0;
- /* Load error recovery routine */
+ // Load error recovery routine
+
+ // Clear any stack
while (_stackbase != NULL) {
- /* Clear any stack */
dumpstack();
}
- /* Restart from process 1 */
- longjmp(_loadfail, 1);
+
+ // Restart from process 1
+ _tagOfActiveDoline = 1;
+ _dolineReturnVal = 3;
return 1;
}
@@ -1572,7 +1573,7 @@ void AGOSEngine_PN::getFilename() {
memset(_saveFile, 0, sizeof(_saveFile));
while (!shouldQuit() && !strlen(_saveFile)) {
const char *msg = "File name : ";
- pcf((unsigned char)'\n');
+ pcf((unsigned char)'\n');
while (*msg)
pcf((unsigned char)*msg++);
@@ -1582,7 +1583,7 @@ void AGOSEngine_PN::getFilename() {
}
}
-int AGOSEngine_PN::loadfl(char *name) {
+int AGOSEngine_PN::loadFile(char *name) {
Common::InSaveFile *f;
haltAnimation();
@@ -1609,13 +1610,13 @@ int AGOSEngine_PN::loadfl(char *name) {
delete f;
return -1;
}
- delete f;
+ delete f;
restartAnimation();
dbtosysf();
return 0;
}
-int AGOSEngine_PN::savfl(char *name) {
+int AGOSEngine_PN::saveFile(char *name) {
Common::OutSaveFile *f;
sysftodb();
haltAnimation();
@@ -1625,7 +1626,7 @@ int AGOSEngine_PN::savfl(char *name) {
restartAnimation();
const char *msg = "Couldn't save. ";
- pcf((unsigned char)'\n');
+ pcf((unsigned char)'\n');
while (*msg)
pcf((unsigned char)*msg++);
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index 4f9aab2965..2885781a9f 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -324,8 +324,8 @@ void AGOSEngine_PN::opn_opcode24() {
// That value then is returned to actCallD, which once again
// returns it. In the end, this amounts to a setScriptReturn(true)
// (but possibly in a different level than the current one).
- longjmp(*(_stackbase->savearea), 2);
- setScriptReturn(false);
+ _dolineReturnVal = 2;
+ _tagOfActiveDoline = _stackbase->tagOfParentDoline;
}
void AGOSEngine_PN::opn_opcode25() {
@@ -334,13 +334,13 @@ void AGOSEngine_PN::opn_opcode25() {
// That value then is returned to actCallD, which once again
// returns it. In the end, this amounts to a setScriptReturn(false)
// (but possibly in a different level than the current one).
- longjmp(*(_stackbase->savearea), 1);
- setScriptReturn(false);
+ _dolineReturnVal = 1;
+ _tagOfActiveDoline = _stackbase->tagOfParentDoline;
}
void AGOSEngine_PN::opn_opcode26() {
while ((_stackbase != NULL) && (_stackbase->classnum != kJmpClassNum))
- junkstack();
+ dumpstack();
dumpstack();
setScriptReturn(true);
}
@@ -353,16 +353,16 @@ void AGOSEngine_PN::opn_opcode27() {
void AGOSEngine_PN::opn_opcode28() {
addstack(varval());
- _stackbase->savearea = _cjmpbuff;
+ _stackbase->tagOfParentDoline = _tagOfActiveDoline;
setScriptReturn(false);
}
void AGOSEngine_PN::opn_opcode29() {
popstack(varval());
- // Jump back to the last doline indicated by the top stackfram.
+ // Jump back to the last doline indicated by the top stackframe.
// The -1 tells it to simply go on with its business.
- longjmp(*(_stackbase->savearea), -1);
- setScriptReturn(false);
+ _dolineReturnVal = -1;
+ _tagOfActiveDoline = _stackbase->tagOfParentDoline;
}
void AGOSEngine_PN::opn_opcode30() {
@@ -386,7 +386,7 @@ void AGOSEngine_PN::opn_opcode31() {
strcpy(bf, genSaveName(slot));
break;
case 1:
- strcpy(bf, "test.sav");
+ strcpy(bf, "pn.sav");
break;
case 2:
// NOTE: Is this case ever used?
@@ -397,7 +397,7 @@ void AGOSEngine_PN::opn_opcode31() {
if (slot == -1) {
setScriptReturn(false);
} else {
- a = loadfl(bf);
+ a = loadFile(bf);
if (a)
setScriptReturn(badload(a));
else
@@ -426,7 +426,7 @@ void AGOSEngine_PN::opn_opcode32() {
strcpy(bf, genSaveName(curSlot));
break;
case 1:
- strcpy(bf, "test.sav");
+ strcpy(bf, "pn.sav");
break;
case 2:
// NOTE: Is this case ever used?
@@ -434,7 +434,7 @@ void AGOSEngine_PN::opn_opcode32() {
break;
}
- a = savfl(bf);
+ a = saveFile(bf);
setScriptReturn(a);
}
@@ -520,19 +520,32 @@ void AGOSEngine_PN::opn_opcode39() {
}
void AGOSEngine_PN::opn_opcode40() {
- setScriptReturn(doaction() | doaction());
+ int a = doaction();
+ if (_dolineReturnVal != 0)
+ return;
+ int b = doaction();
+ setScriptReturn(a | b);
}
void AGOSEngine_PN::opn_opcode41() {
- setScriptReturn(doaction() & doaction());
+ int a = doaction();
+ if (_dolineReturnVal != 0)
+ return;
+ int b = doaction();
+ setScriptReturn(a & b);
}
void AGOSEngine_PN::opn_opcode42() {
- setScriptReturn(doaction() ^ doaction());
+ int a = doaction();
+ if (_dolineReturnVal != 0)
+ return;
+ int b = doaction();
+ setScriptReturn(a ^ b);
}
void AGOSEngine_PN::opn_opcode43() {
- setScriptReturn(!(doaction()));
+ int a = doaction();
+ setScriptReturn(!a);
}
void AGOSEngine_PN::opn_opcode44() {
@@ -874,41 +887,14 @@ int AGOSEngine_PN::doaction() {
}
int AGOSEngine_PN::doline(int needsave) {
- int x;
- jmp_buf *old_jmpbuf = NULL;
- jmp_buf *mybuf;
+ assert(!_stackbase == !needsave);
- mybuf = (jmp_buf *)malloc(sizeof(jmp_buf));
- if (mybuf == NULL)
- error("doline: Out of memory - stack overflow");
-
- x = setjmp(*mybuf);
- // Looking at the longjmp calls below, x can be -1, 1 or 2
- // (and of course 0 when it returns directly, as always).
- if (x > 0) {
- dumpstack();
- // Restore the active jmpbuf to its previous value,
- // then return the longjmp value (will be 2-1=1 or 1-1=0).
- _cjmpbuff = old_jmpbuf;
- free((char *)mybuf);
- return (x - 1);
- }
+ int x;
+ int myTag = ++_tagOfActiveDoline; // Obtain a unique tag for this doline invocation
+ _dolineReturnVal = 0;
- if (x == -1) {
- // Make this doline instance the active one (again).
- // This is used to "return" over possibly multiple
- // layers of nested script invocations.
- // Kind of like throwing an exception.
- _cjmpbuff = mybuf;
- goto carryon;
- }
-
- // Remember the previous active jmpbuf (gets restored
- // above when a longjmp with a positive param occurs).
- old_jmpbuf = _cjmpbuff;
- _cjmpbuff = mybuf;
if (needsave)
- _stackbase->savearea = mybuf;
+ _stackbase->tagOfParentDoline = myTag;
do {
_linct = ((*_linebase) & 127) - 1;
@@ -919,9 +905,26 @@ int AGOSEngine_PN::doline(int needsave) {
goto skipln;
}
-carryon:
do {
x = doaction();
+
+ if (_dolineReturnVal != 0) {
+ if (_tagOfActiveDoline != myTag)
+ return 0;
+
+ x = _dolineReturnVal;
+ _dolineReturnVal = 0;
+
+ if (x > 0) {
+ if (x != 3)
+ dumpstack();
+ // Restore the active jmpbuf to its previous value,
+ // then return _dolineReturnVal-1 (will be 2-1=1 or 1-1=0).
+ _tagOfActiveDoline = myTag - 1;
+ return (x - 1);
+ }
+ }
+
} while (x && !shouldQuit());
skipln:
@@ -1063,7 +1066,7 @@ void AGOSEngine_PN::addstack(int type) {
StackFrame *a;
int i;
- a = (StackFrame *)malloc(sizeof(StackFrame));
+ a = (StackFrame *)calloc(1, sizeof(StackFrame));
if (a == NULL)
error("addstack: Out of memory - stack overflow");
@@ -1093,24 +1096,13 @@ void AGOSEngine_PN::dumpstack() {
_stackbase = a;
}
-void AGOSEngine_PN::junkstack() {
- StackFrame *a;
-
- if (_stackbase == NULL)
- error("junkstack: Stack underflow or unknown longjmp");
-
- a = _stackbase->nextframe;
- if (_stackbase->classnum == kJmpClassNum)
- free((char *)_stackbase->savearea);
- free((char *)_stackbase);
- _stackbase = a;
-}
-
void AGOSEngine_PN::popstack(int type) {
- int i;
+ int i = 0;
- while ((_stackbase != NULL) && (_stackbase->classnum != type))
- junkstack();
+ while ((_stackbase != NULL) && (_stackbase->classnum != type)) {
+ dumpstack();
+ ++i;
+ }
if (_stackbase == NULL)
error("popstack: Stack underflow or unknown longjmp");
diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp
index 2e3d936037..81efb5cd81 100644
--- a/engines/agos/script_s1.cpp
+++ b/engines/agos/script_s1.cpp
@@ -576,18 +576,15 @@ void AGOSEngine_Simon1::os1_specialFade() {
// 187: fade to black
uint i;
- memcpy(_videoBuf1, _currentPalette, 4 * 256);
-
for (i = 32; i != 0; --i) {
- paletteFadeOut(_videoBuf1, 32, 8);
- paletteFadeOut(_videoBuf1 + 4 * 48, 144, 8);
- paletteFadeOut(_videoBuf1 + 4 * 208, 48, 8);
- _system->setPalette(_videoBuf1, 0, 256);
+ paletteFadeOut(_currentPalette, 32, 8);
+ paletteFadeOut(_currentPalette + 4 * 48, 144, 8);
+ paletteFadeOut(_currentPalette + 4 * 208, 48, 8);
+ _system->setPalette(_currentPalette, 0, 256);
delay(5);
}
- memcpy(_currentPalette, _videoBuf1, 1024);
- memcpy(_displayPalette, _videoBuf1, 1024);
+ memcpy(_displayPalette, _currentPalette, 1024);
}
void AGOSEngine::scriptMouseOff() {
diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp
index f6e6630d43..de3cb55963 100644
--- a/engines/agos/vga_e2.cpp
+++ b/engines/agos/vga_e2.cpp
@@ -353,9 +353,32 @@ void AGOSEngine::vc55_moveBox() {
_needHitAreaRecalc++;
}
-void AGOSEngine::vc56_fullScreen() {
- uint8 palette[1024];
+void AGOSEngine::fullFade() {
+ uint8 *srcPal, *dstPal;
+ int c, p;
+
+ for (c = 64; c != 0; c --) {
+ srcPal = _curVgaFile2 + 32;
+ dstPal = _currentPalette;
+ for (p = 768; p !=0 ; p -= 3) {
+ uint8 r = srcPal[0] * 4;
+ if (dstPal[0] != r)
+ dstPal[0] += 4;
+ uint8 g = srcPal[1] * 4;
+ if (dstPal[1] != g)
+ dstPal[1] += 4;
+ uint8 b = srcPal[2] * 4;
+ if (dstPal[2] != b)
+ dstPal[2] += 4;
+ srcPal += 3;
+ dstPal += 4;
+ }
+ _system->setPalette(_currentPalette, 0, 256);
+ delay(5);
+ }
+}
+void AGOSEngine::vc56_fullScreen() {
Graphics::Surface *screen = _system->lockScreen();
byte *dst = (byte *)screen->pixels;
byte *src = _curVgaFile2 + 800;
@@ -367,23 +390,12 @@ void AGOSEngine::vc56_fullScreen() {
}
_system->unlockScreen();
- //fullFade();
-
- src = _curVgaFile2 + 32;
- for (int i = 0; i < 256; i++) {
- palette[i * 4 + 0] = *src++ * 4;
- palette[i * 4 + 1] = *src++ * 4;
- palette[i * 4 + 2] = *src++ * 4;
- palette[i * 4 + 3] = 0;
- }
-
- _system->setPalette(palette, 0, 256);
+ fullFade();
}
void AGOSEngine::vc57_blackPalette() {
- uint8 palette[1024];
- memset(palette, 0, sizeof(palette));
- _system->setPalette(palette, 0, 256);
+ memset(_currentPalette, 0, sizeof(_currentPalette));
+ _system->setPalette(_currentPalette, 0, 256);
}
void AGOSEngine::vc58_checkCodeWheel() {
diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp
index e7f2ad7807..afc05f7869 100644
--- a/engines/agos/vga_ww.cpp
+++ b/engines/agos/vga_ww.cpp
@@ -193,20 +193,8 @@ void AGOSEngine::vc61() {
_system->unlockScreen();
- if (a == 6) {
- //fullFade();
- src = _curVgaFile2 + 32;
-
- uint8 palette[1024];
- for (int i = 0; i < 256; i++) {
- palette[i * 4 + 0] = *src++ * 4;
- palette[i * 4 + 1] = *src++ * 4;
- palette[i * 4 + 2] = *src++ * 4;
- palette[i * 4 + 3] = 0;
- }
-
- _system->setPalette(palette, 0, 256);
- }
+ if (a == 6)
+ fullFade();
}
void AGOSEngine::vc62_fastFadeOut() {
@@ -221,8 +209,6 @@ void AGOSEngine::vc62_fastFadeOut() {
_fastFadeCount = 208;
}
- memcpy(_videoBuf1, _currentPalette, _fastFadeCount * 4);
-
if (getGameType() == GType_FF || getGameType() == GType_PP) {
if (getGameType() == GType_FF && getBitFlag(75)) {
fadeCount = 4;
@@ -237,8 +223,8 @@ void AGOSEngine::vc62_fastFadeOut() {
}
for (i = fadeCount; i != 0; --i) {
- paletteFadeOut(_videoBuf1, _fastFadeCount, fadeSize);
- _system->setPalette(_videoBuf1, 0, _fastFadeCount);
+ paletteFadeOut(_currentPalette, _fastFadeCount, fadeSize);
+ _system->setPalette(_currentPalette, 0, _fastFadeCount);
delay(5);
}
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 64a9a9dfb8..8756a2fc3c 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -64,7 +65,7 @@ CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Eng
g_cine = this;
- syst->getEventManager()->registerRandomSource(_rnd, "cine");
+ g_eventRec.registerRandomSource(_rnd, "cine");
}
CineEngine::~CineEngine() {
@@ -113,6 +114,9 @@ int CineEngine::modifyGameSpeed(int speedChange) {
}
void CineEngine::initialize() {
+ // Initialize all savegames' descriptions to empty strings
+ memset(currentSaveName, 0, sizeof(currentSaveName));
+
// Resize object table to its correct size and reset all its elements
objectTable.resize(NUM_MAX_OBJECT);
resetObjectTable();
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index 4786005647..3bc26ab417 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -607,35 +607,37 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
pattern += ".?";
Common::StringList filenames = saveFileMan->listSavefiles(pattern);
sort(filenames.begin(), filenames.end());
- Common::StringList::const_iterator file = filenames.begin();
+ Common::StringList::const_iterator file;
Common::String filename = target;
filename += ".dir";
Common::InSaveFile *in = saveFileMan->openForLoading(filename);
if (in) {
- int8 ch;
- char saveDesc[20];
- do {
+ typedef char CommandeType[20];
+ CommandeType saveNames[10];
+
+ // Initialize all savegames' descriptions to empty strings
+ // so that if the savegames' descriptions can only be partially read from file
+ // then the missing ones are correctly set to empty strings.
+ memset(saveNames, 0, sizeof(saveNames));
+
+ in->read(saveNames, 10 * 20);
+ CommandeType saveDesc;
+
+ for (file = filenames.begin(); file != filenames.end(); ++file) {
+ // Jump over savegame files that don't end with a digit (e.g. "fw.3" is ok, "fw.a" is not).
+ if (!isdigit(file->lastChar()))
+ continue;
+
// Obtain the last digit of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 1);
- uint pos = 0;
- do {
- ch = in->readByte();
- if (pos < (sizeof(saveDesc) - 1)) {
- if (ch < 32 || in->eos()) {
- saveDesc[pos++] = '\0';
- }
- else if (ch >= 32) {
- saveDesc[pos++] = ch;
- }
- }
- } while (ch >= 32 && !in->eos());
- if (saveDesc[0] != 0) {
- saveList.push_back(SaveStateDescriptor(slotNum, saveDesc));
- file++;
- }
- } while (!in->eos());
+ // Copy the savegame description making sure it ends with a trailing zero
+ strncpy(saveDesc, saveNames[slotNum], 20);
+ saveDesc[sizeof(CommandeType) - 1] = 0;
+
+ saveList.push_back(SaveStateDescriptor(slotNum, saveDesc));
+ }
}
delete in;
@@ -650,6 +652,11 @@ void CineMetaEngine::removeSaveState(const char *target, int slot) const {
typedef char CommandeType[20];
CommandeType saveNames[10];
+ // Initialize all savegames' descriptions to empty strings
+ // so that if the savegames' descriptions can only be partially read from file
+ // then the missing ones are correctly set to empty strings.
+ memset(saveNames, 0, sizeof(saveNames));
+
Common::InSaveFile *in;
char tmp[80];
@@ -707,8 +714,9 @@ Common::Error CineEngine::saveGameState(int slot, const char *desc) {
// Load savegame descriptions from index file
loadSaveDirectory();
- // Set description for selected slot
+ // Set description for selected slot making sure it ends with a trailing zero
strncpy(currentSaveName[slot], desc, 20);
+ currentSaveName[slot][sizeof(CommandeType) - 1] = 0;
// Update savegame descriptions
char indexFile[80];
diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp
index b3e3629239..757419ef87 100644
--- a/engines/cine/pal.cpp
+++ b/engines/cine/pal.cpp
@@ -239,9 +239,6 @@ Palette &Palette::saturatedAddNormalizedGray(Palette& output, byte firstIndex, b
}
// a.k.a. transformColor
-// Parameter color components (i.e. r, g and b) are in range [-7, 7]
-// e.g. r = 7 sets the resulting color's red component to maximum
-// e.g. r = -7 sets the resulting color's red component to minimum (i.e. zero)
Cine::Palette::Color Palette::saturatedAddColor(Cine::Palette::Color baseColor, signed r, signed g, signed b) const {
Cine::Palette::Color result;
result.r = CLIP<int>(baseColor.r + r, 0, _format.rMax());
diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp
index be1e19b229..158d209289 100644
--- a/engines/cine/saveload.cpp
+++ b/engines/cine/saveload.cpp
@@ -468,9 +468,18 @@ bool CineEngine::loadSaveDirectory(void) {
return false;
}
+ // Initialize all savegames' descriptions to empty strings
+ // so that if the savegames' descriptions can only be partially read from file
+ // then the missing ones are correctly set to empty strings.
+ memset(currentSaveName, 0, sizeof(currentSaveName));
+
fHandle->read(currentSaveName, 10 * 20);
delete fHandle;
+ // Make sure all savegames' descriptions end with a trailing zero.
+ for (int i = 0; i < ARRAYSIZE(currentSaveName); i++)
+ currentSaveName[i][sizeof(CommandeType) - 1] = 0;
+
return true;
}
diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
index 3d3a44a36c..7abf83f054 100644
--- a/engines/cruise/cruise.cpp
+++ b/engines/cruise/cruise.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -65,7 +66,7 @@ CruiseEngine::CruiseEngine(OSystem * syst, const CRUISEGameDescription *gameDesc
_debugger = new Debugger();
_sound = new PCSound(_mixer, this);
- syst->getEventManager()->registerRandomSource(_rnd, "cruise");
+ g_eventRec.registerRandomSource(_rnd, "cruise");
}
CruiseEngine::~CruiseEngine() {
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index e5864ebb31..94dfc95cb5 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -1390,7 +1390,7 @@ int CruiseEngine::processInput(void) {
}
// Player Menu - test for both buttons or the F10 key
- if (((button & MB_BOTH) == MB_BOTH) || (keyboardCode == Common::KEYCODE_F10)) {
+ if (((button & CRS_MB_BOTH) == CRS_MB_BOTH) || (keyboardCode == Common::KEYCODE_F10)) {
changeCursor(CURSOR_NORMAL);
keyboardCode = Common::KEYCODE_INVALID;
return (playerMenu(mouseX, mouseY));
@@ -1398,7 +1398,7 @@ int CruiseEngine::processInput(void) {
if (userWait) {
// Check for left mouse button click or Space to end user waiting
- if ((keyboardCode == Common::KEYCODE_SPACE) || (button == MB_LEFT))
+ if ((keyboardCode == Common::KEYCODE_SPACE) || (button == CRS_MB_LEFT))
userWait = 0;
keyboardCode = Common::KEYCODE_INVALID;
@@ -1450,7 +1450,7 @@ int CruiseEngine::processInput(void) {
menuDown = 0;
}
} else {
- if ((button & MB_LEFT) && (buttonDown == 0)) {
+ if ((button & CRS_MB_LEFT) && (buttonDown == 0)) {
if (menuTable[0]) {
callRelation(getSelectedEntryInMenu(menuTable[0]), dialogueObj);
@@ -1472,7 +1472,7 @@ int CruiseEngine::processInput(void) {
}
}
- } else if ((button & MB_LEFT) && (buttonDown == 0)) {
+ } else if ((button & CRS_MB_LEFT) && (buttonDown == 0)) {
// left click
buttonDown = 1;
@@ -1538,20 +1538,17 @@ int CruiseEngine::processInput(void) {
aniX = mouseX;
aniY = mouseY;
animationStart = true;
- buttonDown = 0;
}
} else {
aniX = mouseX;
aniY = mouseY;
animationStart = true;
- buttonDown = 0;
}
} else {
// No object found, we move the character to the cursor
aniX = mouseX;
aniY = mouseY;
animationStart = true;
- buttonDown = 0;
}
} else {
// handle click in menu
@@ -1590,7 +1587,7 @@ int CruiseEngine::processInput(void) {
}
}
}
- } else if ((button & MB_RIGHT) || (keyboardCode == Common::KEYCODE_F9)) {
+ } else if ((button & CRS_MB_RIGHT) || (keyboardCode == Common::KEYCODE_F9)) {
if (buttonDown == 0) {
keyboardCode = Common::KEYCODE_INVALID;
@@ -1628,29 +1625,28 @@ bool bFastMode = false;
bool manageEvents() {
Common::Event event;
- bool result = false;
Common::EventManager * eventMan = g_system->getEventManager();
- while (eventMan->pollEvent(event) && !result) {
- result = true;
+ while (eventMan->pollEvent(event)) {
+ bool abortFlag = true;
switch (event.type) {
case Common::EVENT_LBUTTONDOWN:
- currentMouseButton |= MB_LEFT;
+ currentMouseButton |= CRS_MB_LEFT;
break;
case Common::EVENT_LBUTTONUP:
- currentMouseButton &= ~MB_LEFT;
+ currentMouseButton &= ~CRS_MB_LEFT;
break;
case Common::EVENT_RBUTTONDOWN:
- currentMouseButton |= MB_RIGHT;
+ currentMouseButton |= CRS_MB_RIGHT;
break;
case Common::EVENT_RBUTTONUP:
- currentMouseButton &= ~MB_RIGHT;
+ currentMouseButton &= ~CRS_MB_RIGHT;
break;
case Common::EVENT_MOUSEMOVE:
currentMouseX = event.mouse.x;
currentMouseY = event.mouse.y;
- result = false;
+ abortFlag = false;
break;
case Common::EVENT_QUIT:
case Common::EVENT_RTL:
@@ -1659,7 +1655,7 @@ bool manageEvents() {
case Common::EVENT_KEYUP:
switch (event.kbd.keycode) {
case Common::KEYCODE_ESCAPE:
- currentMouseButton &= ~MB_MIDDLE;
+ currentMouseButton &= ~CRS_MB_MIDDLE;
break;
default:
break;
@@ -1668,7 +1664,7 @@ bool manageEvents() {
case Common::EVENT_KEYDOWN:
switch (event.kbd.keycode) {
case Common::KEYCODE_ESCAPE:
- currentMouseButton |= MB_MIDDLE;
+ currentMouseButton |= CRS_MB_MIDDLE;
break;
default:
keyboardCode = event.kbd.keycode;
@@ -1689,9 +1685,12 @@ bool manageEvents() {
default:
break;
}
+
+ if (abortFlag)
+ return true;
}
- return result;
+ return false;
}
void getMouseStatus(int16 *pMouseVar, int16 *pMouseX, int16 *pMouseButton, int16 *pMouseY) {
@@ -1798,6 +1797,9 @@ void CruiseEngine::mainLoop(void) {
// User waiting has ended
changeScriptParamInList(-1, -1, &procHead, 9999, 0);
changeScriptParamInList(-1, -1, &relHead, 9999, 0);
+
+ // Disable any mouse click used to end the user wait
+ currentMouseButton = 0;
}
manageScripts(&relHead);
@@ -1899,8 +1901,6 @@ void CruiseEngine::mainLoop(void) {
g_system->updateScreen();
}
- manageEvents();
-
} while (!playerDontAskQuit && quitValue2 && quitValue != 7);
}
diff --git a/engines/cruise/cruise_main.h b/engines/cruise/cruise_main.h
index d2e9350d70..5f4d5c5c13 100644
--- a/engines/cruise/cruise_main.h
+++ b/engines/cruise/cruise_main.h
@@ -56,10 +56,10 @@
namespace Cruise {
enum MouseButton {
- MB_LEFT = 1,
- MB_RIGHT = 2,
- MB_MIDDLE = 4,
- MB_BOTH = MB_LEFT | MB_RIGHT
+ CRS_MB_LEFT = 1,
+ CRS_MB_RIGHT = 2,
+ CRS_MB_MIDDLE = 4,
+ CRS_MB_BOTH = CRS_MB_LEFT | CRS_MB_RIGHT
};
/*#define DUMP_SCRIPT
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
index 3cf3957703..1202d06fbc 100644
--- a/engines/cruise/dataLoader.cpp
+++ b/engines/cruise/dataLoader.cpp
@@ -382,7 +382,7 @@ int loadFNTSub(uint8 *ptr, int destIdx) {
currentPtr = destPtr + 14;
- for (i = 0; i < *(int16 *)(destPtr + 8); i++) {
+ for (i = 0; i < (int16)READ_UINT16(destPtr + 8); i++) {
bigEndianLongToNative((int32 *) currentPtr);
currentPtr += 4;
diff --git a/engines/cruise/linker.cpp b/engines/cruise/linker.cpp
index bb6f682e1e..2d14d46ce3 100644
--- a/engines/cruise/linker.cpp
+++ b/engines/cruise/linker.cpp
@@ -23,6 +23,7 @@
*
*/
+#include "common/endian.h"
#include "cruise/cruise_main.h"
namespace Cruise {
@@ -182,9 +183,7 @@ int updateScriptImport(int ovlIdx) {
uint8 *ptr = ptrData + temp;
*(ptr + 1) = out2;
- *(int16 *)(ptr + 2) = ptrDest2->idx;
-
- bigEndianShortToNative((int16 *)(ptr + 2));
+ WRITE_BE_UINT16(ptr + 2, ptrDest2->idx);
} else {
if (param2 == 20 || param2 == 30 || param2 == 40 || param2 == 50) { // this patch a double push
uint8 *ptr = ptrData + temp;
@@ -192,9 +191,7 @@ int updateScriptImport(int ovlIdx) {
*(ptr + 1) = 0;
*(ptr + 2) = out2; // update the overlay number
- *(int16 *)(ptr + 4) = ptrDest2->idx;
-
- bigEndianShortToNative((int16 *)(ptr + 4));
+ WRITE_BE_UINT16(ptr + 4, ptrDest2->idx);
} else {
int var_4 = ptrDest2->var4;
@@ -213,17 +210,7 @@ int updateScriptImport(int ovlIdx) {
*(ptrData + temp) = param2;
*(ptrData + temp + 1) = out2;
- *(int16 *)(ptrData + temp + 2) = ptrDest2->idx;
-
- bigEndianShortToNative
- (
- (int16
- *)
- (ptrData
- +
- temp
- +
- 2));
+ WRITE_BE_UINT16(ptrData + temp + 2, ptrDest2->idx);
}
}
}
diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp
index 2932e6dc7d..047f00ee90 100644
--- a/engines/cruise/mainDraw.cpp
+++ b/engines/cruise/mainDraw.cpp
@@ -206,10 +206,34 @@ int m_first_Y;
int m_scaleValue;
int m_color;
-int16 DIST_3D[512];
-int16 polyBuffer2[512];
-int16 XMIN_XMAX[404];
-int16 polyBuffer4[512];
+/*
+ FIXME: Whether intentional or not, the game often seems to use negative indexing
+ of one or more of the arrays below and expects(?) to end up in the preceding one.
+ This "worked" on many platforms so far, but on OSX apparently the buffers don't
+ occupy contiguous memory, and this causes severe corruption and subsequent crashes.
+ Since I'm not really familiar with how the strange drawing code is supposed to work,
+ or whether this behaviour is intentional or not, the short-term fix is to allocate a big
+ buffer and setup pointers within it. This fixes the crashes I'm seeing without causing any
+ (visual) side-effects.
+ If anyone wants to look, this is easily reproduced by starting the game and examining the rug.
+ drawPolyMode1() will then (indirectly) negatively index polyBuffer4. Good luck!
+*/
+
+//int16 DIST_3D[512];
+//int16 polyBuffer2[512];
+//int16 XMIN_XMAX[404];
+//int16 polyBuffer4[512];
+
+int16 bigPolyBuf[512 + 512 + 404 + 512]; /* consolidates the 4 separate buffers above */
+
+//set up the replacement index pointers.
+int16 *DIST_3D = &bigPolyBuf[0];
+int16 *polyBuffer2 = &bigPolyBuf[512];
+int16 *XMIN_XMAX = &bigPolyBuf[512 + 512];
+int16 *polyBuffer4 = &bigPolyBuf[512 + 512 + 404];
+
+
+
// this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
void getPolySize(int positionX, int positionY, int scale, int sizeTable[4], unsigned char *dataPtr) {
diff --git a/engines/cruise/mainDraw.h b/engines/cruise/mainDraw.h
index dc988b551d..620ac6e4d7 100644
--- a/engines/cruise/mainDraw.h
+++ b/engines/cruise/mainDraw.h
@@ -29,8 +29,8 @@
namespace Cruise {
extern int currentTransparent;
-extern int16 polyBuffer2[512];
-extern int16 XMIN_XMAX[404];
+extern int16 *polyBuffer2;
+extern int16 *XMIN_XMAX;
extern int m_color;
int upscaleValue(int value, int scale);
diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp
index 54f686f32a..7e454e78f8 100644
--- a/engines/cruise/menu.cpp
+++ b/engines/cruise/menu.cpp
@@ -179,6 +179,7 @@ int processMenu(menuStruct *pMenu) {
flipScreen();
manageEvents();
+ g_system->delayMillis(10);
// readKeyboard();
} while (!si);
diff --git a/engines/cruise/script.cpp b/engines/cruise/script.cpp
index 9f89f04069..761bba3673 100644
--- a/engines/cruise/script.cpp
+++ b/engines/cruise/script.cpp
@@ -23,6 +23,7 @@
*
*/
+#include "cruise/cruise.h"
#include "cruise/cruise_main.h"
#include "common/endian.h"
@@ -632,7 +633,11 @@ int executeScripts(scriptInstanceStruct *ptr) {
#endif
opcodeType = getByteFromScript();
- // printf("opType: %d\n",(opcodeType&0xFB)>>3);
+ debugC(5, kCruiseDebugScript, "Script %s/%d ip=%d opcode=%d",
+ overlayTable[currentScriptPtr->overlayNumber].overlayName,
+ currentScriptPtr->scriptNumber,
+ currentScriptPtr->scriptOffset,
+ (opcodeType & 0xFB) >> 3);
currentScriptOpcodeType = opcodeType & 7;
diff --git a/engines/cruise/sound.cpp b/engines/cruise/sound.cpp
index 92c2ac6256..7ca4246785 100644
--- a/engines/cruise/sound.cpp
+++ b/engines/cruise/sound.cpp
@@ -766,6 +766,10 @@ void PCSoundFxPlayer::doSync(Common::Serializer &s) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
_instrumentsChannelTable[i] = -1;
}
+
+ _numOrders = _sfxData[470];
+ _eventsDelay = (244 - _sfxData[471]) * 100 / 1060;
+ _updateTicksCounter = 0;
}
s.syncAsSint16LE(_songPlayed);
diff --git a/engines/cruise/staticres.cpp b/engines/cruise/staticres.cpp
index d49d12c05b..595ac5a38b 100644
--- a/engines/cruise/staticres.cpp
+++ b/engines/cruise/staticres.cpp
@@ -168,6 +168,59 @@ int16 german_fontCharacterTable[256] = {
-1, -1, -1, -1
};
+int16 spanish_fontCharacterTable[256] = {
+ -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, -1, -1, -1, -1,
+ -1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 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, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92,
+ -1, -1, -1,
+ 0x72, 0x80
+ -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, -1,
+ 0x7f, 0x79, 0x7b, 0x81, 0x82, 0x83,
+ -1, -1,
+ 0x7d,
+ -1, -1, -1, -1,
+ 0x7E,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ 0x6A, 0x69,
+ -1, -1, -1, -1,
+ 0x6B, 0x6C,
+ -1, -1,
+ 0x6D, 0x6E,
+ -1, -1, -1, -1, -1, -1,
+ 0x6F,
+ -1,
+ 0x70,
+ -1, -1,
+ 0x71, 0x72,
+ -1, -1,
+ 0x74, 0x5D,
+ -1,
+ 0x76,
+ -1,
+ 0x5E,
+ -1,
+ 0x75, 0x73, 0x60, 0x5F, 0x61, 0x62, 0x79, 0x78, 0x63, 0x64,
+ -1, -1,
+ 0x7B, 0x7A,
+ 0x65,
+ -1,
+ 0x66,
+ -1, -1,
+ 0x67,
+ -1,
+ 0x68,
+ -1, -1, -1, -1
+};
+
//
// Mouse data
//
diff --git a/engines/cruise/staticres.h b/engines/cruise/staticres.h
index ef9a1b47e9..964bf294dc 100644
--- a/engines/cruise/staticres.h
+++ b/engines/cruise/staticres.h
@@ -41,9 +41,11 @@ extern int actor_invstat[][13];
extern short int english_fontCharacterTable[256];
extern short int german_fontCharacterTable[256];
+extern short int spanish_fontCharacterTable[256];
#define fontCharacterTable (_vm->getLanguage() == Common::DE_DEU ? \
- german_fontCharacterTable : english_fontCharacterTable)
+ german_fontCharacterTable : (_vm->getLanguage() == Common::ES_ESP ? \
+ spanish_fontCharacterTable : english_fontCharacterTable))
// Mouse cursor data
extern const byte mouseCursorNormal[];
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index 4aa8ee0d9e..006f16ab45 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -141,8 +141,9 @@ void DrasculaEngine::converse(int index) {
int game1 = kDialogOptionUnselected,
game2 = kDialogOptionUnselected,
game3 = kDialogOptionUnselected;
- char phrase1[78], phrase2[78], phrase3[78], phrase4[78];
+ char phrase1[128], phrase2[128], phrase3[128], phrase4[128];
char sound1[13], sound2[13], sound3[13], sound4[13];
+ int phrase1_bottom, phrase2_bottom, phrase3_bottom, phrase4_bottom;
int answer1, answer2, answer3;
char buffer[256];
@@ -207,12 +208,12 @@ void DrasculaEngine::converse(int index) {
updateEvents();
- print_abc_opc(phrase1, 2, game1);
- print_abc_opc(phrase2, 10, game2);
- print_abc_opc(phrase3, 18, game3);
- print_abc_opc(phrase4, 26, kDialogOptionUnselected);
+ phrase1_bottom = 8 * print_abc_opc(phrase1, 2, game1);
+ phrase2_bottom = phrase1_bottom + 8 * print_abc_opc(phrase2, phrase1_bottom + 2, game2);
+ phrase3_bottom = phrase2_bottom + 8 * print_abc_opc(phrase3, phrase2_bottom + 2, game3);
+ phrase4_bottom = phrase3_bottom + 8 * print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionUnselected);
- if (mouseY > 0 && mouseY < 9) {
+ if (mouseY > 0 && mouseY < phrase1_bottom) {
if (game1 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game1 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -226,13 +227,13 @@ void DrasculaEngine::converse(int index) {
talk(phrase1, sound1);
response(answer1);
}
- } else if (mouseY > 8 && mouseY < 17) {
+ } else if (mouseY > phrase1_bottom && mouseY < phrase2_bottom) {
if (game2 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game2 != kDialogOptionClicked && _color != kColorLightGreen)
color_abc(kColorLightGreen);
- print_abc_opc(phrase2, 10, kDialogOptionSelected);
+ print_abc_opc(phrase2, phrase1_bottom + 2, kDialogOptionSelected);
if (leftMouseButton == 1) {
delay(100);
@@ -240,13 +241,13 @@ void DrasculaEngine::converse(int index) {
talk(phrase2, sound2);
response(answer2);
}
- } else if (mouseY > 16 && mouseY < 25) {
+ } else if (mouseY > phrase2_bottom && mouseY < phrase3_bottom) {
if (game3 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game3 != kDialogOptionClicked && _color != kColorLightGreen)
color_abc(kColorLightGreen);
- print_abc_opc(phrase3, 18, kDialogOptionSelected);
+ print_abc_opc(phrase3, phrase2_bottom + 2, kDialogOptionSelected);
if (leftMouseButton == 1) {
delay(100);
@@ -254,8 +255,8 @@ void DrasculaEngine::converse(int index) {
talk(phrase3, sound3);
response(answer3);
}
- } else if (mouseY > 24 && mouseY < 33) {
- print_abc_opc(phrase4, 26, kDialogOptionSelected);
+ } else if (mouseY > phrase3_bottom && mouseY < phrase4_bottom) {
+ print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionSelected);
if (leftMouseButton == 1) {
delay(100);
@@ -265,6 +266,7 @@ void DrasculaEngine::converse(int index) {
} else if (_color != kColorLightGreen)
color_abc(kColorLightGreen);
+ _system->delayMillis(10);
updateScreen();
} // while (breakOut == 0)
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index a3c56be1f4..2e3db3478e 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/keyboard.h"
#include "common/file.h"
#include "common/savefile.h"
@@ -92,7 +93,7 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
*textName = 0;
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "drascula");
+ g_eventRec.registerRandomSource(*_rnd, "drascula");
int cd_num = ConfMan.getInt("cdrom");
if (cd_num >= 0)
@@ -181,10 +182,6 @@ Common::Error DrasculaEngine::run() {
for (;;) {
int i;
-
- VGA = (byte *)malloc(320 * 200);
- memset(VGA, 0, 64000);
-
takeObject = 0;
_menuBar = false;
_menuScreen = false;
@@ -295,7 +292,6 @@ void DrasculaEngine::endChapter() {
MusicFadeout();
stopMusic();
freeMemory();
- free(VGA);
}
bool DrasculaEngine::runCurrentChapter() {
@@ -716,7 +712,8 @@ bool DrasculaEngine::verify2() {
Common::KeyCode DrasculaEngine::getScan() {
updateEvents();
- if (_keyBufferHead == _keyBufferTail) return Common::KEYCODE_INVALID;
+ if (_keyBufferHead == _keyBufferTail)
+ return Common::KEYCODE_INVALID;
Common::KeyCode key = _keyBuffer[_keyBufferTail].keycode;
_keyBufferTail = (_keyBufferTail + 1) % KEYBUFSIZE;
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index b06a2c9d4b..85f31ea2d1 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -344,7 +344,6 @@ public:
byte *mouseCursor;
// Graphics buffers/pointers
- byte *VGA;
byte *bgSurface;
byte *backSurface;
byte *drawSurface3;
@@ -353,7 +352,6 @@ public:
byte *extraSurface; // not sure about this one, was "dir_hare_dch"
byte *screenSurface;
byte *frontSurface;
- byte *textSurface;
byte *memPtr;
byte *mSession;
@@ -564,7 +562,7 @@ public:
void playTalkSequence(int sequence);
void doTalkSequenceCommand(TalkSequenceCommand cmd);
void converse(int);
- void print_abc_opc(const char *, int, int);
+ int print_abc_opc(const char *, int, int);
void response(int);
void activatePendulum();
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 76a551c980..74b9e131e3 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -24,6 +24,7 @@
*/
#include "drascula/drascula.h"
+#include "graphics/surface.h"
namespace Drascula {
@@ -47,7 +48,7 @@ void DrasculaEngine::allocMemory() {
assert(tableSurface);
extraSurface = (byte *)malloc(64000);
assert(extraSurface);
- crosshairCursor = (byte *)malloc(40 * 25);
+ crosshairCursor = (byte *)malloc(OBJWIDTH * OBJHEIGHT);
assert(crosshairCursor);
mouseCursor = (byte *)malloc(OBJWIDTH * OBJHEIGHT);
assert(mouseCursor);
@@ -126,16 +127,18 @@ void DrasculaEngine::showFrame(bool firstFrame) {
}
byte *prevFrame = (byte *)malloc(64000);
- memcpy(prevFrame, VGA, 64000);
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
+ memcpy(prevFrame, screenBuffer, 64000);
- decodeRLE(pcxData, VGA);
+ decodeRLE(pcxData, screenBuffer);
free(pcxData);
if (!firstFrame)
- mixVideo(VGA, prevFrame);
+ mixVideo(screenBuffer, prevFrame);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ _system->unlockScreen();
_system->updateScreen();
+
if (firstFrame)
setPalette(cPal);
@@ -192,8 +195,9 @@ void DrasculaEngine::copyRect(int xorg, int yorg, int xdes, int ydes, int width,
}
void DrasculaEngine::updateScreen(int xorg, int yorg, int xdes, int ydes, int width, int height, byte *buffer) {
- copyBackground(xorg, yorg, xdes, ydes, width, height, buffer, VGA);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
+ copyBackground(xorg, yorg, xdes, ydes, width, height, buffer, screenBuffer);
+ _system->unlockScreen();
_system->updateScreen();
}
@@ -235,13 +239,30 @@ void DrasculaEngine::print_abc(const char *said, int screenX, int screenY) {
} // for
}
-void DrasculaEngine::print_abc_opc(const char *said, int screenY, int game) {
+int DrasculaEngine::print_abc_opc(const char *said, int screenY, int game) {
int signY, letterY, letterX = 0;
uint len = strlen(said);
int screenX = 1;
+ int lines = 1;
for (uint h = 0; h < len; h++) {
+ int wordLength;
+
+ // Look ahead to the end of the word.
+ wordLength = 0;
+ int pos = h;
+ while (said[pos] && said[pos] != ' ') {
+ wordLength++;
+ pos++;
+ }
+
+ if (screenX + wordLength * CHAR_WIDTH_OPC > 317) {
+ screenX = 0;
+ screenY += (CHAR_HEIGHT + 2);
+ lines++;
+ }
+
if (game == 1) {
letterY = 6;
signY = 15;
@@ -281,6 +302,8 @@ void DrasculaEngine::print_abc_opc(const char *said, int screenY, int game) {
screenX = screenX + CHAR_WIDTH_OPC;
}
+
+ return lines;
}
bool DrasculaEngine::textFitsCentered(char *text, int x) {
@@ -402,6 +425,7 @@ void DrasculaEngine::screenSaver() {
int x1_, y1_, off1, off2;
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 320; j++) {
x1_ = j + tempRow[i];
@@ -419,10 +443,11 @@ void DrasculaEngine::screenSaver() {
y1_ = checkWrapY(y1_);
off2 = 320 * y1_ + x1_;
- VGA[320 * i + j] = ghost[bgSurface[off2] + (copia[off1] << 8)];
+ screenBuffer[320 * i + j] = ghost[bgSurface[off2] + (copia[off1] << 8)];
}
}
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+
+ _system->unlockScreen();
_system->updateScreen();
_system->delayMillis(20);
@@ -515,11 +540,14 @@ int DrasculaEngine::playFrameSSN() {
decodeRLE(BufferSSN, screenSurface);
free(BufferSSN);
waitFrameSSN();
+
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
if (FrameSSN)
- mixVideo(VGA, screenSurface);
+ mixVideo(screenBuffer, screenSurface);
else
- memcpy(VGA, screenSurface, 64000);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ memcpy(screenBuffer, screenSurface, 64000);
+
+ _system->unlockScreen();
_system->updateScreen();
FrameSSN++;
} else {
@@ -534,11 +562,13 @@ int DrasculaEngine::playFrameSSN() {
decodeOffset(BufferSSN, screenSurface, length);
free(BufferSSN);
waitFrameSSN();
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
if (FrameSSN)
- mixVideo(VGA, screenSurface);
+ mixVideo(screenBuffer, screenSurface);
else
- memcpy(VGA, screenSurface, 64000);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ memcpy(screenBuffer, screenSurface, 64000);
+
+ _system->unlockScreen();
_system->updateScreen();
FrameSSN++;
}
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index 8284112c1e..c9912f25d2 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1866,69 +1866,68 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
void DrasculaEngine::clearRoom() {
- memset(VGA, 0, 64000);
_system->fillScreen(0);
_system->updateScreen();
}
-bool DrasculaEngine::exitRoom(int l) {
- debug(2, "Exiting room from door %d", l);
+bool DrasculaEngine::exitRoom(int doorNumber) {
+ debug(2, "Exiting room from door %d", doorNumber);
int roomNum = 0;
// Player can't exit the inn in chapter 1
- if (currentChapter == 1 && objectNum[l] == 104) {
+ if (currentChapter == 1 && objectNum[doorNumber] == 104) {
return false;
}
- if (currentChapter == 1 && objectNum[l] == 105 && flags[0] == 0) {
+ if (currentChapter == 1 && objectNum[doorNumber] == 105 && flags[0] == 0) {
talk(442);
return false;
}
- updateDoor(l);
- if (isDoor[l] != 0 &&
- ((currentChapter != 3 && currentChapter != 5) || visible[l] == 1)) {
+ updateDoor(doorNumber);
+ if (isDoor[doorNumber] != 0 &&
+ ((currentChapter != 3 && currentChapter != 5) || visible[doorNumber] == 1)) {
hideCursor();
- gotoObject(roomObjX[l], roomObjY[l]);
+ gotoObject(roomObjX[doorNumber], roomObjY[doorNumber]);
if (currentChapter != 2) {
- trackProtagonist = trackObj[l];
+ trackProtagonist = trackObj[doorNumber];
updateRoom();
updateScreen();
}
characterMoved = 0;
- trackProtagonist = trackCharacter_alkeva[l];
- objExit = roomExits[l];
+ trackProtagonist = trackCharacter_alkeva[doorNumber];
+ objExit = roomExits[doorNumber];
doBreak = 1;
previousMusic = roomMusic;
// Object specific actions
- if (currentChapter == 1 && objectNum[l] == 105) {
+ if (currentChapter == 1 && objectNum[doorNumber] == 105) {
animation_2_1();
return true;
} else if (currentChapter == 2) {
- if (objectNum[l] == 136)
+ if (objectNum[doorNumber] == 136)
animation_2_2();
- if (objectNum[l] == 124) {
+ if (objectNum[doorNumber] == 124) {
gotoObject(163, 106);
gotoObject(287, 101);
trackProtagonist = 0;
}
- if (objectNum[l] == 173) {
+ if (objectNum[doorNumber] == 173) {
animation_35_2();
return true;
}
- if (objectNum[l] == 146 && flags[39] == 1) {
+ if (objectNum[doorNumber] == 146 && flags[39] == 1) {
flags[5] = 1;
flags[11] = 1;
}
- if (objectNum[l] == 176 && flags[29] == 1) {
+ if (objectNum[doorNumber] == 176 && flags[29] == 1) {
flags[29] = 0;
removeObject(kItemEarWithEarPlug);
addObject(kItemEarplugs);
}
- } else if (currentChapter == 4 && objectNum[l] == 108) {
+ } else if (currentChapter == 4 && objectNum[doorNumber] == 108) {
gotoObject(171, 78);
}
@@ -1936,7 +1935,7 @@ bool DrasculaEngine::exitRoom(int l) {
hare_se_ve = 1;
clearRoom();
- sscanf(_targetSurface[l], "%d", &roomNum);
+ sscanf(_targetSurface[doorNumber], "%d", &roomNum);
curX = -1;
enterRoom(roomNum);
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index 7c94938c9b..4b649ce8db 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -803,6 +803,7 @@ void DrasculaEngine::talk_sync(const char *said, const char *filename, const cha
p = 0;
+ memset(buf, 0, sizeof(buf));
talkInit(filename);
do {
diff --git a/engines/gob/demos/demoplayer.cpp b/engines/gob/demos/demoplayer.cpp
index 7f65721ce5..13b7aa5327 100644
--- a/engines/gob/demos/demoplayer.cpp
+++ b/engines/gob/demos/demoplayer.cpp
@@ -34,6 +34,7 @@
#include "gob/draw.h"
#include "gob/inter.h"
#include "gob/videoplayer.h"
+#include "gob/sound/sound.h"
namespace Gob {
@@ -186,6 +187,30 @@ void DemoPlayer::playVideo(const char *fileName) {
free(filePtr);
}
+void DemoPlayer::playADL(const char *params) {
+ const char *end;
+
+ end = strchr(params, ' ');
+ if (!end)
+ end = params + strlen(params);
+
+ Common::String fileName(params, end);
+ bool waitEsc = true;
+ int32 repeat = -1;
+
+ if (*end != '\0') {
+ const char *start = end + 1;
+
+ waitEsc = (*start != '0');
+
+ end = strchr(start, ' ');
+ if (end)
+ repeat = atoi(end + 1);
+ }
+
+ playADL(fileName, waitEsc, repeat);
+}
+
void DemoPlayer::playVideoNormal() {
_vm->_vidPlayer->primaryPlay();
}
@@ -233,6 +258,26 @@ void DemoPlayer::playVideoDoubled() {
}
}
+void DemoPlayer::playADL(const Common::String &fileName, bool waitEsc, int32 repeat) {
+ debugC(1, kDebugDemo, "Playing ADL \"%s\" (%d, %d)", fileName.c_str(), waitEsc, repeat);
+
+ _vm->_sound->adlibUnload();
+ _vm->_sound->adlibLoadADL(fileName.c_str());
+ _vm->_sound->adlibSetRepeating(repeat);
+ _vm->_sound->adlibPlay();
+
+ if (!waitEsc)
+ return;
+
+ int16 key = 0;
+ while (!_vm->shouldQuit() && (key != kKeyEscape) && _vm->_sound->adlibIsPlaying()) {
+ _vm->_util->longDelay(1);
+ while (_vm->_util->checkKey(key))
+ if (key == kKeyEscape)
+ break;
+ }
+}
+
void DemoPlayer::evaluateVideoMode(const char *mode) {
debugC(2, kDebugDemo, "Video mode \"%s\"", mode);
diff --git a/engines/gob/demos/demoplayer.h b/engines/gob/demos/demoplayer.h
index 64c98b58c5..f0672b9645 100644
--- a/engines/gob/demos/demoplayer.h
+++ b/engines/gob/demos/demoplayer.h
@@ -57,9 +57,11 @@ protected:
void evaluateVideoMode(const char *mode);
void clearScreen();
void playVideo(const char *fileName);
+ void playADL(const char *params);
void playVideoNormal();
void playVideoDoubled();
+ void playADL(const Common::String &fileName, bool waitEsc = true, int32 repeat = -1);
private:
enum ScriptSource {
diff --git a/engines/gob/demos/scnplayer.cpp b/engines/gob/demos/scnplayer.cpp
index 616da3272a..bf81773a15 100644
--- a/engines/gob/demos/scnplayer.cpp
+++ b/engines/gob/demos/scnplayer.cpp
@@ -66,6 +66,8 @@ bool SCNPlayer::playStream(Common::SeekableReadStream &scn) {
_rebase0 = true;
} else if (lineStartsWith(line, "REBASE0:OFF")) {
_rebase0 = false;
+ } else if (lineStartsWith(line, "ADL ")) {
+ playADL(line.c_str() + 4);
}
// Mind user input
diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp
index 61c17b16f8..6088d622f8 100644
--- a/engines/gob/detection.cpp
+++ b/engines/gob/detection.cpp
@@ -2750,7 +2750,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2764,7 +2764,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2778,7 +2778,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2792,7 +2792,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2806,7 +2806,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2820,7 +2820,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2834,7 +2834,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2848,7 +2848,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2862,7 +2862,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2876,7 +2876,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2890,7 +2890,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2904,7 +2904,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2918,7 +2918,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2932,7 +2932,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2946,7 +2946,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2960,7 +2960,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2974,7 +2974,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2988,7 +2988,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3002,7 +3002,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3016,7 +3016,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3030,7 +3030,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3044,7 +3044,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3058,7 +3058,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3072,7 +3072,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3086,7 +3086,7 @@ static const GOBGameDescription gameDescriptions[] = {
PL_POL,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -4299,7 +4299,7 @@ static const GOBGameDescription fallbackDescs[] = {
GUIO_NONE
},
kGameTypeUrban,
- kFeatures640 | kFeaturesSCNDemo,
+ kFeaturesAdlib | kFeatures640 | kFeaturesSCNDemo,
"", "", 8
}
};
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index fb3cb9bbcd..46f75f67aa 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -303,6 +303,8 @@ void Draw::dirtiedRect(SurfaceDescPtr surface,
invalidateRect(left, top, right, bottom);
else if (surface == _frontSurface)
_vm->_video->dirtyRectsAdd(left, top, right, bottom);
+ else if (_vm->_video->_splitSurf && (surface == _vm->_video->_splitSurf))
+ _vm->_video->retrace();
}
void Draw::initSpriteSurf(int16 index, int16 width, int16 height,
diff --git a/engines/gob/draw.h b/engines/gob/draw.h
index ba32df0c3e..1da6ba4b74 100644
--- a/engines/gob/draw.h
+++ b/engines/gob/draw.h
@@ -39,7 +39,7 @@ namespace Gob {
#define RENDERFLAG_USEDELTAS 0x0010
#define RENDERFLAG_UNKNOWN 0x0080
#define RENDERFLAG_NOBLITINVALIDATED 0x0200
-#define RENDERFLAG_SKIPOPTIONALTEXT 0x0400
+#define RENDERFLAG_NOSUBTITLES 0x0400
#define RENDERFLAG_FROMSPLIT 0x0800
#define RENDERFLAG_DOUBLECOORDS 0x1000
@@ -77,6 +77,9 @@ public:
int16 _backDeltaX;
int16 _backDeltaY;
+ int16 _subtitleFont;
+ int16 _subtitleColor;
+
FontToSprite _fontToSprite[4];
Font *_fonts[kFontCount];
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index e2cfcb613d..719945fd6f 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -318,6 +318,8 @@ void Draw_v1::spriteOperation(int16 operation) {
int16 perLine;
Resource *resource;
+ operation &= 0x0F;
+
if (_sourceSurface >= 100)
_sourceSurface -= 80;
if (_destSurface >= 100)
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 8fe70589a7..a1074d7ecb 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -216,7 +216,9 @@ void Draw_v2::printTotText(int16 id) {
dataPtr = textItem->getData();
ptr = dataPtr;
- if ((_renderFlags & RENDERFLAG_SKIPOPTIONALTEXT) && (ptr[1] & 0x80)) {
+ bool isSubtitle = (ptr[1] & 0x80) != 0;
+
+ if (isSubtitle && !_vm->_global->_doSubtitles) {
delete textItem;
return;
}
@@ -398,10 +400,15 @@ void Draw_v2::printTotText(int16 id) {
} else {
_destSpriteX = offX;
_destSpriteY = offY;
- _fontIndex = fontIndex;
- _frontColor = frontColor;
+ _fontIndex = fontIndex;
+ _frontColor = frontColor;
_textToPrint = str;
+ if (isSubtitle) {
+ _fontIndex = _subtitleFont;
+ _frontColor = _subtitleColor;
+ }
+
if (_needAdjust != 2) {
if ((_destSpriteX >= destX) && (_destSpriteY >= destY) &&
(((_fonts[_fontIndex]->getCharHeight() / 2) + _destSpriteY - 1) <= spriteBottom)) {
@@ -449,6 +456,10 @@ void Draw_v2::printTotText(int16 id) {
ptr++;
offX = destX + (int16)READ_LE_UINT16(ptr);
offY = destY + (int16)READ_LE_UINT16(ptr + 2);
+ if (_renderFlags & RENDERFLAG_DOUBLECOORDS) {
+ offX += (int16)READ_LE_UINT16(ptr);
+ offY += (int16)READ_LE_UINT16(ptr + 2);
+ }
ptr += 4;
break;
@@ -457,11 +468,19 @@ void Draw_v2::printTotText(int16 id) {
fontIndex = ((*ptr & 0xF0) >> 4) & 7;
frontColor = *ptr & 0x0F;
ptr++;
+
+ if (isSubtitle) {
+ _subtitleFont = fontIndex;
+ _subtitleColor = frontColor;
+ }
break;
case 4:
ptr++;
frontColor = *ptr++;
+
+ if (isSubtitle)
+ _subtitleColor = frontColor;
break;
case 6:
@@ -502,8 +521,7 @@ void Draw_v2::printTotText(int16 id) {
case 10:
str[0] = (char) 255;
- WRITE_LE_UINT16((uint16 *) (str + 1),
- ptr - _vm->_game->_resources->getTexts());
+ WRITE_LE_UINT16(str + 1, ptr - _vm->_game->_resources->getTexts());
str[3] = 0;
ptr++;
for (int i = *ptr++; i > 0; i--) {
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index d201019d08..4e2bd223b7 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -275,6 +275,12 @@ void Game::playTot(int16 skipPlay) {
_vm->_draw->_fontToSprite[i].height = -1;
}
+ // Gobliiins music stopping
+ if (_vm->getGameType() == kGameTypeGob1) {
+ _vm->_sound->adlibStop();
+ _vm->_sound->cdStop();
+ }
+
_vm->_mult->initAll();
_vm->_mult->zeroMultData();
diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp
index 2969ed0870..f4f1303386 100644
--- a/engines/gob/global.cpp
+++ b/engines/gob/global.cpp
@@ -124,6 +124,8 @@ Global::Global(GobEngine *vm) : _vm(vm) {
_speedFactor = 1;
+ _doSubtitles = false;
+
_noCd = false;
}
diff --git a/engines/gob/global.h b/engines/gob/global.h
index 7849490107..5830e3e58c 100644
--- a/engines/gob/global.h
+++ b/engines/gob/global.h
@@ -141,6 +141,8 @@ public:
// Can be 1, 2 or 3 for normal, double and triple speed, respectively
uint8 _speedFactor;
+ bool _doSubtitles;
+
bool _noCd;
Global(GobEngine *vm);
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index fa4f04eab8..082345e675 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -25,6 +25,7 @@
#include "common/endian.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "base/plugins.h"
#include "common/config-manager.h"
@@ -129,7 +130,7 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst) {
Common::addDebugChannel(kDebugHotspots, "Hotspots", "Hotspots debug level");
Common::addDebugChannel(kDebugDemo, "Demo", "Demo script debug level");
- syst->getEventManager()->registerRandomSource(_rnd, "gob");
+ g_eventRec.registerRandomSource(_rnd, "gob");
}
GobEngine::~GobEngine() {
@@ -302,7 +303,6 @@ void GobEngine::pauseEngineIntern(bool pause) {
} else {
uint32 duration = _system->getMillis() - _pauseStart;
- _vidPlayer->notifyPaused(duration);
_util->notifyPaused(duration);
_game->_startTimeKey += duration;
@@ -314,6 +314,12 @@ void GobEngine::pauseEngineIntern(bool pause) {
_mixer->pauseAll(pause);
}
+void GobEngine::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _init->updateConfig();
+}
+
void GobEngine::pauseGame() {
pauseEngineIntern(true);
@@ -329,139 +335,138 @@ bool GobEngine::initGameParts() {
_saveLoad = 0;
- _global = new Global(this);
- _util = new Util(this);
- _dataIO = new DataIO(this);
- _palAnim = new PalAnim(this);
+ _global = new Global(this);
+ _util = new Util(this);
+ _dataIO = new DataIO(this);
+ _palAnim = new PalAnim(this);
_vidPlayer = new VideoPlayer(this);
- _sound = new Sound(this);
- _game = new Game(this);
+ _sound = new Sound(this);
+ _game = new Game(this);
switch (_gameType) {
case kGameTypeGeisha:
case kGameTypeAdibouUnknown:
case kGameTypeGob1:
- _init = new Init_v1(this);
- _video = new Video_v1(this);
- _inter = new Inter_v1(this);
- _mult = new Mult_v1(this);
- _draw = new Draw_v1(this);
- _map = new Map_v1(this);
- _goblin = new Goblin_v1(this);
- _scenery = new Scenery_v1(this);
+ _init = new Init_v1(this);
+ _video = new Video_v1(this);
+ _inter = new Inter_v1(this);
+ _mult = new Mult_v1(this);
+ _draw = new Draw_v1(this);
+ _map = new Map_v1(this);
+ _goblin = new Goblin_v1(this);
+ _scenery = new Scenery_v1(this);
break;
case kGameTypeFascination:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
- _inter = new Inter_Fascination(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_Fascination(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
break;
case kGameTypeWeen:
case kGameTypeGob2:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
- _inter = new Inter_v2(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v2(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
break;
case kGameTypeBargon:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
- _inter = new Inter_Bargon(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_Bargon(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_Bargon(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_Bargon(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
break;
case kGameTypeGob3:
case kGameTypeInca2:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v3(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v3(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v3(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v3(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v3(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v3(this, _targetName.c_str(), SaveLoad_v3::kScreenshotTypeGob3);
break;
case kGameTypeLostInTime:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v3(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v3(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v3(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v3(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v3(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v3(this, _targetName.c_str(), SaveLoad_v3::kScreenshotTypeLost);
break;
case kGameTypeWoodruff:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v4(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v4(this);
- _goblin = new Goblin_v4(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v4(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v4(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v4(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v4(this, _targetName.c_str());
break;
case kGameTypeDynasty:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v5(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v4(this);
- _goblin = new Goblin_v4(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v3(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v5(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v4(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad(this);
break;
case kGameTypeAdibou4:
case kGameTypeUrban:
- _init = new Init_v6(this);
- _video = new Video_v6(this);
- _inter = new Inter_v6(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v4(this);
- _goblin = new Goblin_v4(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v6(this);
+ _video = new Video_v6(this);
+ _inter = new Inter_v6(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v4(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v6(this, _targetName.c_str());
break;
case kGameTypePlaytoon:
case kGameTypePlaytnCk:
case kGameTypeBambou:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
-// _inter = new Inter_Playtoons(this);
- _inter = new Inter_v6(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v6(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_Playtoons(this);
break;
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index 02f6af51bf..84ff707877 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -75,8 +75,6 @@ class SaveLoad;
#define GET_VAR_FSTR(var) _vm->_inter->_variables->getAddressVarString(var)
#define GET_VARO_FSTR(off) _vm->_inter->_variables->getAddressOffString(off)
-#define VAR_ADDRESS(var) _vm->_inter->_variables->getAddressVar32(var)
-
#define WRITE_VAR_OFFSET(off, val) WRITE_VARO_UINT32((off), (val))
#define WRITE_VAR(var, val) WRITE_VAR_UINT32((var), (val))
#define VAR_OFFSET(off) READ_VARO_UINT32(off)
@@ -165,6 +163,7 @@ private:
virtual Common::Error run();
virtual bool hasFeature(EngineFeature f) const;
virtual void pauseEngineIntern(bool pause);
+ virtual void syncSoundSettings();
bool initGameParts();
void deinitGameParts();
diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp
index faf85a5b41..834e9b8553 100644
--- a/engines/gob/init.cpp
+++ b/engines/gob/init.cpp
@@ -49,6 +49,9 @@ Init::Init(GobEngine *vm) : _vm(vm) {
_palDesc = 0;
}
+Init::~Init() {
+}
+
void Init::cleanup() {
_vm->_video->freeDriver();
_vm->_global->_primarySurfDesc.reset();
@@ -87,6 +90,7 @@ void Init::initGame() {
char buffer[128];
initVideo();
+ updateConfig();
if (!_vm->isDemo()) {
if (_vm->_dataIO->existData(_vm->_startStk.c_str()))
@@ -206,4 +210,7 @@ void Init::initGame() {
cleanup();
}
+void Init::updateConfig() {
+}
+
} // End of namespace Gob
diff --git a/engines/gob/init.h b/engines/gob/init.h
index 60642d0189..c2784a59ac 100644
--- a/engines/gob/init.h
+++ b/engines/gob/init.h
@@ -32,12 +32,14 @@ namespace Gob {
class Init {
public:
+ Init(GobEngine *vm);
+ virtual ~Init();
+
virtual void initGame();
virtual void initVideo() = 0;
- Init(GobEngine *vm);
- virtual ~Init() {}
+ virtual void updateConfig();
protected:
Video::PalDesc *_palDesc;
@@ -50,34 +52,42 @@ protected:
class Init_v1 : public Init {
public:
- virtual void initVideo();
-
Init_v1(GobEngine *vm);
- virtual ~Init_v1() {}
+ ~Init_v1();
+
+ void initVideo();
};
class Init_v2 : public Init_v1 {
public:
- virtual void initVideo();
-
Init_v2(GobEngine *vm);
- virtual ~Init_v2() {}
+ ~Init_v2();
+
+ void initVideo();
};
class Init_v3 : public Init_v2 {
public:
- virtual void initVideo();
-
Init_v3(GobEngine *vm);
- virtual ~Init_v3() {}
+ ~Init_v3();
+
+ void initVideo();
};
-class Init_v6 : public Init_v3 {
+class Init_v4 : public Init_v3 {
public:
- virtual void initGame();
+ Init_v4(GobEngine *vm);
+ ~Init_v4();
+
+ void updateConfig();
+};
+class Init_v6 : public Init_v3 {
+public:
Init_v6(GobEngine *vm);
- virtual ~Init_v6() {}
+ ~Init_v6();
+
+ void initGame();
};
} // End of namespace Gob
diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp
index e482104ff9..50db774734 100644
--- a/engines/gob/init_v1.cpp
+++ b/engines/gob/init_v1.cpp
@@ -35,6 +35,9 @@ namespace Gob {
Init_v1::Init_v1(GobEngine *vm) : Init(vm) {
}
+Init_v1::~Init_v1() {
+}
+
void Init_v1::initVideo() {
if (_vm->_global->_videoMode)
_vm->validateVideoMode(_vm->_global->_videoMode);
diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp
index 4c65b8102c..f89d5a8cfb 100644
--- a/engines/gob/init_v2.cpp
+++ b/engines/gob/init_v2.cpp
@@ -36,6 +36,9 @@ namespace Gob {
Init_v2::Init_v2(GobEngine *vm) : Init_v1(vm) {
}
+Init_v2::~Init_v2() {
+}
+
void Init_v2::initVideo() {
if (_vm->_global->_videoMode)
_vm->validateVideoMode(_vm->_global->_videoMode);
diff --git a/engines/gob/init_v3.cpp b/engines/gob/init_v3.cpp
index 67304b389a..c96005ed5a 100644
--- a/engines/gob/init_v3.cpp
+++ b/engines/gob/init_v3.cpp
@@ -34,6 +34,9 @@ namespace Gob {
Init_v3::Init_v3(GobEngine *vm) : Init_v2(vm) {
}
+Init_v3::~Init_v3() {
+}
+
void Init_v3::initVideo() {
Init_v2::initVideo();
diff --git a/engines/gob/init_v4.cpp b/engines/gob/init_v4.cpp
new file mode 100644
index 0000000000..3bd50a494d
--- /dev/null
+++ b/engines/gob/init_v4.cpp
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+#include "common/config-manager.h"
+
+#include "gob/gob.h"
+#include "gob/init.h"
+#include "gob/global.h"
+
+namespace Gob {
+
+Init_v4::Init_v4(GobEngine *vm) : Init_v3(vm) {
+}
+
+Init_v4::~Init_v4() {
+}
+
+void Init_v4::updateConfig() {
+ _vm->_global->_doSubtitles = ConfMan.getBool("subtitles");
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/init_v6.cpp b/engines/gob/init_v6.cpp
index 4b14c8a29c..40b4769e78 100644
--- a/engines/gob/init_v6.cpp
+++ b/engines/gob/init_v6.cpp
@@ -34,6 +34,9 @@ namespace Gob {
Init_v6::Init_v6(GobEngine *vm) : Init_v3(vm) {
}
+Init_v6::~Init_v6() {
+}
+
void Init_v6::initGame() {
_vm->_global->_noCd = false;
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 69c392b198..446d86643d 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -972,6 +972,7 @@ bool Inter_v1::o1_loadTot(OpFuncParams &params) {
bool Inter_v1::o1_palLoad(OpFuncParams &params) {
int index1, index2;
+ int16 id;
byte cmd;
Resource *resource;
@@ -1116,7 +1117,8 @@ bool Inter_v1::o1_palLoad(OpFuncParams &params) {
case 61:
index1 = _vm->_game->_script->readByte();
index2 = (_vm->_game->_script->readByte() - index1 + 1) * 3;
- resource = _vm->_game->_resources->getResource(_vm->_game->_script->readInt16());
+ id = _vm->_game->_script->readInt16();
+ resource = _vm->_game->_resources->getResource(id);
if (!resource)
break;
@@ -1124,6 +1126,13 @@ bool Inter_v1::o1_palLoad(OpFuncParams &params) {
resource->getData() + index1 * 3, index2);
delete resource;
+ // WORKAROUND: The Last Dynasty overwrites the 0. palette entry but depends on it staying black.
+ if ((_vm->getGameType() == kGameTypeDynasty) && (index1 == 0)) {
+ _vm->_draw->_vgaPalette[0].red = 0;
+ _vm->_draw->_vgaPalette[0].green = 0;
+ _vm->_draw->_vgaPalette[0].blue = 0;
+ }
+
if (_vm->_draw->_applyPal) {
_vm->_draw->_applyPal = false;
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
@@ -2303,7 +2312,7 @@ void Inter_v1::o1_setItemPos(OpGobParams &params) {
void Inter_v1::o1_loadObjects(OpGobParams &params) {
params.extraData = _vm->_game->_script->readInt16();
- _vm->_goblin->loadObjects((char *) VAR_ADDRESS(params.extraData));
+ _vm->_goblin->loadObjects(_variables->getAddressVarString(params.extraData));
}
void Inter_v1::o1_freeObjects(OpGobParams &params) {
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 20f812bb88..19cac86465 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -25,6 +25,8 @@
#include "common/endian.h"
+#include "gui/message.h"
+
#include "sound/mixer.h"
#include "sound/mods/infogrames.h"
@@ -587,6 +589,11 @@ void Inter_v2::o2_totSub() {
if (!scumm_stricmp(totFile, "edit"))
_vm->_util->forceMouseUp();
+ // WORKAROUND: For some reason, the variable indicating which TOT to load next
+ // is overwritten in the guard house card game in Woodruff
+ if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(totFile, "6"))
+ strcpy(totFile, "EMAP2011");
+
flags = _vm->_game->_script->readByte();
_vm->_game->totSub(flags, totFile);
}
@@ -1297,16 +1304,23 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
size = -1;
handle = 1;
- mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr());
+ char *file = _vm->_game->_script->getResultStr();
+
+ // WORKAROUND: For some reason, the variable indicating which TOT to load next
+ // is overwritten in the guard house card game in Woodruff
+ if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(file, "6.TOT"))
+ strcpy(file, "EMAP2011.TOT");
+
+ mode = _vm->_saveLoad->getSaveMode(file);
if (mode == SaveLoad::kSaveModeNone) {
- if (_vm->_dataIO->existData(_vm->_game->_script->getResultStr()))
- size = _vm->_dataIO->getDataSize(_vm->_game->_script->getResultStr());
+ if (_vm->_dataIO->existData(file))
+ size = _vm->_dataIO->getDataSize(file);
else
- warning("File \"%s\" not found", _vm->_game->_script->getResultStr());
+ warning("File \"%s\" not found", file);
} else if (mode == SaveLoad::kSaveModeSave)
- size = _vm->_saveLoad->getSize(_vm->_game->_script->getResultStr());
+ size = _vm->_saveLoad->getSize(file);
else if (mode == SaveLoad::kSaveModeExists)
size = 23;
@@ -1314,7 +1328,7 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
handle = -1;
debugC(2, kDebugFileIO, "Requested size of file \"%s\": %d",
- _vm->_game->_script->getResultStr(), size);
+ file, size);
WRITE_VAR_OFFSET(varOff, handle);
WRITE_VAR(16, (uint32) size);
@@ -1338,21 +1352,32 @@ bool Inter_v2::o2_readData(OpFuncParams &params) {
offset = _vm->_game->_script->getResultInt();
retSize = 0;
+ char *file = _vm->_game->_script->getResultStr();
+
debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)",
- _vm->_game->_script->getResultStr(), dataVar, size, offset);
+ file, dataVar, size, offset);
- mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr());
+ mode = _vm->_saveLoad->getSaveMode(file);
if (mode == SaveLoad::kSaveModeSave) {
+
WRITE_VAR(1, 1);
- if (_vm->_saveLoad->load(_vm->_game->_script->getResultStr(), dataVar, size, offset))
+
+ if (!_vm->_saveLoad->load(file, dataVar, size, offset)) {
+
+ GUI::MessageDialog dialog("Failed to load game state from file.");
+ dialog.runModal();
+
+ } else
WRITE_VAR(1, 0);
+
return false;
+
} else if (mode == SaveLoad::kSaveModeIgnore)
return false;
if (size < 0) {
warning("Attempted to read a raw sprite from file \"%s\"",
- _vm->_game->_script->getResultStr());
+ file);
return false ;
} else if (size == 0) {
dataVar = 0;
@@ -1361,13 +1386,13 @@ bool Inter_v2::o2_readData(OpFuncParams &params) {
buf = _variables->getAddressOff8(dataVar);
- if (_vm->_game->_script->getResultStr()[0] == 0) {
+ if (file[0] == 0) {
WRITE_VAR(1, size);
return false;
}
WRITE_VAR(1, 1);
- handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr());
+ handle = _vm->_dataIO->openData(file);
if (handle < 0)
return false;
@@ -1408,17 +1433,26 @@ bool Inter_v2::o2_writeData(OpFuncParams &params) {
_vm->_game->_script->evalExpr(0);
offset = _vm->_game->_script->getResultInt();
+ char *file = _vm->_game->_script->getResultStr();
+
debugC(2, kDebugFileIO, "Write to file \"%s\" (%d, %d bytes at %d)",
- _vm->_game->_script->getResultStr(), dataVar, size, offset);
+ file, dataVar, size, offset);
WRITE_VAR(1, 1);
- mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr());
+ mode = _vm->_saveLoad->getSaveMode(file);
if (mode == SaveLoad::kSaveModeSave) {
- if (_vm->_saveLoad->save(_vm->_game->_script->getResultStr(), dataVar, size, offset))
+
+ if (!_vm->_saveLoad->save(file, dataVar, size, offset)) {
+
+ GUI::MessageDialog dialog("Failed to save game state to file.");
+ dialog.runModal();
+
+ } else
WRITE_VAR(1, 0);
+
} else if (mode == SaveLoad::kSaveModeNone)
- warning("Attempted to write to file \"%s\"", _vm->_game->_script->getResultStr());
+ warning("Attempted to write to file \"%s\"", file);
return false;
}
diff --git a/engines/gob/map.h b/engines/gob/map.h
index 4a211f205d..ba976ff7ac 100644
--- a/engines/gob/map.h
+++ b/engines/gob/map.h
@@ -204,14 +204,6 @@ protected:
void loadGoblinStates(Common::SeekableReadStream &data, int index);
};
-class Map_v4 : public Map_v2 {
-public:
- virtual void loadMapObjects(const char *avjFile);
-
- Map_v4(GobEngine *vm);
- virtual ~Map_v4();
-};
-
} // End of namespace Gob
#endif // GOB_MAP_H
diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp
index 6ceda7ab44..51caad74b8 100644
--- a/engines/gob/map_v2.cpp
+++ b/engines/gob/map_v2.cpp
@@ -60,7 +60,10 @@ void Map_v2::loadMapObjects(const char *avjFile) {
id = _vm->_game->_script->readInt16();
- if (id == -1) {
+ if (((uint16) id) >= 65520) {
+ warning("Map_v2::loadMapObjects(): ID >= 65520");
+ return;
+ } else if (id == -1) {
_passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var);
return;
}
@@ -71,13 +74,20 @@ void Map_v2::loadMapObjects(const char *avjFile) {
Common::SeekableReadStream &mapData = *resource->stream();
- if (mapData.readByte() == 3) {
+ _widthByte = mapData.readByte();
+ if (_widthByte == 4) {
_screenWidth = 640;
+ _screenHeight = 400;
+ } else if (_widthByte == 3) {
_passWidth = 65;
+ _screenWidth = 640;
+ _screenHeight = 200;
} else {
- _screenWidth = 320;
_passWidth = 40;
+ _screenWidth = 320;
+ _screenHeight = 200;
}
+
_wayPointsCount = mapData.readByte();
_tilesWidth = mapData.readSint16LE();
_tilesHeight = mapData.readSint16LE();
@@ -85,6 +95,11 @@ void Map_v2::loadMapObjects(const char *avjFile) {
_bigTiles = !(_tilesHeight & 0xFF00);
_tilesHeight &= 0xFF;
+ if (_widthByte == 4) {
+ _screenWidth = mapData.readSint16LE();
+ _screenHeight = mapData.readSint16LE();
+ }
+
_mapWidth = _screenWidth / _tilesWidth;
_mapHeight = _screenHeight / _tilesHeight;
@@ -104,6 +119,11 @@ void Map_v2::loadMapObjects(const char *avjFile) {
_wayPoints[i].notWalkable = mapData.readSByte();
}
+ if (_widthByte == 4) {
+ _mapWidth = VAR(17);
+ _passWidth = _mapWidth;
+ }
+
// In the original asm, this writes byte-wise into the variables-array
tmpPos = mapData.pos();
mapData.seek(passPos);
diff --git a/engines/gob/map_v4.cpp b/engines/gob/map_v4.cpp
deleted file mode 100644
index 1db3d6a3f8..0000000000
--- a/engines/gob/map_v4.cpp
+++ /dev/null
@@ -1,159 +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.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stream.h"
-
-#include "gob/gob.h"
-#include "gob/map.h"
-#include "gob/global.h"
-#include "gob/goblin.h"
-#include "gob/inter.h"
-#include "gob/game.h"
-#include "gob/script.h"
-#include "gob/resources.h"
-#include "gob/mult.h"
-
-namespace Gob {
-
-Map_v4::Map_v4(GobEngine *vm) : Map_v2(vm) {
-}
-
-Map_v4::~Map_v4() {
-}
-
-void Map_v4::loadMapObjects(const char *avjFile) {
- uint8 wayPointsCount;
- int16 var;
- int16 id;
- int16 mapWidth, mapHeight;
- int16 tmp;
- byte *variables;
- uint32 tmpPos;
- uint32 passPos;
-
- var = _vm->_game->_script->readVarIndex();
- variables = _vm->_inter->_variables->getAddressOff8(var);
-
- id = _vm->_game->_script->readInt16();
-
- if (((uint16) id) >= 65520) {
- warning("Woodruff Stub: loadMapObjects ID >= 65520");
- return;
- } else if (id == -1) {
- _passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var);
- return;
- }
-
- Resource *resource = _vm->_game->_resources->getResource(id);
- if (!resource)
- return;
-
- Common::SeekableReadStream &mapData = *resource->stream();
-
- _widthByte = mapData.readByte();
- if (_widthByte == 4) {
- _screenWidth = 640;
- _screenHeight = 400;
- } else if (_widthByte == 3) {
- _screenWidth = 640;
- _screenHeight = 200;
- } else {
- _screenWidth = 320;
- _screenHeight = 200;
- }
-
- _wayPointsCount = mapData.readByte();
- _tilesWidth = mapData.readSint16LE();
- _tilesHeight = mapData.readSint16LE();
-
- _bigTiles = !(_tilesHeight & 0xFF00);
- _tilesHeight &= 0xFF;
-
- if (_widthByte == 4) {
- _screenWidth = mapData.readSint16LE();
- _screenHeight = mapData.readSint16LE();
- }
-
- _mapWidth = _screenWidth / _tilesWidth;
- _mapHeight = _screenHeight / _tilesHeight;
-
- passPos = mapData.pos();
- mapData.skip(_mapWidth * _mapHeight);
-
- if (resource->getData()[0] == 1)
- wayPointsCount = _wayPointsCount = 40;
- else
- wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount;
-
- delete[] _wayPoints;
- _wayPoints = new Point[wayPointsCount];
- for (int i = 0; i < _wayPointsCount; i++) {
- _wayPoints[i].x = mapData.readSByte();
- _wayPoints[i].y = mapData.readSByte();
- _wayPoints[i].notWalkable = mapData.readSByte();
- }
-
- if (_widthByte == 4)
- _mapWidth = VAR(17);
-
- _passWidth = _mapWidth;
-
- // In the original asm, this writes byte-wise into the variables-array
- tmpPos = mapData.pos();
- mapData.seek(passPos);
- if ((variables != 0) &&
- (variables != _vm->_inter->_variables->getAddressOff8(0))) {
-
- _passMap = (int8 *) variables;
- mapHeight = _screenHeight / _tilesHeight;
- mapWidth = _screenWidth / _tilesWidth;
-
- for (int i = 0; i < mapHeight; i++) {
- for (int j = 0; j < mapWidth; j++)
- setPass(j, i, mapData.readSByte());
- _vm->_inter->_variables->getAddressOff8(var + i * _passWidth);
- }
- }
- mapData.seek(tmpPos);
-
- tmp = mapData.readSint16LE();
- mapData.skip(tmp * 14);
- tmp = mapData.readSint16LE();
- mapData.skip(tmp * 14 + 28);
- tmp = mapData.readSint16LE();
- mapData.skip(tmp * 14);
-
- _vm->_goblin->_gobsCount = tmp;
- for (int i = 0; i < _vm->_goblin->_gobsCount; i++)
- loadGoblinStates(mapData, i);
-
- _vm->_goblin->_soundSlotsCount = _vm->_game->_script->readInt16();
- for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
- _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
-
- delete resource;
-}
-
-} // End of namespace Gob
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 611abb6038..26cc4e5d27 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -23,6 +23,7 @@ MODULE_OBJS := \
init_v1.o \
init_v2.o \
init_v3.o \
+ init_v4.o \
init_v6.o \
inter.o \
inter_v1.o \
@@ -36,7 +37,6 @@ MODULE_OBJS := \
map.o \
map_v1.o \
map_v2.o \
- map_v4.o \
mult.o \
mult_v1.o \
mult_v2.o \
diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp
index c52b65f0d7..2f3b1b23e7 100644
--- a/engines/gob/resources.cpp
+++ b/engines/gob/resources.cpp
@@ -144,8 +144,6 @@ Resources::~Resources() {
bool Resources::load(const Common::String &fileName) {
unload();
- Common::String fileBase;
-
_totFile = TOTFile::createFileName(fileName, _hasLOM);
if (_hasLOM) {
@@ -154,9 +152,9 @@ bool Resources::load(const Common::String &fileName) {
return false;
}
- fileBase = TOTFile::getFileBase(fileName);
+ _fileBase = TOTFile::getFileBase(fileName);
- _extFile = fileBase + ".ext";
+ _extFile = _fileBase + ".ext";
bool hasTOTRes = loadTOTResourceTable();
bool hasEXTRes = loadEXTResourceTable();
@@ -165,7 +163,7 @@ bool Resources::load(const Common::String &fileName) {
return false;
if (hasTOTRes) {
- if (!loadTOTTextTable(fileBase)) {
+ if (!loadTOTTextTable(_fileBase)) {
unload();
return false;
}
@@ -195,6 +193,7 @@ void Resources::unload(bool del) {
delete[] _totData;
delete[] _imData;
+ _fileBase.clear();
_totFile.clear();
_extFile.clear();
_exFile.clear();
@@ -573,6 +572,41 @@ byte *Resources::getTexts() const {
return _totTextTable->data;
}
+bool Resources::dumpResource(const Resource &resource,
+ const Common::String &fileName) const {
+
+ Common::DumpFile dump;
+
+ if (!dump.open(fileName))
+ return false;
+
+ if (dump.write(resource.getData(), resource.getSize()) != ((uint32) resource.getSize()))
+ return false;
+
+ if (!dump.flush())
+ return false;
+ if (dump.err())
+ return false;
+
+ dump.close();
+ return true;
+}
+
+bool Resources::dumpResource(const Resource &resource, uint16 id,
+ const Common::String &ext) const {
+
+ Common::String fileName = _fileBase;
+
+ char idStr[7];
+
+ snprintf(idStr, 7, "_%05d", id);
+ fileName += idStr;
+ fileName += ".";
+ fileName += ext;
+
+ return dumpResource(resource, fileName);
+}
+
Resource *Resources::getTOTResource(uint16 id) const {
if (id >= _totResourceTable->itemsCount) {
warning("Trying to load non-existent TOT resource (%s, %d/%d)",
diff --git a/engines/gob/resources.h b/engines/gob/resources.h
index d316be83e5..7511185954 100644
--- a/engines/gob/resources.h
+++ b/engines/gob/resources.h
@@ -91,6 +91,11 @@ public:
byte *getTexts() const;
+ bool dumpResource(const Resource &resource,
+ const Common::String &fileName) const;
+ bool dumpResource(const Resource &resource, uint16 id,
+ const Common::String &ext = "dmp") const;
+
private:
// Structure sizes in the files
static const int kTOTResItemSize = 4 + 2 + 2 + 2;
@@ -166,6 +171,7 @@ private:
GobEngine *_vm;
+ Common::String _fileBase;
Common::String _totFile;
Common::String _extFile;
Common::String _exFile;
diff --git a/engines/gob/save/saveconverter.cpp b/engines/gob/save/saveconverter.cpp
index 38fec06859..7bfb2a2da2 100644
--- a/engines/gob/save/saveconverter.cpp
+++ b/engines/gob/save/saveconverter.cpp
@@ -122,14 +122,14 @@ bool SaveConverter::swapDataEndian(byte *data, const byte *sizes, uint32 count)
while (count-- > 0) {
if (*sizes == 3) // 32bit value (3 additional bytes)
- *((uint32 *) data) = SWAP_BYTES_32(*((uint32 *) data));
+ WRITE_UINT32(data, SWAP_BYTES_32(READ_UINT32(data)));
else if (*sizes == 1) // 16bit value (1 additional byte)
- *((uint16 *) data) = SWAP_BYTES_16(*((uint16 *) data));
+ WRITE_UINT16(data, SWAP_BYTES_16(READ_UINT16(data)));
else if (*sizes != 0) // else, it has to be an 8bit value
return false;
count -= *sizes;
- data += *sizes + 1;
+ data += *sizes + 1;
sizes += *sizes + 1;
}
diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index 8d785c7233..1a1a47178b 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -74,15 +74,15 @@ protected:
/** Save/Load class for Gobliins 2, Ween: The Prophecy and Bargon Attack. */
class SaveLoad_v2 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 15;
+ static const uint32 kSlotNameLength = 40;
+
SaveLoad_v2(GobEngine *vm, const char *targetName);
virtual ~SaveLoad_v2();
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 15;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
@@ -136,6 +136,9 @@ protected:
/** Save/Load class for Goblins 3 and Lost in Time. */
class SaveLoad_v3 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 30;
+ static const uint32 kSlotNameLength = 40;
+
enum ScreenshotType {
kScreenshotTypeGob3, //!< Goblins 3 type screenshot
kScreenshotTypeLost //!< Lost in Time type screenshot
@@ -147,9 +150,6 @@ public:
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 30;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
@@ -264,15 +264,15 @@ protected:
/** Save/Load class for Woodruff. */
class SaveLoad_v4 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 10;
+ static const uint32 kSlotNameLength = 40;
+
SaveLoad_v4(GobEngine *vm, const char *targetName);
virtual ~SaveLoad_v4();
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 10;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
@@ -289,6 +289,8 @@ protected:
GameHandler(GobEngine *vm, const char *target);
~GameHandler();
+ int getLastSlot() const;
+
int32 getSize();
bool load(int16 dataVar, int32 size, int32 offset);
bool save(int16 dataVar, int32 size, int32 offset);
@@ -317,6 +319,8 @@ protected:
File *_slotFile;
+ int _lastSlot;
+
SaveReader *_reader;
SaveWriter *_writer;
@@ -386,15 +390,15 @@ protected:
/** Save/Load class for Urban Runner. */
class SaveLoad_v6 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 60;
+ static const uint32 kSlotNameLength = 40;
+
SaveLoad_v6(GobEngine *vm, const char *targetName);
virtual ~SaveLoad_v6();
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 60;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
diff --git a/engines/gob/save/saveload_v4.cpp b/engines/gob/save/saveload_v4.cpp
index 06280af2a6..16c87b9a64 100644
--- a/engines/gob/save/saveload_v4.cpp
+++ b/engines/gob/save/saveload_v4.cpp
@@ -84,6 +84,8 @@ SaveLoad_v4::GameHandler::GameHandler(GobEngine *vm, const char *target) : SaveH
_slotFile = new File(vm, target);
+ _lastSlot = -1;
+
_writer = 0;
_reader = 0;
}
@@ -94,6 +96,10 @@ SaveLoad_v4::GameHandler::~GameHandler() {
delete _writer;
}
+int SaveLoad_v4::GameHandler::getLastSlot() const {
+ return _lastSlot;
+}
+
int32 SaveLoad_v4::GameHandler::getSize() {
// Fake an empty save file for the very first query, to get clear properties
if (_firstSize) {
@@ -178,6 +184,7 @@ bool SaveLoad_v4::GameHandler::load(int16 dataVar, int32 size, int32 offset) {
if (!vars.writeInto(0, 0, varSize))
return false;
+ _lastSlot = slot;
}
return true;
@@ -261,6 +268,7 @@ bool SaveLoad_v4::GameHandler::save(int16 dataVar, int32 size, int32 offset) {
if (!_writer->writePart(1, &vars))
return false;
+ _lastSlot = slot;
}
return true;
@@ -465,7 +473,11 @@ bool SaveLoad_v4::ScreenPropsHandler::load(int16 dataVar, int32 size, int32 offs
return false;
}
- return _gameHandler->loadScreenProps(_file->getSlot(offset), _curProps->_props);
+ int slot = _gameHandler->getLastSlot();
+ if (slot == -1)
+ slot = _file->getSlot(offset);
+
+ return _gameHandler->loadScreenProps(slot, _curProps->_props);
}
bool SaveLoad_v4::ScreenPropsHandler::save(int16 dataVar, int32 size, int32 offset) {
@@ -474,7 +486,11 @@ bool SaveLoad_v4::ScreenPropsHandler::save(int16 dataVar, int32 size, int32 offs
return false;
}
- return _gameHandler->saveScreenProps(_file->getSlot(offset), _curProps->_props);
+ int slot = _gameHandler->getLastSlot();
+ if (slot == -1)
+ slot = _file->getSlot(offset);
+
+ return _gameHandler->saveScreenProps(slot, _curProps->_props);
}
diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp
index 7a4b8ad868..a6d6c06544 100644
--- a/engines/gob/scenery.cpp
+++ b/engines/gob/scenery.cpp
@@ -95,7 +95,7 @@ void Scenery::init() {
int16 Scenery::loadStatic(char search) {
int16 size;
- int16 *backsPtr;
+ byte *backsPtr;
int16 picsCount;
int16 resId;
int16 sceneryIndex;
@@ -108,7 +108,7 @@ int16 Scenery::loadStatic(char search) {
_vm->_game->_script->evalExpr(&sceneryIndex);
size = _vm->_game->_script->readInt16();
- backsPtr = (int16 *) (_vm->_game->_script->getData() + _vm->_game->_script->pos());
+ backsPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos();
_vm->_game->_script->skip(size * 2);
picsCount = _vm->_game->_script->readInt16();
resId = _vm->_game->_script->readInt16();
@@ -162,7 +162,7 @@ int16 Scenery::loadStatic(char search) {
ptr->layers[i].planes = 0;
ptr->layers[i].backResId = (int16) READ_LE_UINT16(backsPtr);
- backsPtr++;
+ backsPtr += 2;
}
ptr->pieces = new PieceDesc*[picsCount];
@@ -185,7 +185,7 @@ int16 Scenery::loadStatic(char search) {
_staticPictToSprite[7 * sceneryIndex + i] = sprIndex;
_spriteRefs[sprIndex]++;
} else {
- for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; sprIndex--);
+ for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; sprIndex--) { }
_staticPictToSprite[7 * sceneryIndex + i] = sprIndex;
_spriteRefs[sprIndex] = 1;
@@ -632,6 +632,11 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
_vm->_vidPlayer->slotPlay(obj.videoSlot - 1);
}
+ // Subtitle
+ Graphics::CoktelVideo::State state = _vm->_vidPlayer->getState(obj.videoSlot - 1);
+ if (state.flags & Graphics::CoktelVideo::kStateSpeech)
+ _vm->_draw->printTotText(state.speechId);
+
destX = 0;
destY = 0;
left = *(obj.pPosX);
diff --git a/engines/gob/script.cpp b/engines/gob/script.cpp
index 38b1f8fa40..0475bb06f7 100644
--- a/engines/gob/script.cpp
+++ b/engines/gob/script.cpp
@@ -201,7 +201,7 @@ int32 Script::readInt32() {
char *Script::readString(int32 length) {
if (length < 0) {
length = 0;
- while (_totPtr[length++] != '\0');
+ while (_totPtr[length++] != '\0') { }
}
char *string = (char *) _totPtr;
diff --git a/engines/gob/sound/bgatmosphere.cpp b/engines/gob/sound/bgatmosphere.cpp
index 6ce184155e..f0977aa45b 100644
--- a/engines/gob/sound/bgatmosphere.cpp
+++ b/engines/gob/sound/bgatmosphere.cpp
@@ -25,6 +25,7 @@
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "gob/sound/bgatmosphere.h"
#include "gob/sound/sounddesc.h"
@@ -39,7 +40,7 @@ BackgroundAtmosphere::BackgroundAtmosphere(Audio::Mixer &mixer) :
_shaded = false;
_shadable = true;
- g_system->getEventManager()->registerRandomSource(_rnd, "gobBA");
+ g_eventRec.registerRandomSource(_rnd, "gobBA");
}
BackgroundAtmosphere::~BackgroundAtmosphere() {
diff --git a/engines/gob/sound/sounddesc.cpp b/engines/gob/sound/sounddesc.cpp
index b9b327d105..e8045d21f7 100644
--- a/engines/gob/sound/sounddesc.cpp
+++ b/engines/gob/sound/sounddesc.cpp
@@ -121,9 +121,9 @@ void SoundDesc::convToSigned() {
return;
if (_mixerFlags & Audio::Mixer::FLAG_16BITS) {
- uint16 *data = (uint16 *) _dataPtr;
- for (uint32 i = 0; i < _size; i++)
- data[i] ^= 0x8000;
+ byte *data = _dataPtr;
+ for (uint32 i = 0; i < _size; i++, data += 2)
+ WRITE_LE_UINT16(data, READ_LE_UINT16(data) ^ 0x8000);
} else
for (uint32 i = 0; i < _size; i++)
_dataPtr[i] ^= 0x80;
diff --git a/engines/gob/sound/soundmixer.cpp b/engines/gob/sound/soundmixer.cpp
index 68a96d3b01..eb6d7882f0 100644
--- a/engines/gob/sound/soundmixer.cpp
+++ b/engines/gob/sound/soundmixer.cpp
@@ -33,8 +33,7 @@ SoundMixer::SoundMixer(Audio::Mixer &mixer, Audio::Mixer::SoundType type) : _mix
_rate = _mixer->getOutputRate();
_end = true;
- _data8 = 0;
- _data16 = 0;
+ _data = 0;
_length = 0;
_freq = 0;
_repCount = 0;
@@ -61,9 +60,9 @@ SoundMixer::~SoundMixer() {
inline int16 SoundMixer::getData(int offset) {
if (!_16bit)
- return (int16) _data8[offset];
+ return (int16) ((int8) _data[offset]);
else
- return (int16) FROM_LE_16(_data16[offset]);
+ return (int16) READ_LE_UINT16(_data + (offset * 2));
}
bool SoundMixer::isPlaying() const {
@@ -78,8 +77,7 @@ void SoundMixer::stop(int16 fadeLength) {
Common::StackLock slock(_mutex);
if (fadeLength <= 0) {
- _data8 = 0;
- _data16 = 0;
+ _data = 0;
_end = true;
_playingSound = 0;
return;
@@ -109,13 +107,7 @@ void SoundMixer::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency,
_16bit = (sndDesc._mixerFlags & Audio::Mixer::FLAG_16BITS) != 0;
- if (_16bit) {
- _data16 = (int16 *) sndDesc.getData();
- _shift = 0;
- } else {
- _data8 = (int8 *) sndDesc.getData();
- _shift = 8;
- }
+ _data = sndDesc.getData();
_length = sndDesc.size();
_freq = frequency;
@@ -171,7 +163,7 @@ int SoundMixer::readBuffer(int16 *buffer, const int numSamples) {
Common::StackLock slock(_mutex);
for (int i = 0; i < numSamples; i++) {
- if (!_data8 && !_data16)
+ if (!_data)
return i;
if (_end || (_offset >= _length))
checkEndSample();
@@ -181,7 +173,7 @@ int SoundMixer::readBuffer(int16 *buffer, const int numSamples) {
// Linear interpolation. See sound/rate.cpp
int16 val = (_last + (((_cur - _last) * _offsetFrac +
- FRAC_HALF) >> FRAC_BITS)) << _shift;
+ FRAC_HALF) >> FRAC_BITS)) << (_16bit ? 0 : 8);
*buffer++ = (val * _fadeVol) >> 16;
_offsetFrac += _offsetInc;
@@ -211,8 +203,7 @@ int SoundMixer::readBuffer(int16 *buffer, const int numSamples) {
void SoundMixer::endFade() {
if (_fadeVolStep > 0) {
- _data8 = 0;
- _data16 = 0;
+ _data = 0;
_end = true;
_playingSound = 0;
} else {
diff --git a/engines/gob/sound/soundmixer.h b/engines/gob/sound/soundmixer.h
index 20376b5152..9e66c474e9 100644
--- a/engines/gob/sound/soundmixer.h
+++ b/engines/gob/sound/soundmixer.h
@@ -62,11 +62,9 @@ protected:
Common::Mutex _mutex;
bool _16bit;
- int _shift;
bool _end;
- int8 *_data8;
- int16 *_data16;
+ byte *_data;
uint32 _length;
uint32 _rate;
int32 _freq;
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 356eb3c643..1a8668b1c2 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -45,7 +45,6 @@ Util::Util(GobEngine *vm) : _vm(vm) {
_frameRate = 12;
_frameWaitTime = 0;
_startFrameTime = 0;
- _frameWaitLag = 0;
}
uint32 Util::getTimeKey(void) {
@@ -331,12 +330,10 @@ void Util::setFrameRate(int16 rate) {
_frameRate = rate;
_frameWaitTime = 1000 / rate;
_startFrameTime = getTimeKey();
- _frameWaitLag = 0;
}
void Util::notifyNewAnim() {
_startFrameTime = getTimeKey();
- _frameWaitLag = 0;
}
void Util::waitEndFrame() {
@@ -350,17 +347,12 @@ void Util::waitEndFrame() {
return;
}
- int32 waitTime = _frameWaitTime - _frameWaitLag;
- int32 toWait = waitTime - time;
+ int32 toWait = _frameWaitTime - time;
if (toWait > 0)
delay(toWait);
- int32 now = getTimeKey();
-
- _frameWaitLag = (now - _startFrameTime) - waitTime;
-
- _startFrameTime = now;
+ _startFrameTime = getTimeKey();
}
void Util::setScrollOffset(int16 x, int16 y) {
diff --git a/engines/gob/util.h b/engines/gob/util.h
index 82e2df94de..ef972eb68c 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -145,7 +145,6 @@ protected:
int16 _frameRate;
int16 _frameWaitTime;
uint32 _startFrameTime;
- int32 _frameWaitLag;
GobEngine *_vm;
diff --git a/engines/gob/variables.cpp b/engines/gob/variables.cpp
index 1183ec21ae..572cba0796 100644
--- a/engines/gob/variables.cpp
+++ b/engines/gob/variables.cpp
@@ -123,22 +123,6 @@ uint8 *Variables::getAddressVar8(uint32 var) {
return getAddressOff8(var * 4);
}
-const uint16 *Variables::getAddressVar16(uint32 var) const {
- return getAddressOff16(var * 4);
-}
-
-uint16 *Variables::getAddressVar16(uint32 var) {
- return getAddressOff16(var * 4);
-}
-
-const uint32 *Variables::getAddressVar32(uint32 var) const {
- return getAddressOff32(var * 4);
-}
-
-uint32 *Variables::getAddressVar32(uint32 var) {
- return getAddressOff32(var * 4);
-}
-
const char *Variables::getAddressVarString(uint32 var) const {
return getAddressOffString(var * 4);
}
@@ -155,22 +139,6 @@ uint8 *Variables::getAddressOff8(uint32 offset) {
return ((uint8 *) (_vars + offset));
}
-const uint16 *Variables::getAddressOff16(uint32 offset) const {
- return ((const uint16 *) (_vars + offset));
-}
-
-uint16 *Variables::getAddressOff16(uint32 offset) {
- return ((uint16 *) (_vars + offset));
-}
-
-const uint32 *Variables::getAddressOff32(uint32 offset) const {
- return ((const uint32 *) (_vars + offset));
-}
-
-uint32 *Variables::getAddressOff32(uint32 offset) {
- return ((uint32 *) (_vars + offset));
-}
-
const char *Variables::getAddressOffString(uint32 offset) const {
return ((const char *) (_vars + offset));
}
diff --git a/engines/gob/variables.h b/engines/gob/variables.h
index 84a4772baa..d11b91ea16 100644
--- a/engines/gob/variables.h
+++ b/engines/gob/variables.h
@@ -69,24 +69,12 @@ public:
const uint8 *getAddressVar8(uint32 var) const;
uint8 *getAddressVar8(uint32 var);
- const uint16 *getAddressVar16(uint32 var) const;
- uint16 *getAddressVar16(uint32 var);
-
- const uint32 *getAddressVar32(uint32 var) const;
- uint32 *getAddressVar32(uint32 var);
-
const char *getAddressVarString(uint32 var) const;
char *getAddressVarString(uint32 var);
const uint8 *getAddressOff8(uint32 offset) const;
uint8 *getAddressOff8(uint32 offset);
- const uint16 *getAddressOff16(uint32 offset) const;
- uint16 *getAddressOff16(uint32 offset);
-
- const uint32 *getAddressOff32(uint32 offset) const;
- uint32 *getAddressOff32(uint32 offset);
-
const char *getAddressOffString(uint32 offset) const;
char *getAddressOffString(uint32 offset);
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index f708729fd8..a7399caa54 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -711,6 +711,9 @@ void VideoPlayer::playFrame(int16 frame, int16 breakKey,
_vm->_video->retrace();
}
+ // Subtitle
+ if (state.flags & Graphics::CoktelVideo::kStateSpeech)
+ _vm->_draw->printTotText(state.speechId);
if (modifiedPal && ((palCmd == 2) || (palCmd == 4)))
_vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
@@ -736,6 +739,8 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
_vm->_inter->storeKey(_vm->_util->checkKey());
if (VAR(0) == (unsigned) breakKey) {
_primaryVideo->getVideo()->disableSound();
+ // Seek to the last frame. Some scripts depend on that.
+ _primaryVideo->getVideo()->seekFrame(endFrame, SEEK_SET, true);
return true;
}
}
@@ -769,7 +774,7 @@ void VideoPlayer::writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
height = _primaryVideo->getVideo()->getHeight();
if (VAR_OFFSET(varX) == 0xFFFFFFFF)
- _primaryVideo->getVideo()->getAnchor(1, 2, x, y, width, height);
+ _primaryVideo->getVideo()->getFrameCoords(1, x, y, width, height);
WRITE_VAR_OFFSET(varX, x);
WRITE_VAR_OFFSET(varY, y);
@@ -794,13 +799,4 @@ void VideoPlayer::evalBgShading(Graphics::CoktelVideo &video) {
_vm->_sound->bgUnshade();
}
-void VideoPlayer::notifyPaused(uint32 duration) {
- if (_primaryVideo->isOpen())
- _primaryVideo->getVideo()->notifyPaused(duration);
-
- for (uint i = 0; i < _videoSlots.size(); i++)
- if (_videoSlots[i] && _videoSlots[i]->isOpen())
- _videoSlots[i]->getVideo()->notifyPaused(duration);
-}
-
} // End of namespace Gob
diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h
index 532d216d7e..28e72ab43a 100644
--- a/engines/gob/videoplayer.h
+++ b/engines/gob/videoplayer.h
@@ -103,8 +103,6 @@ public:
void writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
int16 varFrames, int16 varWidth, int16 varHeight);
- void notifyPaused(uint32 duration);
-
private:
class Video {
public:
diff --git a/engines/groovie/cell.cpp b/engines/groovie/cell.cpp
index 3bc8650aa6..c257ac108e 100644
--- a/engines/groovie/cell.cpp
+++ b/engines/groovie/cell.cpp
@@ -27,156 +27,773 @@
namespace Groovie {
-CellGame::CellGame(byte *board) :
- _board(board) {
+CellGame::CellGame() {
_startX = _startY = _endX = _endY = 255;
-}
-int8 CellGame::calcMove(byte *origboard, uint8 color, uint8 depth) {
- uint8 i, j;
- int8 di, dj;
- uint8 bestStartX, bestStartY, bestEndX, bestEndY;
- int8 bestDiff = -100;
- int8 origBoardCount = countBoard(origboard, color);
- int8 currDiff = -100;
- byte *newboard;
- uint8 boardmemsize = sizeof(byte) * BOARDSIZE * BOARDSIZE;
- uint8 oppColor = 3 - color;
+ _stack_index = _boardStackPtr = 0;
+ _flag4 = false;
+ _flag2 = false;
+ _coeff3 = 0;
- bestStartX = bestStartY = bestEndX = bestEndY = 255;
- newboard = (byte*) malloc(boardmemsize);
- memcpy(newboard, origboard, boardmemsize);
+ _moveCount = 0;
+}
- if (0 == depth) {
+byte CellGame::getStartX() {
+ if (_startX > BOARDSIZE) {
+ warning ("CellGame::getStartX: not calculated yet (%d)!", _startX);
return 0;
+ } else {
+ return _startX;
+ }
+}
+
+byte CellGame::getStartY() {
+ if (_startY > BOARDSIZE) {
+ warning ("CellGame::getStartY: not calculated yet (%d)!", _startY);
+ return 6;
+ } else {
+ return _startY;
+ }
+}
+
+byte CellGame::getEndX() {
+ if (_endX > BOARDSIZE) {
+ warning ("CellGame::getEndX: not calculated yet (%d)!", _endX);
+ return 1;
+ } else {
+ return _endX;
+ }
+}
+
+byte CellGame::getEndY() {
+ if (_endY > BOARDSIZE) {
+ warning ("CellGame::getEndY: not calculated yet (%d)!", _endY);
+ return 6;
+ } else {
+ return _endY;
+ }
+}
+
+CellGame::~CellGame() {
+}
+
+const int8 possibleMoves[][9] = {
+ { 1, 7, 8, -1 },
+ { 0, 2, 7, 8, 9, -1 },
+ { 1, 3, 8, 9, 10, -1 },
+ { 2, 4, 9, 10, 11, -1 },
+ { 3, 5, 10, 11, 12, -1 },
+ { 4, 6, 11, 12, 13, -1 }, // 5
+ { 5, 12, 13, -1 },
+ { 0, 1, 8, 14, 15, -1 },
+ { 0, 1, 2, 7, 9, 14, 15, 16, -1 },
+ { 1, 2, 3, 8, 10, 15, 16, 17, -1 },
+ { 2, 3, 4, 9, 11, 16, 17, 18, -1 }, // 10
+ { 3, 4, 5, 10, 12, 17, 18, 19, -1 },
+ { 4, 5, 6, 11, 13, 18, 19, 20, -1 },
+ { 5, 6, 12, 19, 20, -1 },
+ { 7, 8, 15, 21, 22, -1 },
+ { 7, 8, 9, 14, 16, 21, 22, 23, -1 }, // 15
+ { 8, 9, 10, 15, 17, 22, 23, 24, -1 },
+ { 9, 10, 11, 16, 18, 23, 24, 25, -1 },
+ { 10, 11, 12, 17, 19, 24, 25, 26, -1 },
+ { 11, 12, 13, 18, 20, 25, 26, 27, -1 },
+ { 12, 13, 19, 26, 27, -1 }, // 20
+ { 14, 15, 22, 28, 29, -1 },
+ { 14, 15, 16, 21, 23, 28, 29, 30, -1 },
+ { 15, 16, 17, 22, 24, 29, 30, 31, -1 },
+ { 16, 17, 18, 23, 25, 30, 31, 32, -1 },
+ { 17, 18, 19, 24, 26, 31, 32, 33, -1 }, // 25
+ { 18, 19, 20, 25, 27, 32, 33, 34, -1 },
+ { 19, 20, 26, 33, 34, -1 },
+ { 21, 22, 29, 35, 36, -1 },
+ { 21, 22, 23, 28, 30, 35, 36, 37, -1 },
+ { 22, 23, 24, 29, 31, 36, 37, 38, -1 }, // 30
+ { 23, 24, 25, 30, 32, 37, 38, 39, -1 },
+ { 24, 25, 26, 31, 33, 38, 39, 40, -1 },
+ { 25, 26, 27, 32, 34, 39, 40, 41, -1 },
+ { 26, 27, 33, 40, 41, -1 },
+ { 28, 29, 36, 42, 43, -1 }, // 35
+ { 28, 29, 30, 35, 37, 42, 43, 44, -1 },
+ { 29, 30, 31, 36, 38, 43, 44, 45, -1 },
+ { 30, 31, 32, 37, 39, 44, 45, 46, -1 },
+ { 31, 32, 33, 38, 40, 45, 46, 47, -1 },
+ { 32, 33, 34, 39, 41, 46, 47, 48, -1 }, // 40
+ { 33, 34, 40, 47, 48, -1 },
+ { 35, 36, 43, -1 },
+ { 35, 36, 37, 42, 44, -1 },
+ { 36, 37, 38, 43, 45, -1 },
+ { 37, 38, 39, 44, 46, -1 }, // 45
+ { 38, 39, 40, 45, 47, -1 },
+ { 39, 40, 41, 46, 48, -1 },
+ { 40, 41, 47, -1 }
+};
+
+
+const int8 strategy2[][17] = {
+ { 2, 9, 14, 15, 16, -1 },
+ { 3, 10, 14, 15, 16, 17, -1 },
+ { 0, 4, 7, 11, 14, 15, 16, 17, 18, -1 },
+ { 1, 5, 8, 12, 15, 16, 17, 18, 19, -1 },
+ { 2, 6, 9, 13, 16, 17, 18, 19, 20, -1 },
+ { 3, 10, 17, 18, 19, 20, -1 }, // 5
+ { 4, 11, 18, 19, 20, -1 },
+ { 2, 9, 16, 21, 22, 23, -1 },
+ { 3, 10, 17, 21, 22, 23, 24, -1 },
+ { 0, 4, 7, 11, 14, 18, 21, 22, 23, 24, 25, -1 },
+ { 1, 5, 8, 12, 15, 19, 22, 23, 24, 25, 26, -1 }, // 10
+ { 2, 6, 9, 13, 16, 20, 23, 24, 25, 26, 27, -1 },
+ { 3, 10, 17, 24, 25, 26, 27, -1 },
+ { 4, 11, 18, 25, 26, 27, -1 },
+ { 0, 1, 2, 9, 16, 23, 28, 29, 30, -1 },
+ { 0, 1, 2, 3, 10, 17, 24, 28, 29, 30, 31, -1 }, // 15
+ { 0, 1, 2, 3, 4, 7, 11, 14, 18, 21, 25, 28, 29, 30, 31, 32, -1 },
+ { 1, 2, 3, 4, 5, 8, 12, 15, 19, 22, 26, 29, 30, 31, 32, 33, -1 },
+ { 2, 3, 4, 5, 6, 9, 13, 16, 20, 23, 27, 30, 31, 32, 33, 34, -1 },
+ { 3, 4, 5, 6, 10, 17, 24, 31, 32, 33, 34, -1 },
+ { 4, 5, 6, 11, 18, 25, 32, 33, 34, -1 }, // 20
+ { 7, 8, 9, 16, 23, 30, 35, 36, 37, -1 },
+ { 7, 8, 9, 10, 17, 24, 31, 35, 36, 37, 38, -1 },
+ { 7, 8, 9, 10, 11, 14, 18, 21, 25, 28, 32, 35, 36, 37, 38, 39, -1 },
+ { 8, 9, 10, 11, 12, 15, 19, 22, 26, 29, 33, 36, 37, 38, 39, 40, -1 },
+ { 9, 10, 11, 12, 13, 16, 20, 23, 27, 30, 34, 37, 38, 39, 40, 41, -1 }, // 25
+ { 10, 11, 12, 13, 17, 24, 31, 38, 39, 40, 41, -1 },
+ { 11, 12, 13, 18, 25, 32, 39, 40, 41, -1 },
+ { 14, 15, 16, 23, 30, 37, 42, 43, 44, -1 },
+ { 14, 15, 16, 17, 24, 31, 38, 42, 43, 44, 45, -1 },
+ { 14, 15, 16, 17, 18, 21, 25, 28, 32, 35, 39, 42, 43, 44, 45, 46, -1 }, // 30
+ { 15, 16, 17, 18, 19, 22, 26, 29, 33, 36, 40, 43, 44, 45, 46, 47, -1 },
+ { 16, 17, 18, 19, 20, 23, 27, 30, 34, 37, 41, 44, 45, 46, 47, 48, -1 },
+ { 17, 18, 19, 20, 24, 31, 38, 45, 46, 47, 48, -1 },
+ { 18, 19, 20, 25, 32, 39, 46, 47, 48, -1 },
+ { 21, 22, 23, 30, 37, 44, -1 }, // 35
+ { 21, 22, 23, 24, 31, 38, 45, -1 },
+ { 21, 22, 23, 24, 25, 28, 32, 35, 39, 42, 46, -1 },
+ { 22, 23, 24, 25, 26, 29, 33, 36, 40, 43, 47, -1 },
+ { 23, 24, 25, 26, 27, 30, 34, 37, 41, 44, 48, -1 },
+ { 24, 25, 26, 27, 31, 38, 45, -1 }, // 40
+ { 25, 26, 27, 32, 39, 46, -1 },
+ { 28, 29, 30, 37, 44, -1 },
+ { 28, 29, 30, 31, 38, 45, -1 },
+ { 28, 29, 30, 31, 32, 35, 39, 42, 46, -1 },
+ { 29, 30, 31, 32, 33, 36, 40, 43, 47, -1 }, // 45
+ { 30, 31, 32, 33, 34, 37, 41, 44, 48, -1 },
+ { 31, 32, 33, 34, 38, 45, -1 },
+ { 32, 33, 34, 39, 46, -1 }
+};
+
+void CellGame::copyToTempBoard() {
+ for (int i = 0; i < 53; ++i) {
+ _tempBoard[i] = _board[i];
+ }
+}
+
+void CellGame::copyFromTempBoard() {
+ for (int i = 0; i < 53; ++i) {
+ _board[i] = _tempBoard[i];
}
+}
+
+void CellGame::copyToShadowBoard() {
+ _board[53] = 0;
+ _board[55] = 1;
+ _board[56] = 0;
+
+ for (int i = 0; i < 49; ++i) {
+ _shadowBoard[i] = _board[i];
+ }
+}
+
+void CellGame::pushBoard() {
+ assert(_boardStackPtr < 57 * 9);
- for (i = 0; BOARDSIZE > i; i++) { // For every square on the board
- for (j = 0; BOARDSIZE > j; j++) { //
- if (color == *(origboard + i + (BOARDSIZE * j))) { // If the square is the desired colour
- for (di = -2; 2 >= di; di++) { // Check every square two or less in every direction
- for (dj = -2; 2 >= dj; dj++) { //
- if (di != 0 || dj != 0) { // Don't allow a move onto itself
- debugC(7, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Testing move %d, %d-> %d, %d", depth, i, j, i+di, j+dj);
- if (validMove(origboard, color, i+di, j+dj)) {
- int8 nextlevel;
- debugC(5, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Valid move %d, %d-> %d, %d", depth, i, j, i+di, j+dj);
- execMove (newboard, color, i, j, i+di, j+dj);
-
- nextlevel = calcMove (newboard, oppColor, depth - 1);
- debugC(5, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Next level down returned %d", depth, nextlevel);
- currDiff = countBoard(newboard, color) - origBoardCount - nextlevel;
- if (currDiff > bestDiff) {
- debugC(4, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Found new best move (diff of %d): %d, %d-> %d, %d", depth, currDiff, i, j, i+di, j+dj);
- bestDiff = currDiff;
- bestStartX = i;
- bestStartY = j;
- bestEndX = i+di;
- bestEndY = j+dj;
-
- }
- // TODO: ideal would be to revert the move, rather than copy the board again. I think.
- memcpy(newboard, origboard, boardmemsize);
- }
- }
+ for (int i = 0; i < 57; ++i)
+ _boardStack[_boardStackPtr + i] = _board[i];
+ _boardStackPtr += 57;
+}
+
+void CellGame::popBoard() {
+ assert(_boardStackPtr > 0);
+
+ _boardStackPtr -= 57;
+ for (int i = 0; i < 57; ++i) {
+ _board[i] = _boardStack[_boardStackPtr + i];
+ }
+}
+
+void CellGame::pushShadowBoard() {
+ assert(_boardStackPtr < 57 * 9);
+
+ for (int i = 0; i < 57; ++i)
+ _boardStack[_boardStackPtr + i] = _shadowBoard[i];
+
+ _boardStackPtr += 57;
+}
+
+void CellGame::popShadowBoard() {
+ assert(_boardStackPtr > 0);
+
+ _boardStackPtr -= 57;
+
+ for (int i = 0; i < 57; ++i) {
+ _shadowBoard[i] = _boardStack[_boardStackPtr + i];
+ }
+}
+
+void CellGame::clearMoves() {
+ _stack_startXY[0] = _board[53];
+ _stack_endXY[0] = _board[54];
+ _stack_pass[0] = _board[55];
+
+ _stack_index = 1;
+}
+
+void CellGame::pushMove() {
+ _stack_startXY[_stack_index] = _board[53];
+ _stack_endXY[_stack_index] = _board[54];
+ _stack_pass[_stack_index] = _board[55];
+
+ _stack_index++;
+}
+
+void CellGame::resetMove() {
+ _board[53] = 0;
+ _board[54] = 0;
+ _board[55] = 0;
+}
+
+void CellGame::takeCells(uint16 whereTo, int8 color) {
+ int cellN;
+ const int8 *str;
+
+ str = possibleMoves[whereTo];
+ while (1) {
+ cellN = *str++;
+ if (cellN < 0)
+ break;
+ if (_tempBoard[cellN] > 0) {
+ --_tempBoard[_tempBoard[cellN] + 48];
+ _tempBoard[cellN] = color;
+ ++_tempBoard[color + 48];
+ }
+ }
+}
+
+void CellGame::countAllCells() {
+ _board[49] = 0;
+ _board[50] = 0;
+ _board[51] = 0;
+ _board[52] = 0;
+
+ for (int i = 0; i < 49; i++) {
+ switch (_board[i]) {
+ case 1: // CELL_BLUE
+ _board[49]++;
+ break;
+ case 2: // CELL_GREEN
+ _board[50]++;
+ break;
+ case 3:
+ _board[51]++;
+ break;
+ case 4:
+ _board[52]++;
+ break;
+ }
+ }
+}
+
+int CellGame::countCellsOnTempBoard(int8 color) {
+ const int8 *str;
+ int res = 0;
+ int i;
+
+ for (i = 0; i < 49; i++)
+ _boardSum[i] = 0;
+
+ for (i = 0; i < 49; i++) {
+ if (_tempBoard[i] == color) {
+ for (str = possibleMoves[i]; *str > 0; str++) {
+ if (!_tempBoard[*str])
+ ++_boardSum[*str];
+ }
+ }
+ }
+
+ for (i = 0; i < 49; i++)
+ res += _boardSum[i];
+
+ return res;
+}
+
+bool CellGame::canMoveFunc1(int8 color) {
+ const int8 *str;
+
+ if (_board[55] == 1) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &possibleMoves[_board[53]][_board[56]];
+ for (;_board[56] < 8; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_shadowBoard[_board[54]]) {
+ _shadowBoard[_board[54]] = -1;
+ ++_board[56];
+ return true;
}
}
+ _board[56] = 0;
+ }
+ }
+ _board[53] = 0;
+ _board[55] = 2;
+ _board[56] = 0;
+ }
+ if (_board[55] == 2) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &strategy2[_board[53]][_board[56]];
+ for (;_board[56] < 16; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_board[_board[54]]) {
+ ++_board[56];
+ return true;
+ }
+ }
+ _board[56] = 0;
}
}
}
- _startX = bestStartX;
- _startY = bestStartY;
- _endX = bestEndX;
- _endY = bestEndY;
-
- debugC(2, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Best move is (diff of %d): %d, %d-> %d, %d", depth, bestDiff, _startX, _startY, _endX, _endY);
- free(newboard);
- debugC(5, kGroovieDebugCell | kGroovieDebugAll, "Freed newboard");
- return bestDiff;
+ return false;
}
-void CellGame::execMove(byte *board, uint8 color, int8 startX, int8 startY, int8 endX, int8 endY) {
- int8 i, j;
- uint8 colorToEat = 3 - color; // The opposite of the colour passed: 2 -> 1, 1 -> 2
+bool CellGame::canMoveFunc3(int8 color) {
+ const int8 *str;
+
+ if (_board[55] == 1) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &possibleMoves[_board[53]][_board[56]];
+ for (;_board[56] < 8; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_shadowBoard[_board[54]]) {
+ _shadowBoard[_board[54]] = -1;
+ ++_board[56];
+ return true;
+ }
+ }
+ _board[56] = 0;
+ }
+ }
- if (abs(endX - startX) == 2 || abs(endY - startY) == 2) {
- *(board + startX + BOARDSIZE * startY) = 0;
+ _board[53] = 0;
+ _board[55] = 2;
+ _board[56] = 0;
+ for (int i = 0; i < 49; ++i)
+ _shadowBoard[i] = _board[i];
+ }
+ if (_board[55] == 2) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &strategy2[_board[53]][_board[56]];
+ for (;_board[56] < 16; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_shadowBoard[_board[54]]) {
+ _shadowBoard[_board[54]] = -1;
+ ++_board[56];
+ return true;
+ }
+ }
+ _board[56] = 0;
+ }
+ }
}
- *(board + endX + BOARDSIZE * endY) = color;
+ return false;
+}
+
+bool CellGame::canMoveFunc2(int8 color) {
+ const int8 *str;
- for (i = (endX - 1); endX + 1 >= i; i++) {
- for (j = (endY - 1); endY + 1 >= j; j++) {
- if (BOARDSIZE > i && BOARDSIZE > j && 0 <= i && 0 <= j) { // Don't wrap around the board edges!
- uint8 offset = i + BOARDSIZE * j;
- if (colorToEat == *(board + offset)) {
- *(board + offset) = color;
+ while (1) {
+ while (_board[_board[54]]) {
+ ++_board[54];
+ if (_board[54] >= 49)
+ return false;
+ }
+ if (!_board[55]) {
+ str = possibleMoves[_board[54]];
+ while (1) {
+ _board[53] = *str++;
+ if (_board[53] < 0)
+ break;
+ if (_board[_board[53]] == color) {
+ _board[55] = 1;
+ return true;
+ }
+ }
+ _board[55] = 1;
+ }
+ if (_board[55] == 1) {
+ _board[55] = 2;
+ _board[56] = 0;
+ }
+ if (_board[55] == 2) {
+ str = &strategy2[_board[54]][_board[56]];
+ for (; _board[56] < 16; _board[56]++) {
+ _board[53] = *str++;
+ if (_board[53] < 0)
+ break;
+ if (_board[_board[53]] == color) {
+ ++_board[56];
+ return true;
}
}
+ ++_board[54];
+ _board[55] = 0;
+ if (_board[54] >= 49)
+ break;
}
}
+ return false;
+}
+
+void CellGame::makeMove(int8 color) {
+ copyToTempBoard();
+ _tempBoard[_board[54]] = color;
+ ++_tempBoard[color + 48];
+ if (_board[55] == 2) {
+ _tempBoard[_board[53]] = 0;
+ --_tempBoard[color + 48];
+ }
+ takeCells(_board[54], color);
}
-bool CellGame::validMove(byte *board, uint8 color, int8 endX, int8 endY) {
- if (0 > endX || 0 > endY || BOARDSIZE <= endX || BOARDSIZE <= endY) { // Move is out of bounds
- return false;
+int CellGame::getBoardWeight(int8 color1, int8 color2) {
+ int8 celln;
+ const int8 *str;
+ byte cellCnt[8];
+
+ str = possibleMoves[_board[54]];
+ cellCnt[1] = _board[49];
+ cellCnt[2] = _board[50];
+ cellCnt[3] = _board[51];
+ cellCnt[4] = _board[52];
+ if (_board[55] != 2)
+ ++cellCnt[color2];
+ celln = *str++;
+
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
}
- if (0 == *(board + endX + (BOARDSIZE * endY))) {
- return true;
+ celln = *str++;
+
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
}
- return false;
+ celln = *str++;
+
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
+ }
+ while (1) {
+ celln = *str++;
+ if (celln < 0)
+ break;
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
+ }
+ }
+ return _coeff3 + 2 * (2 * cellCnt[color1] - cellCnt[1] - cellCnt[2] - cellCnt[3] - cellCnt[4]);
}
-uint8 CellGame::countBoard(byte *board, uint8 color) {
- uint8 total = 0;
- for (uint8 i = 0; BOARDSIZE > i; i++) {
- for (uint8 j = 0; BOARDSIZE > j; j++) {
- if (color == *(board + i + (BOARDSIZE * j))) {
- total++;
+void CellGame::chooseBestMove(int8 color) {
+ int moveIndex = 0;
+ int curWeight;
+ int bestWeight;
+
+ if (_flag2) {
+ bestWeight = 32767;
+ for (int i = 0; i < _stack_index; ++i) {
+ _board[53] = _stack_startXY[i];
+ _board[54] = _stack_endXY[i];
+ _board[55] = _stack_pass[i];
+ makeMove(color);
+ curWeight = countCellsOnTempBoard(color);
+ if (curWeight <= bestWeight) {
+ if (curWeight < bestWeight)
+ moveIndex = 0;
+ bestWeight = curWeight;
+ _stack_startXY[moveIndex] = _board[53];
+ _stack_endXY[moveIndex] = _board[54];
+ _stack_pass[moveIndex++] = _board[55];
}
}
+ _stack_index = moveIndex;
}
- return total;
+
+ _startX = _stack_startXY[0] % 7;
+ _startY = _stack_startXY[0] / 7;
+ _endX = _stack_endXY[0] % 7;
+ _endY = _stack_endXY[0] / 7;
}
-byte CellGame::getStartX() {
- if (_startX > BOARDSIZE) {
- warning ("CellGame::getStartX: not calculated yet!");
- return 0;
+int8 CellGame::calcBestWeight(int8 color1, int8 color2, uint16 depth, int bestWeight) {
+ int8 res;
+ int8 curColor;
+ bool canMove;
+ int type;
+ uint16 i;
+ int8 currBoardWeight;
+ int8 weight;
+
+ pushBoard();
+ copyFromTempBoard();
+ curColor = color2;
+ for (i = 0;; ++i) {
+ if (i >= 4) {
+ res = _coeff3 + 2 * (2 * _board[color1 + 48] - _board[49] - _board[50] - _board[51] - _board[52]);
+ popBoard();
+ return res;
+ }
+ ++curColor;
+ if (curColor > 4)
+ curColor = 1;
+
+ if (_board[curColor + 48]) {
+ if (_board[curColor + 48] >= 49 - _board[49] - _board[50] - _board[51] - _board[52]) {
+ resetMove();
+ canMove = canMoveFunc2(curColor);
+ type = 1;
+ } else {
+ copyToShadowBoard();
+ if (depth == 1) {
+ canMove = canMoveFunc3(curColor);
+ type = 3;
+ } else {
+ canMove = canMoveFunc1(curColor);
+ type = 2;
+ }
+ }
+ if (canMove)
+ break;
+ }
+ }
+ if (_flag1) {
+ popBoard();
+ return bestWeight + 1;
+ }
+
+ depth -= 1;
+ if (depth) {
+ makeMove(curColor);
+ if (type == 1) {
+ res = calcBestWeight(color1, curColor, depth, bestWeight);
+ } else {
+ pushShadowBoard();
+ res = calcBestWeight(color1, curColor, depth, bestWeight);
+ popShadowBoard();
+ }
} else {
- return _startX;
+ res = getBoardWeight(color1, curColor);
+ }
+
+ if ((res < bestWeight && color1 != curColor) || _flag4) {
+ popBoard();
+ return res;
+ }
+
+ currBoardWeight = _coeff3 + 2 * (2 * _board[color1 + 48] - _board[49] - _board[50] - _board[51] - _board[52]);
+ while (1) {
+ if (type == 1) {
+ canMove = canMoveFunc2(curColor);
+ } else if (type == 2) {
+ canMove = canMoveFunc1(curColor);
+ } else {
+ canMove = canMoveFunc3(curColor);
+ }
+
+ if (!canMove)
+ break;
+ if (_flag1) {
+ popBoard();
+ return bestWeight + 1;
+ }
+ if (_board[55] == 2) {
+ if (getBoardWeight(color1, curColor) == currBoardWeight)
+ continue;
+ }
+ if (!depth) {
+ weight = getBoardWeight(color1, curColor);
+ if (type == 1) {
+ if (_board[55] == 2)
+ _board[56] = 16;
+ }
+ } else {
+ makeMove(curColor);
+ if (type != 1) {
+ pushShadowBoard();
+ weight = calcBestWeight(color1, curColor, depth, bestWeight);
+ popShadowBoard();
+ } else {
+ weight = calcBestWeight(color1, curColor, depth, bestWeight);
+ }
+ }
+ if ((weight < res && color1 != curColor) || (weight > res && color1 == curColor))
+ res = weight;
+
+ if ((res < bestWeight && color1 != curColor) || _flag4)
+ break;
}
+ popBoard();
+
+ return res;
}
-byte CellGame::getStartY() {
- if (_startY > BOARDSIZE) {
- warning ("CellGame::getStartY: not calculated yet!");
- return 6;
+int16 CellGame::doGame(int8 color, int depth) {
+ bool canMove;
+ int type;
+ int8 currBoardWeight;
+ int8 w1;
+ int8 w2;
+
+ countAllCells();
+ if (_board[color + 48] >= 49 - _board[49] - _board[50] - _board[51] - _board[52]) {
+ resetMove();
+ canMove = canMoveFunc2(color);
+ type = true;
} else {
- return _startY;
+ copyToShadowBoard();
+ canMove = canMoveFunc1(color);
+ type = false;
}
-}
-byte CellGame::getEndX() {
- if (_endX > BOARDSIZE) {
- warning ("CellGame::getEndX: not calculated yet!");
+ if (canMove) {
+ if (_board[color + 48] - _board[49] - _board[50] - _board[51] - _board[52] == 0)
+ depth = 0;
+ _coeff3 = 0;
+ if (_board[55] == 1)
+ _coeff3 = 1;
+ clearMoves();
+ if (depth) {
+ makeMove(color);
+ _flag4 = false;
+ if (type) {
+ w2 = calcBestWeight(color, color, depth, -127);
+ } else {
+ pushShadowBoard();
+ w2 = calcBestWeight(color, color, depth, -127);
+ popShadowBoard();
+ }
+ } else {
+ w2 = getBoardWeight(color, color);
+ }
+ currBoardWeight = 2 * (2 * _board[color + 48] - _board[49] - _board[50] - _board[51] - _board[52]);
+ while (1) {
+ if (type)
+ canMove = canMoveFunc2(color);
+ else
+ canMove = canMoveFunc1(color);
+
+ if (!canMove)
+ break;
+ if (_flag1)
+ break;
+ _coeff3 = 0;
+ if (_board[55] == 2) {
+ if (getBoardWeight(color, color) == currBoardWeight)
+ continue;
+ }
+ if (_board[55] == 1)
+ _coeff3 = 1;
+ if (depth) {
+ makeMove(color);
+ _flag4 = false;
+ if (type) {
+ w1 = calcBestWeight(color, color, depth, w2);
+ } else {
+ pushShadowBoard();
+ w1 = calcBestWeight(color, color, depth, w2);
+ popShadowBoard();
+ }
+ } else {
+ w1 = getBoardWeight(color, color);
+ }
+ if (w1 == w2)
+ pushMove();
+
+ if (w1 > w2) {
+ clearMoves();
+ w2 = w1;
+ }
+ }
+ chooseBestMove(color);
return 1;
- } else {
- return _endX;
}
+
+ return 0;
}
-byte CellGame::getEndY() {
- if (_endY > BOARDSIZE) {
- warning ("CellGame::getEndY: not calculated yet!");
- return 6;
+const int8 depths[] = { 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 3, 3 };
+
+int16 CellGame::calcMove(int8 color, uint16 depth) {
+ int result;
+
+ _flag1 = false;
+ ++_moveCount;
+ if (depth) {
+ if (depth == 1) {
+ _flag2 = true;
+ result = doGame(color, 0);
+ } else {
+ int newDepth;
+
+ newDepth = depths[3 * (depth - 2) + _moveCount % 3];
+ _flag2 = true;
+ if (newDepth >= 20) {
+ assert(0); // This branch is not implemented
+ } else {
+ result = doGame(color, newDepth);
+ }
+ }
} else {
- return _endY;
+ _flag2 = false;
+ result = doGame(color, depth);
}
+ return result;
}
-CellGame::~CellGame() {
+int CellGame::playStauf(byte color, uint16 depth, byte *scriptBoard) {
+ int i;
+
+ for (i = 0; i < 49; i++, scriptBoard++) {
+ _board[i] = 0;
+ if (*scriptBoard == 50)
+ _board[i] = 1;
+ if (*scriptBoard == 66)
+ _board[i] = 2;
+ }
+ for (i = 49; i < 57; i++)
+ _board[i] = 0;
+
+ return calcMove(color, depth);
}
+
} // End of Groovie namespace
diff --git a/engines/groovie/cell.h b/engines/groovie/cell.h
index 70e135b62d..39ee529beb 100644
--- a/engines/groovie/cell.h
+++ b/engines/groovie/cell.h
@@ -29,6 +29,7 @@
#include "common/file.h"
#include "common/util.h"
+#include "groovie/cell.h"
#include "groovie/groovie.h"
#define BOARDSIZE 7
@@ -43,24 +44,59 @@ class Script;
class CellGame {
public:
- CellGame(byte *board);
+ CellGame();
~CellGame();
- int8 calcMove(byte *origboard, uint8 color, uint8 depth);
byte getStartX();
byte getStartY();
byte getEndX();
byte getEndY();
+ int playStauf(byte color, uint16 depth, byte *scriptBoard);
private:
- bool validMove(byte *board, uint8 color, int8 endX, int8 endY);
- void execMove(byte *board, uint8 color, int8 startX, int8 startY, int8 endX, int8 endY);
- uint8 countBoard(byte* board, uint8 color);
- byte *_board;
+ void copyToTempBoard();
+ void copyFromTempBoard();
+ void copyToShadowBoard();
+ void pushBoard();
+ void popBoard();
+ void pushShadowBoard();
+ void popShadowBoard();
+ void clearMoves();
+ void pushMove();
+ void resetMove();
+ bool canMoveFunc1(int8 color);
+ bool canMoveFunc2(int8 color);
+ bool canMoveFunc3(int8 color);
+ void takeCells(uint16 whereTo, int8 color);
+ void countAllCells();
+ int countCellsOnTempBoard(int8 color);
+ void makeMove(int8 color);
+ int getBoardWeight(int8 color1, int8 color2);
+ void chooseBestMove(int8 color);
+ int8 calcBestWeight(int8 color1, int8 color2, uint16 depth, int bestWeight);
+ int16 doGame(int8 color, int depth);
+ int16 calcMove(int8 color, uint16 depth);
byte _startX;
byte _startY;
byte _endX;
byte _endY;
+
+ int8 _board[57];
+ int8 _tempBoard[58];
+ int8 _shadowBoard[64];
+ int8 _boardStack[570];
+ int _boardStackPtr;
+
+ int8 _boardSum[58];
+
+ int8 _stack_startXY[128];
+ int8 _stack_endXY[128];
+ int8 _stack_pass[128];
+ int _stack_index;
+
+ int _coeff3;
+ bool _flag1, _flag2, _flag4;
+ int _moveCount;
};
} // End of Groovie namespace
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index 6dd1124fce..86713ee3e6 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -33,6 +33,7 @@
#include "common/config-manager.h"
#include "common/endian.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#define NUM_OPCODES 90
@@ -61,7 +62,7 @@ static void debugScript(int level, bool nl, const char *s, ...) {
Script::Script(GroovieEngine *vm, EngineVersion version) :
_code(NULL), _savedCode(NULL), _stacktop(0),
_debugger(NULL), _vm(vm),
- _videoFile(NULL), _videoRef(0), _font(NULL) {
+ _videoFile(NULL), _videoRef(0), _font(NULL), _staufsMove(NULL) {
// Initialize the opcode set depending on the engine version
switch (version) {
case kGroovieT7G:
@@ -73,7 +74,7 @@ Script::Script(GroovieEngine *vm, EngineVersion version) :
}
// Initialize the random source
- _vm->_system->getEventManager()->registerRandomSource(_random, "GroovieScripts");
+ g_eventRec.registerRandomSource(_random, "GroovieScripts");
// Prepare the variables
_bitflags = 0;
@@ -196,6 +197,10 @@ void Script::directGameLoad(int slot) {
// TODO: We'll probably need to start by running the beginning of the
// script to let it do the soundcard initialization and then do the
// actual loading.
+
+ // Due to HACK above, the call to check valid save slots is not run.
+ // As this is where we load save names, manually call it here.
+ o_checkvalidsaves();
}
void Script::step() {
@@ -1391,32 +1396,21 @@ void Script::o_sub() {
}
void Script::o_cellmove() {
- uint16 arg = readScript8bits();
+ uint16 depth = readScript8bits();
byte *scriptBoard = &_variables[0x19];
- byte *board = (byte *) malloc (BOARDSIZE * BOARDSIZE * sizeof(byte));
byte startX, startY, endX, endY;
- debugScript(1, true, "CELL MOVE var[0x%02X]", arg);
-
- // Arguments used by the original implementation: (2, arg, scriptBoard)
- for (int y = 0; y < 7; y++) {
- for (int x = 0; x < 7; x++) {
- uint8 offset = x + BOARDSIZE * y;
- *(board + offset) = 0;
- if (*scriptBoard == 0x32) *(board + offset) = CELL_BLUE;
- if (*scriptBoard == 0x42) *(board + offset) = CELL_GREEN;
- scriptBoard++;
- debugScript(1, false, "%d", *(board + offset));
- }
- debugScript(1, false, "\n");
- }
+ debugScript(1, true, "CELL MOVE var[0x%02X]", depth);
- CellGame staufsMove((byte *) board);
- staufsMove.calcMove((byte *) board, CELL_GREEN, 2);
- startX = staufsMove.getStartX();
- startY = staufsMove.getStartY();
- endX = staufsMove.getEndX();
- endY = staufsMove.getEndY();
+ if (!_staufsMove)
+ _staufsMove = new CellGame;
+
+ _staufsMove->playStauf(2, depth, scriptBoard);
+
+ startX = _staufsMove->getStartX();
+ startY = _staufsMove->getStartY();
+ endX = _staufsMove->getEndX();
+ endY = _staufsMove->getEndY();
// Set the movement origin
setVariable(0, startY); // y
@@ -1424,8 +1418,6 @@ void Script::o_cellmove() {
// Set the movement destination
setVariable(2, endY);
setVariable(3, endX);
-
- free(board);
}
void Script::o_returnscript() {
diff --git a/engines/groovie/script.h b/engines/groovie/script.h
index 8a95f093ce..4ff79b36b6 100644
--- a/engines/groovie/script.h
+++ b/engines/groovie/script.h
@@ -40,6 +40,7 @@ enum EngineVersion {
};
class GroovieEngine;
+class CellGame;
class Script {
friend class Debugger;
@@ -121,6 +122,8 @@ private:
Common::String _debugString;
uint16 _oldInstruction;
+ CellGame *_staufsMove;
+
// Helper functions
uint8 getCodeByte(uint16 address);
uint8 readScript8bits();
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 85d974f675..d9924d233b 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -538,18 +538,18 @@ int MainMenu::handle(int dim) {
int item = (mouse.y - menuRect.top) / fh;
if (item != selected) {
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5);
- printString(_static.strings[item], textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5);
+ 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(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5);
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
_screen->updateScreen();
_system->delayMillis(50);
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5);
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5, _static.strings[selected]);
_screen->updateScreen();
_system->delayMillis(50);
}
@@ -577,7 +577,7 @@ void MainMenu::draw(int select) {
for (int i = 0; i < _static.menuTable[3]; ++i) {
int curY = top + i * _screen->getFontHeight();
int color = (i == select) ? _static.menuTable[6] : _static.menuTable[5];
- printString(_static.strings[i], ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5);
+ printString("%s", ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5, _static.strings[i]);
}
}
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index 69e7419757..cb2476ff99 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -757,7 +757,6 @@ int GUI_HoF::optionsButton(Button *button) {
initMenu(*_currentMenu);
_madeSave = false;
_loadedSave = false;
- _vm->_itemInHand = -1;
updateAllMenuButtons();
if (_isDeathMenu) {
@@ -821,6 +820,7 @@ void GUI_HoF::resetState(int item) {
_vm->setNextIdleAnimTimer();
_isDeathMenu = false;
if (!_loadedSave) {
+ _vm->_itemInHand = -1;
_vm->setHandItem(item);
} else {
_vm->setHandItem(_vm->_itemInHand);
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index e7001ed31f..858e3fde94 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -1141,6 +1141,7 @@ void GUI_MR::resetState(int item) {
_vm->setNextIdleAnimTimer();
_isDeathMenu = false;
if (!_loadedSave) {
+ _vm->_itemInHand = -1;
_vm->setHandItem(item);
} else {
_vm->setHandItem(_vm->_itemInHand);
@@ -1260,7 +1261,6 @@ int GUI_MR::optionsButton(Button *button) {
initMenu(*_currentMenu);
_madeSave = false;
_loadedSave = false;
- _vm->_itemInHand = -1;
updateAllMenuButtons();
if (_isDeathMenu) {
diff --git a/engines/kyra/items_mr.cpp b/engines/kyra/items_mr.cpp
index 5397651e97..d08d58e65d 100644
--- a/engines/kyra/items_mr.cpp
+++ b/engines/kyra/items_mr.cpp
@@ -87,7 +87,8 @@ void KyraEngine_MR::setMouseCursor(uint16 item) {
shape = item+248;
}
- if ((int16)item != _itemInHand)
+ _mouseState = item;
+ if ((int16)item >= 0)
_screen->setMouseCursor(hotX, hotY, getShapePtr(shape));
}
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 5c41989713..bf515498dc 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -1658,7 +1658,7 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) {
if (!file)
error("Couldn't load cauldron palette");
file->seek(state*18, SEEK_SET);
- _screen->getPalette(0).loadVGAPalette(*file, 241, 6);
+ _screen->getPalette(2).loadVGAPalette(*file, 241, 6);
delete file;
file = 0;
@@ -1673,8 +1673,8 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) {
_screen->getPalette(0).copy(_screen->getPalette(2), 241, 6);
_cauldronState = state;
_cauldronUseCount = 0;
- //if (state == 5)
- // sub_27149();
+ if (state == 5)
+ setDlgIndex(5);
}
void KyraEngine_HoF::clearCauldronTable() {
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 88bfb8c89b..2204f78b82 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -495,6 +495,7 @@ private:
bool _useFrameTable;
int o3a_setCharacterFrame(EMCState *script);
+ int o3a_playSoundEffect(EMCState *script);
// special shape code
int initAnimationShapes(uint8 *filedata);
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index 258d0c402f..d79d9a8f32 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -24,6 +24,7 @@
*/
#include "common/config-manager.h"
+#include "common/EventRecorder.h"
#include "sound/mididrv.h"
#include "sound/mixer.h"
@@ -81,7 +82,7 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
Common::addDebugChannel(kDebugLevelMovie, "Movie", "Movie debug level");
Common::addDebugChannel(kDebugLevelTimer, "Timer", "Timer debug level");
- _eventMan->registerRandomSource(_rnd, "kyra");
+ g_eventRec.registerRandomSource(_rnd, "kyra");
}
::GUI::Debugger *KyraEngine_v1::getDebugger() {
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index 83230d6e3b..9e0ddcea4f 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -222,11 +222,7 @@ const char *KyraEngine_v1::getSavegameFilename(int num) {
Common::String KyraEngine_v1::getSavegameFilename(const Common::String &target, int num) {
assert(num >= 0 && num <= 999);
-
- char extension[5];
- sprintf(extension, "%03d", num);
-
- return target + "." + extension;
+ return target + Common::String::printf(".%03d", num);
}
bool KyraEngine_v1::saveFileLoadable(int slot) {
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 6c2c48cb02..7a7544a589 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -95,25 +95,10 @@ bool Screen::init() {
}
if (_useSJIS) {
- if (!_sjisFont) {
- // we use the FM-TOWNS font rom for PC-98, too, until we feel
- // like adding support for the PC-98 font
- //if (_vm->gameFlags().platform == Common::kPlatformFMTowns) {
- // FM-TOWNS
- Common::SeekableReadStream *rom = _vm->resource()->createReadStream("FMT_FNT.ROM");
- Graphics::FontTowns *townsFont = new Graphics::FontTowns();
- if (!rom || !townsFont || !townsFont->loadFromStream(*rom))
- error("Could not load font rom ('FMT_FNT.ROM') required for this version");
- _sjisFont = townsFont;
- delete rom;
- /*} else {
- // PC-98
- _sjisFontData = _vm->resource()->fileData("FONT.ROM", 0);
- if (!_sjisFontData)
- error("missing font rom ('FONT.ROM') required for this version");
- }*/
- }
-
+ _sjisFont = Graphics::FontSJIS::createFont(_vm->gameFlags().platform);
+
+ if (!_sjisFont)
+ error("Could not load any SJIS font, neither the original nor ScummVM's 'SJIS.FNT'");
_sjisFont->enableOutline(!_use16ColorMode);
}
}
diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp
index 1800bd1939..819bf838ca 100644
--- a/engines/kyra/script_mr.cpp
+++ b/engines/kyra/script_mr.cpp
@@ -1114,6 +1114,12 @@ int KyraEngine_MR::o3a_setCharacterFrame(EMCState *script) {
return 0;
}
+int KyraEngine_MR::o3a_playSoundEffect(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3a_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0));
+ snd_playSoundEffect(stackPos(0), 200);
+ return 0;
+}
+
#pragma mark -
int KyraEngine_MR::o3d_updateAnim(EMCState *script) {
@@ -1374,7 +1380,7 @@ void KyraEngine_MR::setupOpcodeTable() {
// 0x00
Opcode(o2a_setAnimationShapes);
Opcode(o3a_setCharacterFrame);
- Opcode(o3_playSoundEffect);
+ Opcode(o3a_playSoundEffect);
Opcode(o3_dummy);
// 0x04
Opcode(o2a_setResetFrame);
diff --git a/engines/kyra/sequences_mr.cpp b/engines/kyra/sequences_mr.cpp
index 4d1117f3c9..a1830aec5c 100644
--- a/engines/kyra/sequences_mr.cpp
+++ b/engines/kyra/sequences_mr.cpp
@@ -42,7 +42,8 @@ void KyraEngine_MR::showBadConscience() {
_badConscienceAnim = 6;
else if (_currentChapter == 5 && _rnd.getRandomNumberRng(1, 100) <= 25)
_badConscienceAnim = 7;
- else if (_characterShapeFile == 9)
+
+ if (_characterShapeFile == 9)
_badConscienceAnim = 4;
_badConsciencePosition = (_mainCharacter.x1 <= 160);
diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp
index 6b81b1c022..1d8bc5b03c 100644
--- a/engines/kyra/sound_digital.cpp
+++ b/engines/kyra/sound_digital.cpp
@@ -346,7 +346,7 @@ int AUDStream::readChunk(int16 *buffer, const int maxSamples) {
#pragma mark -
-SoundDigital::SoundDigital(KyraEngine_MR *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer), _sounds() {
+SoundDigital::SoundDigital(KyraEngine_MR *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
for (uint i = 0; i < ARRAYSIZE(_sounds); ++i)
_sounds[i].stream = 0;
}
diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp
index 3cc632a391..456dcc06f3 100644
--- a/engines/kyra/sprites.cpp
+++ b/engines/kyra/sprites.cpp
@@ -28,6 +28,8 @@
#include "common/stream.h"
#include "common/util.h"
#include "common/system.h"
+#include "common/EventRecorder.h"
+
#include "kyra/screen.h"
#include "kyra/kyra_lok.h"
#include "kyra/sprites.h"
@@ -47,7 +49,7 @@ Sprites::Sprites(KyraEngine_LoK *vm, OSystem *system) {
_spriteDefStart = 0;
memset(_drawLayerTable, 0, sizeof(_drawLayerTable));
_sceneAnimatorBeaconFlag = 0;
- _vm->getEventManager()->registerRandomSource(_rnd, "kyraSprites");
+ g_eventRec.registerRandomSource(_rnd, "kyraSprites");
}
Sprites::~Sprites() {
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 969d8215fb..b5ec00fdf9 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -38,6 +38,7 @@
#include "lure/sound.h"
#include "lure/lure.h"
#include "common/endian.h"
+#include "common/EventRecorder.h"
namespace Lure {
@@ -600,7 +601,7 @@ void Hotspot::setRandomDest() {
Common::RandomSource rnd;
int16 xp, yp;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
if (currentActions().isEmpty())
currentActions().addFront(START_WALKING, roomNumber());
@@ -2691,7 +2692,19 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) {
return;
}
h.currentActions().top().setAction(WALKING);
- h.setPosition(h.x(), h.y() & 0xfff8);
+
+ // WORKAROUND: A character that had enteredg an exit area might have been blocked from entering the new room.
+ // The Y position adjust below could thus place a character further into the exit area. So don't do the
+ // position adjustment if the user is already in an exit area
+ int16 x = h.x() + (h.widthCopy() >> 1);
+ int16 y = h.y() + h.heightCopy() - (h.yCorrection() >> 1);
+
+ RoomData *roomData = Resources::getReference().getRoom(h.roomNumber());
+ RoomExitData *exitRec = roomData->exits.checkExits(x, y);
+
+ if (!exitRec)
+ h.setPosition(h.x(), h.y() & 0xfff8);
+
} else if (h.blockedState() == BS_FINAL) {
// If this point is reached, the character twice hasn't found a walking path
debugC(ERROR_DETAILED, kLureDebugAnimations, "Character is hopelessly blocked");
@@ -3135,7 +3148,7 @@ void HotspotTickHandlers::followerAnimHandler(Hotspot &h) {
Common::RandomSource rnd;
RandomActionType actionType;
uint16 scheduleId;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
int actionIndex = rnd.getRandomNumber(set->numActions() - 1);
set->getEntry(actionIndex, actionType, scheduleId);
@@ -3325,7 +3338,7 @@ void HotspotTickHandlers::prisonerAnimHandler(Hotspot &h) {
ValueTableData &fields = Resources::getReference().fieldList();
Common::RandomSource rnd;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
h.handleTalkDialog();
if (h.frameCtr() > 0) {
@@ -3368,7 +3381,7 @@ void HotspotTickHandlers::morkusAnimHandler(Hotspot &h) {
if (h.executeScript()) {
// Script is done - set new script to one of two alternates randomly
Common::RandomSource rnd;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
h.setHotspotScript(rnd.getRandomNumber(100) >= 50 ? 0x54 : 0);
h.setFrameCtr(20 + rnd.getRandomNumber(63));
@@ -3668,7 +3681,7 @@ void HotspotTickHandlers::barmanAnimHandler(Hotspot &h) {
Common::RandomSource rnd;
static bool ewanXOffset = false;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
h.handleTalkDialog();
if (h.delayCtr() > 0) {
diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp
index 95cb0a2f1b..7eb76cad32 100644
--- a/engines/lure/res.cpp
+++ b/engines/lure/res.cpp
@@ -30,6 +30,7 @@
#include "lure/lure.h"
#include "common/endian.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
namespace Lure {
@@ -42,7 +43,7 @@ Resources &Resources::getReference() {
}
Resources::Resources() {
- g_system->getEventManager()->registerRandomSource(_rnd, "lureResources");
+ g_eventRec.registerRandomSource(_rnd, "lureResources");
int_resources = this;
reloadData();
diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
index 391147ebd5..f9d854a73b 100644
--- a/engines/lure/scripts.cpp
+++ b/engines/lure/scripts.cpp
@@ -34,6 +34,7 @@
#include "lure/sound.h"
#include "common/stack.h"
#include "common/endian.h"
+#include "common/EventRecorder.h"
namespace Lure {
@@ -739,7 +740,7 @@ void Script::addActions(uint16 hotspotId, uint16 actions, uint16 v3) {
void Script::randomToGeneral(uint16 maxVal, uint16 minVal, uint16 v3) {
Common::RandomSource rnd;
- g_system->getEventManager()->registerRandomSource(rnd, "lureScripts");
+ g_eventRec.registerRandomSource(rnd, "lureScripts");
uint16 v = minVal + rnd.getRandomNumber(maxVal - minVal);
Resources::getReference().fieldList().setField(GENERAL, v);
}
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
index c27f151fdf..b4973002a6 100644
--- a/engines/m4/m4.cpp
+++ b/engines/m4/m4.cpp
@@ -53,6 +53,7 @@
#include "common/file.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/endian.h"
#include "common/system.h"
#include "common/config-manager.h"
@@ -192,7 +193,7 @@ Common::Error M4Engine::run() {
_animation = new Animation(this);
//_callbacks = new Callbacks(this);
_random = new Common::RandomSource();
- g_system->getEventManager()->registerRandomSource(*_random, "m4");
+ g_eventRec.registerRandomSource(*_random, "m4");
if (isM4())
return goM4();
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index 50a14c3e34..c83f7aaf02 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/keyboard.h"
#include "common/file.h"
#include "common/savefile.h"
@@ -74,7 +75,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_gameId = g->id;
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "made");
+ g_eventRec.registerRandomSource(*_rnd, "made");
int cd_num = ConfMan.getInt("cdrom");
if (cd_num >= 0)
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 7aee966aa6..8fadd4e462 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -25,6 +25,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/util.h"
#include "common/system.h"
@@ -70,7 +71,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
Common::addDebugChannel(kDebugMenu, "menu", "Menu debug level");
Common::addDebugChannel(kDebugInventory, "inventory", "Inventory debug level");
- syst->getEventManager()->registerRandomSource(_rnd, "parallaction");
+ g_eventRec.registerRandomSource(_rnd, "parallaction");
}
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h
index b7c8a9e029..3672fd3b09 100644
--- a/engines/parallaction/parser.h
+++ b/engines/parallaction/parser.h
@@ -172,14 +172,14 @@ protected:
DECLARE_UNQUALIFIED_COMMAND_PARSER(simple);
DECLARE_UNQUALIFIED_COMMAND_PARSER(move);
DECLARE_UNQUALIFIED_COMMAND_PARSER(endcommands);
-
+public:
virtual void parseGetData(ZonePtr z);
virtual void parseExamineData(ZonePtr z);
virtual void parseDoorData(ZonePtr z);
virtual void parseMergeData(ZonePtr z);
virtual void parseHearData(ZonePtr z);
virtual void parseSpeakData(ZonePtr z);
-
+protected:
Common::String parseComment();
Common::String parseDialogueString();
Dialogue *parseDialogue();
@@ -289,10 +289,12 @@ protected:
DECLARE_UNQUALIFIED_ANIM_PARSER(endanimation);
virtual void parseZoneTypeBlock(ZonePtr z);
- void parsePathData(ZonePtr z);
- void parseGetData(ZonePtr z);
- void parseDoorData(ZonePtr z);
- void parseAnswerCounter(Answer *answer);
+public:
+ virtual void parsePathData(ZonePtr z);
+ virtual void parseGetData(ZonePtr z);
+ virtual void parseDoorData(ZonePtr z);
+protected:
+ void parseAnswerCounter(Answer *answer);
virtual Answer *parseAnswer();
public:
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index b1dd86a693..563faa16e6 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -808,26 +808,27 @@ void LocationParser_br::parseDoorData(ZonePtr z) {
}
}
+typedef void (LocationParser_br::*ZoneTypeParser)(ZonePtr);
+static ZoneTypeParser parsers[] = {
+ 0, // no type
+ &LocationParser_br::parseExamineData,
+ &LocationParser_br::parseDoorData,
+ &LocationParser_br::parseGetData,
+ &LocationParser_br::parseMergeData,
+ 0, // taste
+ &LocationParser_br::parseHearData,
+ 0, // feel
+ &LocationParser_br::parseSpeakData,
+ 0, // none
+ 0, // trap
+ 0, // you
+ 0, // command
+ &LocationParser_br::parsePathData,
+ 0, // box
+};
+
void LocationParser_br::parseZoneTypeBlock(ZonePtr z) {
debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type);
- typedef void (LocationParser_br::*ZoneTypeParser)(ZonePtr);
- ZoneTypeParser parsers[] = {
- 0, // no type
- &LocationParser_br::parseExamineData,
- &LocationParser_br::parseDoorData,
- &LocationParser_br::parseGetData,
- &LocationParser_br::parseMergeData,
- 0, // taste
- &LocationParser_br::parseHearData,
- 0, // feel
- &LocationParser_br::parseSpeakData,
- 0, // none
- 0, // trap
- 0, // you
- 0, // command
- &LocationParser_br::parsePathData,
- 0, // box
- };
ZoneTypeParser p = parsers[ACTIONTYPE(z)];
do {
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 9971828c31..1c06f86bfa 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -1411,24 +1411,25 @@ void LocationParser_ns::parseSpeakData(ZonePtr z) {
}
}
+typedef void (LocationParser_ns::*ZoneTypeParser)(ZonePtr);
+static ZoneTypeParser parsers[] = {
+ 0, // no type
+ &LocationParser_ns::parseExamineData,
+ &LocationParser_ns::parseDoorData,
+ &LocationParser_ns::parseGetData,
+ &LocationParser_ns::parseMergeData,
+ 0, // taste
+ &LocationParser_ns::parseHearData,
+ 0, // feel
+ &LocationParser_ns::parseSpeakData,
+ 0, // none
+ 0, // trap
+ 0, // you
+ 0 // command
+};
+
void LocationParser_ns::parseZoneTypeBlock(ZonePtr z) {
debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type);
- typedef void (LocationParser_ns::*ZoneTypeParser)(ZonePtr);
- ZoneTypeParser parsers[] = {
- 0, // no type
- &LocationParser_ns::parseExamineData,
- &LocationParser_ns::parseDoorData,
- &LocationParser_ns::parseGetData,
- &LocationParser_ns::parseMergeData,
- 0, // taste
- &LocationParser_ns::parseHearData,
- 0, // feel
- &LocationParser_ns::parseSpeakData,
- 0, // none
- 0, // trap
- 0, // you
- 0 // command
- };
ZoneTypeParser p = parsers[ACTIONTYPE(z)];
do {
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 5db0e732ee..d95decfd4f 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -67,16 +67,6 @@ public:
virtual void reflowLayout();
};
-Common::String SaveLoad_ns::genOldSaveFileName(uint slot) {
- assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
-
- char s[20];
- sprintf(s, "game.%i", slot);
-
- return Common::String(s);
-}
-
-
Common::String SaveLoad::genSaveFileName(uint slot) {
assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
@@ -430,55 +420,55 @@ void SaveLoad_ns::getGamePartProgress(bool *complete, int size) {
complete[2] = s.contains("dough");
}
-void SaveLoad_ns::renameOldSavefiles() {
+static bool askRenameOldSavefiles() {
+ GUI::MessageDialog dialog0(
+ "ScummVM found that you have old savefiles for Nippon Safes that should be renamed.\n"
+ "The old names are no longer supported, so you will not be able to load your games if you don't convert them.\n\n"
+ "Press OK to convert them now, otherwise you will be asked next time.\n", "OK", "Cancel");
- bool exists[NUM_SAVESLOTS];
- uint num = 0;
- uint i;
+ return (dialog0.runModal() != 0);
+}
- for (i = 0; i < NUM_SAVESLOTS; i++) {
- exists[i] = false;
- Common::String name = genOldSaveFileName(i);
- Common::InSaveFile *f = _saveFileMan->openForLoading(name);
- if (f) {
- exists[i] = true;
- num++;
+void SaveLoad_ns::renameOldSavefiles() {
+ Common::StringList oldFilenames = _saveFileMan->listSavefiles("game.*");
+ uint numOldSaves = oldFilenames.size();
+
+ bool rename = false;
+ uint success = 0, id;
+ Common::String oldName, newName;
+ for (uint i = 0; i < oldFilenames.size(); ++i) {
+ oldName = oldFilenames[i];
+ int e = sscanf(oldName.c_str(), "game.%u", &id);
+ if (e != 1) {
+ // this wasn't a savefile, so adjust numOldSaves accordingly
+ --numOldSaves;
+ continue;
}
- delete f;
- }
-
- if (num == 0) {
- // there are no old savefiles: nothing to do
- return;
- }
- GUI::MessageDialog dialog0(
- "ScummVM found that you have old savefiles for Nippon Safes that should be renamed.\n"
- "The old names are no longer supported, so you will not be able to load your games if you don't convert them.\n\n"
- "Press OK to convert them now, otherwise you will be asked you next time.\n", "OK", "Cancel");
+ if (!rename) {
+ rename = askRenameOldSavefiles();
+ }
+ if (!rename) {
+ // return immediately if the user doesn't want to rename the files
+ return;
+ }
- int choice = dialog0.runModal();
- if (choice == 0) {
- // user pressed cancel
- return;
+ newName = genSaveFileName(id);
+ if (_saveFileMan->renameSavefile(oldName, newName)) {
+ success++;
+ } else {
+ warning("Error %i (%s) occurred while renaming %s to %s", _saveFileMan->getError(),
+ _saveFileMan->getErrorDesc().c_str(), oldName.c_str(), newName.c_str());
+ }
}
- uint success = 0;
- for (i = 0; i < NUM_SAVESLOTS; i++) {
- if (exists[i]) {
- Common::String oldName = genOldSaveFileName(i);
- Common::String newName = genSaveFileName(i);
- if (_saveFileMan->renameSavefile(oldName, newName)) {
- success++;
- } else {
- warning("Error %i (%s) occurred while renaming %s to %s", _saveFileMan->getError(),
- _saveFileMan->getErrorDesc().c_str(), oldName.c_str(), newName.c_str());
- }
- }
+ if (numOldSaves == 0) {
+ // there were no old savefiles: nothing to notify
+ return;
}
char msg[200];
- if (success == num) {
+ if (success == numOldSaves) {
sprintf(msg, "ScummVM successfully converted all your savefiles.");
} else {
sprintf(msg,
diff --git a/engines/parallaction/saveload.h b/engines/parallaction/saveload.h
index 2b2a7ab6a5..0bcc930c8a 100644
--- a/engines/parallaction/saveload.h
+++ b/engines/parallaction/saveload.h
@@ -62,7 +62,6 @@ public:
class SaveLoad_ns : public SaveLoad {
Parallaction_ns *_vm;
- Common::String genOldSaveFileName(uint slot);
protected:
void renameOldSavefiles();
diff --git a/engines/queen/display.cpp b/engines/queen/display.cpp
index bac7c5f419..ae223ff6cf 100644
--- a/engines/queen/display.cpp
+++ b/engines/queen/display.cpp
@@ -25,6 +25,7 @@
#include "common/system.h"
+#include "common/EventRecorder.h"
#include "common/events.h"
#include "graphics/cursorman.h"
@@ -74,7 +75,7 @@ Display::Display(QueenEngine *vm, OSystem *system)
memset(&_dynalum, 0, sizeof(_dynalum));
setupInkColors();
- system->getEventManager()->registerRandomSource(_rnd, "queenDisplay");
+ g_eventRec.registerRandomSource(_rnd, "queenDisplay");
}
Display::~Display() {
diff --git a/engines/queen/music.cpp b/engines/queen/music.cpp
index 8a50ae6b40..3d5bfbdf73 100644
--- a/engines/queen/music.cpp
+++ b/engines/queen/music.cpp
@@ -25,6 +25,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "queen/music.h"
#include "queen/queen.h"
@@ -84,7 +85,7 @@ MidiMusic::MidiMusic(QueenEngine *vm)
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
- vm->getEventManager()->registerRandomSource(_rnd, "queenMusic");
+ g_eventRec.registerRandomSource(_rnd, "queenMusic");
}
MidiMusic::~MidiMusic() {
diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
index ec074190d3..7c351842c4 100644
--- a/engines/queen/queen.cpp
+++ b/engines/queen/queen.cpp
@@ -31,6 +31,7 @@
#include "common/savefile.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "queen/queen.h"
#include "queen/bankman.h"
@@ -193,7 +194,7 @@ namespace Queen {
QueenEngine::QueenEngine(OSystem *syst)
: Engine(syst), _debugger(0) {
- syst->getEventManager()->registerRandomSource(randomizer, "queen");
+ g_eventRec.registerRandomSource(randomizer, "queen");
}
QueenEngine::~QueenEngine() {
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index faf9cbed80..265008992a 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -204,7 +204,7 @@ SaveStateList SagaMetaEngine::listSaves(const char *target) const {
// Obtain the last 2 digits of the filename, since they correspond to the save slot
slotNum = atoi(file->c_str() + file->size() - 2);
- if (slotNum >= 0 && slotNum <= 99) {
+ if (slotNum >= 0 && slotNum < MAX_SAVES) {
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
for (int i = 0; i < 3; i++)
@@ -219,7 +219,7 @@ SaveStateList SagaMetaEngine::listSaves(const char *target) const {
return saveList;
}
-int SagaMetaEngine::getMaximumSaveSlot() const { return 99; }
+int SagaMetaEngine::getMaximumSaveSlot() const { return MAX_SAVES - 1; }
void SagaMetaEngine::removeSaveState(const char *target, int slot) const {
char extension[6];
diff --git a/engines/saga/font.cpp b/engines/saga/font.cpp
index d58d1a8900..8b9b45d3ff 100644
--- a/engines/saga/font.cpp
+++ b/engines/saga/font.cpp
@@ -143,10 +143,7 @@ void Font::createOutline(FontData *font) {
int i;
int row;
int newByteWidth;
- int oldByteWidth;
int newRowLength = 0;
- size_t indexOffset = 0;
- int index;
int currentByte;
unsigned char *basePointer;
unsigned char *srcPointer;
@@ -154,57 +151,22 @@ void Font::createOutline(FontData *font) {
unsigned char *destPointer2;
unsigned char *destPointer3;
unsigned char charRep;
- int nextIndex = 0;
-
// Populate new font style character data
for (i = 0; i < FONT_CHARCOUNT; i++) {
newByteWidth = 0;
- oldByteWidth = 0;
- index = font->normal.fontCharEntry[i].index;
- if ((index > 0) || (i == FONT_FIRSTCHAR)) {
- index += indexOffset;
- }
-
- bool skip = false;
-
- if (font->normal.fontCharEntry[i].width != 0 && font->normal.fontCharEntry[i].index < nextIndex) {
- // Some characters are copies of earlier characters.
- // Look up the original, and make sure not to grow the size of
- // the outline font twice.
- skip = true;
- bool found = false;
- for (int j = 0; j < i; j++) {
- if (font->normal.fontCharEntry[i].index == font->normal.fontCharEntry[j].index) {
- index = font->outline.fontCharEntry[j].index;
- found = true;
- break;
- }
- }
- if (!found)
- error("Invalid index backreference in font char %d", i);
- }
- font->outline.fontCharEntry[i].index = index;
+ font->outline.fontCharEntry[i].index = newRowLength;
font->outline.fontCharEntry[i].tracking = font->normal.fontCharEntry[i].tracking;
font->outline.fontCharEntry[i].flag = font->normal.fontCharEntry[i].flag;
- if (font->normal.fontCharEntry[i].width != 0) {
+ if (font->normal.fontCharEntry[i].width != 0)
newByteWidth = getByteLen(font->normal.fontCharEntry[i].width + 2);
- oldByteWidth = getByteLen(font->normal.fontCharEntry[i].width);
-
- if (!skip && newByteWidth > oldByteWidth) {
- indexOffset++;
- }
- }
font->outline.fontCharEntry[i].width = font->normal.fontCharEntry[i].width + 2;
font->outline.fontCharEntry[i].byteWidth = newByteWidth;
- if (!skip) {
- newRowLength += newByteWidth;
- nextIndex = font->normal.fontCharEntry[i].index + oldByteWidth;
- }
+ newRowLength += newByteWidth;
}
debug(2, "New row length: %d", newRowLength);
@@ -220,10 +182,6 @@ void Font::createOutline(FontData *font) {
// Generate outline font representation
for (i = 0; i < FONT_CHARCOUNT; i++) {
- if (i > 0 && font->normal.fontCharEntry[i].index < font->normal.fontCharEntry[i-1].index) {
- // Skip copies
- continue;
- }
for (row = 0; row < font->normal.header.charHeight; row++) {
for (currentByte = 0; currentByte < font->outline.fontCharEntry[i].byteWidth; currentByte++) {
basePointer = font->outline.font + font->outline.fontCharEntry[i].index + currentByte;
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
index 4acf93d030..2a2a4b993c 100644
--- a/engines/saga/saga.cpp
+++ b/engines/saga/saga.cpp
@@ -29,6 +29,7 @@
#include "common/config-manager.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "sound/mixer.h"
@@ -114,7 +115,7 @@ SagaEngine::SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc)
Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
_displayClip.left = _displayClip.top = 0;
- syst->getEventManager()->registerRandomSource(_rnd, "saga");
+ g_eventRec.registerRandomSource(_rnd, "saga");
}
SagaEngine::~SagaEngine() {
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 7c1a165ec1..2ddc6979c9 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -194,6 +194,7 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
scriptState.seekLevel = 0;
scriptState.runningStep = 0;
scriptState.stopOnEvent = false;
+ scriptState.debugging = false;
}
Console::~Console() {
@@ -2091,28 +2092,30 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
printf("\n");
}
- return 0;
return true;
}
bool Console::cmdStep(int argc, const char **argv) {
if (argc == 2 && atoi(argv[1]) > 0)
scriptState.runningStep = atoi(argv[1]) - 1;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepEvent(int argc, const char **argv) {
scriptState.stopOnEvent = true;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepRet(int argc, const char **argv) {
scriptState.seeking = kDebugSeekLevelRet;
scriptState.seekLevel = _vm->_gamestate->_executionStack.size() - 1;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepGlobal(int argc, const char **argv) {
@@ -2124,8 +2127,9 @@ bool Console::cmdStepGlobal(int argc, const char **argv) {
scriptState.seeking = kDebugSeekGlobal;
scriptState.seekSpecial = atoi(argv[1]);
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepCallk(int argc, const char **argv) {
@@ -2156,8 +2160,9 @@ bool Console::cmdStepCallk(int argc, const char **argv) {
} else {
scriptState.seeking = kDebugSeekCallk;
}
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdDissassemble(int argc, const char **argv) {
@@ -2227,7 +2232,7 @@ bool Console::cmdDissassembleAddress(int argc, const char **argv) {
_vm->_gamestate->seg_manager->dereference(vpc, &size);
size += vpc.offset; // total segment size
- for (int i = 1; i < argc; i++) {
+ for (int i = 2; i < argc; i++) {
if (!scumm_stricmp(argv[i], "bwt"))
do_bwc = 1;
else if (!scumm_stricmp(argv[i], "bc"))
@@ -2322,14 +2327,16 @@ bool Console::cmdSend(int argc, const char **argv) {
xstack->fp += argc;
_vm->_gamestate->_executionStackPosChanged = true;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdGo(int argc, const char **argv) {
+ // CHECKME: is this necessary?
scriptState.seeking = kDebugSeekNothing;
- return true;
+ return Cmd_Exit(argc, argv);
}
bool Console::cmdBreakpointList(int argc, const char **argv) {
diff --git a/engines/sci/debug.h b/engines/sci/debug.h
index cd2de2b3a9..a3c4fab372 100644
--- a/engines/sci/debug.h
+++ b/engines/sci/debug.h
@@ -38,6 +38,7 @@ enum DebugSeeking {
};
struct ScriptState {
+ bool debugging;
bool stopOnEvent;
DebugSeeking seeking; // Stepping forward until some special condition is met
int runningStep; // Set to > 0 to allow multiple stepping
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 92cfe9daf3..11dd56f2aa 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -311,11 +311,18 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
void script_debug(EngineState *s, bool bp) {
// Do we support a separate console?
- printf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc));
- disassemble(s, scriptState.xs->addr.pc, 0, 1);
- if (scriptState.seeking == kDebugSeekGlobal)
- printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial,
- scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial]));
+ /* if (sci_debug_flags & _DEBUG_FLAG_LOGGING) { */
+ printf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc));
+ disassemble(s, scriptState.xs->addr.pc, 0, 1);
+ if (scriptState.seeking == kDebugSeekGlobal)
+ printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial,
+ scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial]));
+ /* } */
+
+#if 0
+ if (!scriptState.debugging)
+ return;
+#endif
if (scriptState.seeking && !bp) { // Are we looking for something special?
MemObject *mobj = GET_SEGMENT(*s->seg_manager, scriptState.xs->addr.pc.segment, MEM_OBJ_SCRIPT);
@@ -370,9 +377,19 @@ void script_debug(EngineState *s, bool bp) {
// OK, found whatever we were looking for
}
}
-
+
printf("Step #%d\n", script_step_counter);
disassemble(s, scriptState.xs->addr.pc, 0, 1);
+
+ if (scriptState.runningStep) {
+ scriptState.runningStep--;
+ return;
+ }
+
+ scriptState.debugging = false;
+
+ Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
+ con->attach();
}
} // End of namespace Sci
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 6752ba3e56..905cba9d94 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -169,7 +169,9 @@ int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) {
setScriptSize(scr, s, script_nr);
scr.buf = (byte *)malloc(scr.buf_size);
- dbgPrint("scr.buf ", scr.buf);
+#ifdef DEBUG_SEG_MANAGER
+ printf("scr.buf = %p ", scr.buf);
+#endif
if (!scr.buf) {
scr.freeScript();
warning("SegManager: Not enough memory space for script size");
@@ -864,14 +866,5 @@ int SegManager::freeDynmem(reg_t addr) {
return 0; // OK
}
-void SegManager::dbgPrint(const char* msg, void *i) {
-#ifdef DEBUG_SEG_MANAGER
- char buf[1000];
- sprintf(buf, "%s = [0x%x], dec:[%d]", msg, i, i);
- perror(buf);
-#endif
-}
-
-
} // End of namespace Sci
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index a41d820014..9d406f559f 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -362,13 +362,6 @@ private:
* 'seg' is a valid segment
*/
bool check(SegmentId seg);
-
- void dbgPrint(const char* msg, void *i); // for debug only
-
- // Perform garbage collection
- // Parameters: (EngineState *) s: The state to operate on
- // Effects : Unreachable objects in 's' are deallocated
- //void sm_gc(EngineState *s);
};
} // End of namespace Sci
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 99b5a86e53..0f8fee0876 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -258,6 +258,7 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP
if (bp->type == BREAK_EXPORT && bp->data.address == bpaddress) {
Console *con = ((SciEngine *)g_engine)->getSciDebugger();
con->DebugPrintf("Break on script %d, export %d\n", script, pubfunct);
+ scriptState.debugging = true;
breakpointFlag = true;
break;
}
@@ -325,6 +326,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt
con->DebugPrintf("Break on %s (in [%04x:%04x])\n", method_name, PRINT_REG(send_obj));
print_send_action = 1;
breakpointFlag = true;
+ scriptState.debugging = true;
break;
}
bp = bp->next;
@@ -652,17 +654,19 @@ void run_vm(EngineState *s, int restoring) {
}
- if (script_abort_flag)
+ if (script_abort_flag || g_engine->shouldQuit())
return; // Emergency
-// TODO: re-enable this
-#if 0
// Debug if this has been requested:
- if (script_debug_flag || sci_debug_flags) {
+ // TODO: re-implement sci_debug_flags
+ if (scriptState.debugging /* sci_debug_flags*/) {
script_debug(s, breakpointFlag);
breakpointFlag = false;
}
-#endif
+ Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
+ if (con->isAttached()) {
+ con->onFrame();
+ }
#ifndef DISABLE_VALIDATIONS
if (scriptState.xs->sp < scriptState.xs->fp)
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index f711570d11..ba225a9c00 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -266,18 +266,19 @@ struct ExecStack {
};
+// These types are used both as identifiers and as elements of bitfields
enum BreakpointType {
/**
* Break when selector is executed. data contains (char *) selector name
* (in the format Object::Method)
*/
- BREAK_SELECTOR,
+ BREAK_SELECTOR = 1,
/**
* Break when an exported function is called. data contains
* script_no << 16 | export_no.
*/
- BREAK_EXPORT
+ BREAK_EXPORT = 2
};
struct Breakpoint {
diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp
index 5604166794..b3a1be68d1 100644
--- a/engines/sci/gfx/operations.cpp
+++ b/engines/sci/gfx/operations.cpp
@@ -1383,7 +1383,6 @@ static sci_event_t scummvm_get_event(GfxDriver *drv) {
// Open debug console
Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
con->attach();
- con->onFrame();
// Clear keyboard event
input.type = SCI_EVT_NONE;
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index d99f9f0771..943361332f 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -882,7 +882,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType restype,
if (resnumber == -1)
return;
if (!file.open(source->location_name)) {
- perror("""__FILE__"": (""__LINE__""): failed to open");
+ warning("ResourceManager::processPatch(): failed to open %s", source->location_name.c_str());
return;
}
fsize = file.size();
@@ -1007,8 +1007,7 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) {
offset = file.readUint32LE();
if (file.ioFailed()) {
- warning("Error while reading %s: ", map->location_name.c_str());
- perror("");
+ warning("Error while reading %s", map->location_name.c_str());
return SCI_ERROR_RESMAP_NOT_FOUND;
}
if (offset == 0xFFFFFFFF)
@@ -1079,8 +1078,7 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
}
}
if (file.ioFailed()) {
- warning("Error while reading %s: ", map->location_name.c_str());
- perror("");
+ warning("Error while reading %s", map->location_name.c_str());
return SCI_ERROR_RESMAP_NOT_FOUND;
}
resId = ResourceId((ResourceType)type, number);
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index af8aac3147..3e434e4f02 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -289,9 +289,7 @@ uint32 SciEngine::getFlags() const {
}
Common::String SciEngine::getSavegameName(int nr) const {
- char extension[6];
- snprintf(extension, sizeof(extension), ".%03d", nr);
- return _targetName + extension;
+ return _targetName + Common::String::printf(".%03d", nr);
}
Common::String SciEngine::getSavegamePattern() const {
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 52866279b8..227ae1d316 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -527,9 +527,15 @@ void Actor_v2::walkActor() {
if (_moving & MF_TURN) {
new_dir = updateActorDirection(false);
// FIXME: is this correct?
- if (_facing != new_dir)
+ 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;
}
@@ -817,6 +823,16 @@ 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) {
@@ -1224,7 +1240,10 @@ void Actor::showActor() {
_vm->ensureResourceLoaded(rtCostume, _costume);
- if (_vm->_game.version <= 2) {
+ if (_vm->_game.version == 0) {
+ _cost.reset();
+ startAnimActor(_standFrame);
+ } else if (_vm->_game.version <= 2) {
_cost.reset();
startAnimActor(_standFrame);
startAnimActor(_initFrame);
@@ -1380,6 +1399,13 @@ void ScummEngine::processActors() {
Actor** end = _sortedActors + numactors;
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;
+ }
// Draw and animate the actors, except those w/o a costume.
// Note: We could 'optimize' this a little bit by only putting
// actors with a costume into the _sortedActors array in the
@@ -1572,6 +1598,8 @@ void Actor_v2::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
// we need to shift it 8 pixels to the left
if (_facing == 90)
bcr->_actorX -= 8;
+ } else if (_vm->_game.version == 0) {
+ bcr->_actorX += 12;
} else if (_vm->_game.version <= 2) {
// HACK: We have to adjust the x position by one strip (8 pixels) in
// V2 games. However, it is not quite clear to me why. And to fully
@@ -1703,6 +1731,12 @@ void Actor::animateActor(int anim) {
case 4: // turn to new direction
turnToDirection(dir);
break;
+ case 64:
+ if (_vm->_game.version == 0) {
+ _moving &= ~MF_TURN;
+ setDirection(dir);
+ break;
+ }
default:
if (_vm->_game.version <= 2)
startAnimActor(anim / 4);
@@ -2167,21 +2201,38 @@ void Actor::setActorCostume(int c) {
}
}
-static const char* v0ActorNames[7] = {
+static const char* v0ActorNames[0x19] = {
"Syd",
"Razor",
"Dave",
"Michael",
"Bernard",
"Wendy",
- "Jeff"
+ "Jeff",
+ "",
+ "Dr Fred",
+ "Nurse Edna",
+ "Weird Ed",
+ "Dead Cousin Ted",
+ "Purple Tentacle",
+ "Green Tentacle",
+ "Meteor",
+ "Plant",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Sandy"
};
const byte *Actor::getActorName() {
- const byte *ptr;
+ const byte *ptr = NULL;
if (_vm->_game.version == 0) {
- ptr = (const byte *)v0ActorNames[_number - 1];
+ if (_number)
+ ptr = (const byte *)v0ActorNames[_number - 1];
} else {
ptr = _vm->getResourceAddress(rtActorName, _number);
}
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index d32f268b11..c3edd24a39 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -380,11 +380,15 @@ protected:
class ActorC64 : public Actor_v2 {
public:
- // FIXME: This flag is never saved, which might lead to broken save states.
+ // FIXME: These vars are never saved, which might lead to broken save states.
byte _miscflags;
+ byte _speaking, _speakingPrev;
+ byte _costCommand, _costFrame;
public:
- ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
+ ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {
+ _speaking = _speakingPrev = _costCommand = _costFrame = 0;
+ }
virtual void initActor(int mode) {
Actor_v2::initActor(mode);
if (mode == -1) {
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 472e04b5f3..d480209501 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -445,7 +445,7 @@ byte ScummEngine::getNumBoxes() {
return 0;
if (_game.version == 8)
return (byte)READ_LE_UINT32(ptr);
- else if (_game.features >= 5)
+ else if (_game.version >= 5)
return (byte)READ_LE_UINT16(ptr);
else
return ptr[0];
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp
index 39c2f73e88..6923c27b38 100644
--- a/engines/scumm/costume.cpp
+++ b/engines/scumm/costume.cpp
@@ -1043,26 +1043,25 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
if (limb >= 8)
return 0;
+ if (a->_cost.start[limb] == 0xFFFF)
+ 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)
+ return 0;
- // TODO:
- // get out how animations are handled
- byte state = a->_moving != 0 ? 0 : 1;
- byte unk1 = (_loaded._animCmds + (state*32) + newDirToOldDir(a->getFacing()) * 8)[limb];
- byte unk2 = _loaded._frameOffsets[_loaded._frameOffsets[limb] + (unk1 & 0x7f)];
- bool flipped = (unk1 & 0x80) != 0;
-
- byte p1 = _loaded._frameOffsets[unk2];
- byte temp1 = _loaded._baseptr[p1];
- byte temp2 = temp1 + _loaded._dataOffsets[4];
- int offL = _loaded._baseptr[temp1 + 2];
- int offH = _loaded._baseptr[temp2];
- int off = (offH << 8) + offL;
+ byte ptrLow = _loaded._baseptr[frame];
+ byte ptrHigh = ptrLow + _loaded._dataOffsets[4];
+ int frameOffset = (_loaded._baseptr[ptrHigh] << 8) + _loaded._baseptr[ptrLow + 2]; // 0x23EF / 0x2400
- const byte *data = _loaded._baseptr + off;
+ const byte *data = _loaded._baseptr + frameOffset;
// Set up the palette data
byte palette[4] = { 0, 0, 0, 0 };
@@ -1080,8 +1079,8 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
int offsetY = *data++;
// these two fields seems to be most times zero
// byte6 was one time 255 in one costume I tried
-// int byte5 = *data++;
-// int byte6 = *data++;
+// int byte5 = *data++; // 0x1F80 // This value is never used
+// int byte6 = *data++; // 0x1F86 // This value is subtracted from ?actor drawy? at 0x2383
// debug(3, "byte5: %d", byte5);
// debug(3, "byte6: %d", byte6);
data += 2;
@@ -1094,17 +1093,13 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
if (flipped) {
if (offsetX)
- xpos += (offsetX-1) * 8;
+ xpos += (offsetX - 1) * 8;
} else {
xpos += offsetX * 8;
}
- // + 4 could be commented, because maybe the _actorX position is
- // wrong, I looked at the scumm-c64 interpreter by lloyd
- // and there Bernhard is directly on the right in the intro
- // but here in ScummVM he is 4 pixel left of the other position.
- xpos += _actorX - (a->_width / 2) + 4;
- ypos += _actorY - _loaded._maxHeight;
+ xpos += _actorX - (a->_width / 2);
+ ypos += (_actorY - _loaded._maxHeight) + 1; // +1 as we appear to be 1 pixel away from the original interpreter
// This code is very similar to procC64()
for (int y = 0; y < height; ++y) {
@@ -1114,9 +1109,9 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
int realX = 0;
if (flipped) {
if (offsetX == 0||offsetX == 1) {
- realX = width-(x+1);
+ realX = width-(x + 1);
} else if (offsetX == 2) {
- realX = width-(x+2);
+ realX = width-(x + 2);
}
} else {
realX = x;
@@ -1137,10 +1132,8 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
}
_draw_top = MIN(_draw_top, ypos);
- _draw_bottom = MAX(_draw_bottom, ypos+height);
- // if +4 above is NOT commented, here "+(flipped ? 4 : 0)" can be commented out
- // and other way round
- _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos+(width*8)/*+(flipped ? 4 : 0)*/, ypos, ypos+height, _actorID);
+ _draw_bottom = MAX(_draw_bottom, ypos + height);
+ _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos + (width * 8), ypos, ypos + height, _actorID);
return 0;
}
@@ -1154,6 +1147,7 @@ void C64CostumeRenderer::setCostume(int costume, int shadow) {
void C64CostumeLoader::loadCostume(int id) {
const byte *ptr = _vm->getResourceAddress(rtCostume, id);
+
_id = id;
_baseptr = ptr + 9;
@@ -1168,33 +1162,152 @@ void C64CostumeLoader::loadCostume(int id) {
_animCmds = _baseptr + READ_LE_UINT16(ptr + 7);
_maxHeight = 0;
- for (int i = 0; i < 8; ++i) {
- int pid = _frameOffsets[_frameOffsets[i]];
- byte p1 = _frameOffsets[pid];
- byte b = _baseptr[p1];
- byte c = b + _dataOffsets[4];
- int offL = _baseptr[b + 2];
- int offH = _baseptr[c];
- int off = (offH << 8) + offL;
- const byte *data = _baseptr + off;
-
- if (data[3] > _maxHeight) {
- _maxHeight = data[3]; // data[3] is libs's Y offset
+}
+
+void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) {
+ byte limbFrames = 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;
+
+ // Has limb frames ptr changed since last update?
+ if (a->_cost.start[limb] == limbFrames)
+ continue;
+
+ // Set new limb command addresses
+ a->_cost.start[limb] = limbFrames;
+ a->_cost.frame[limb] = _frameOffsets[limb] + (limbFrames & 0x7f); // limb animation-frames ptr
+
+ // Get first entry of a limbs' frames
+ byte frameStart = _frameOffsets[ a->_cost.frame[limb]];
+
+ // 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];
+
+ // Each animation-frame until we find end
+ if (frame == 0xFF)
+ break;
+
+ byte ptrLow = _baseptr[frame];
+ byte ptrHigh = ptrLow + _dataOffsets[4];
+ int frameOffset = (_baseptr[ptrHigh] << 8) + _baseptr[ptrLow + 2]; // 0x23EF / 0x2400
+
+ const byte *data = _baseptr + frameOffset;
+
+ if (data[3] > _maxHeight)
+ _maxHeight = data[3] + 1;
+
+ ++pos;
}
+
+ // Set ending position of limb frames
+ a->_cost.end[limb] = pos - 1;
+ a->_cost.curpos[limb] = 0;
}
- ++_maxHeight;
}
-void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
+// 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
+ }
+ // shouldnt' be reached
+ return 4;
}
-byte C64CostumeLoader::increaseAnims(Actor *a) {
- return 0;
+void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) {
+ if ((a->_speaking & 0x80))
+ cmd += 0x0C;
+ else
+ cmd += 0x10;
}
-byte C64CostumeLoader::increaseAnim(Actor *a, int slot) {
- return 0;
+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) {
+ A->_speaking = 1;
+ return;
+ }
+ if (frame == a->_talkStopFrame) {
+ A->_speaking = 0;
+ return;
+ }
+
+ // 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;
+
+ // Update 'speaking' frames?
+ if (A->_speaking) {
+ command = dir; // Incase standing frame was set as cmd
+ actorSpeak(A, command);
+
+ // Update the limb speak frames
+ frameUpdate(A, command);
+ }
}
+byte C64CostumeLoader::increaseAnims(Actor *a) {
+ ActorC64 *A = (ActorC64 *)a;
+
+ // 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;
+
+ // Update to use speak frame
+ if (A->_speaking & 0x80) {
+ actorSpeak(A, cmd);
+
+ } else {
+ // Update to use stand frame
+ if (A->_costFrame == A->_standFrame)
+ cmd = dirToDirStop(cmd);
+ }
+
+ // Update the limb frames
+ frameUpdate(A, cmd);
+ }
+
+ // 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
+ a->_cost.curpos[limb] = 0;
+ }
+
+ return 1;
+}
} // End of namespace Scumm
diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h
index ecb12986cf..929eb8c451 100644
--- a/engines/scumm/costume.h
+++ b/engines/scumm/costume.h
@@ -79,8 +79,12 @@ public:
byte increaseAnims(Actor *a);
int _maxHeight;
+
protected:
- byte increaseAnim(Actor *a, int slot);
+ void actorSpeak(ActorC64 *a, int &cmd);
+ int dirToDirStop(int oldDir);
+ void frameUpdate(ActorC64 *A, int cmd);
+
};
class ClassicCostumeRenderer : public BaseCostumeRenderer {
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 5fa74d22c3..8beb2ef720 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -723,6 +723,32 @@ GameDescriptor ScummMetaEngine::findGame(const char *gameid) const {
return AdvancedDetector::findGameID(gameid, gameDescriptions, obsoleteGameIDsTable);
}
+static Common::String generatePreferredTarget(const DetectorResult &x) {
+ Common::String res(x.game.gameid);
+
+ if (x.game.preferredTag) {
+ res = res + "-" + x.game.preferredTag;
+ }
+
+ if (x.game.features & GF_DEMO) {
+ res = res + "-demo";
+ }
+
+ // Append the platform, if a non-standard one has been specified.
+ if (x.game.platform != Common::kPlatformPC && x.game.platform != Common::kPlatformUnknown) {
+ // HACK: For CoMI, it's pointless to encode the fact that it's for Windows
+ if (x.game.id != GID_CMI)
+ res = res + "-" + Common::getPlatformAbbrev(x.game.platform);
+ }
+
+ // Append the language, if a non-standard one has been specified
+ if (x.language != Common::EN_ANY && x.language != Common::UNK_LANG) {
+ res = res + "-" + Common::getLanguageCode(x.language);
+ }
+
+ return res;
+}
+
GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
GameList detectedGames;
Common::List<DetectorResult> results;
@@ -737,34 +763,34 @@ GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
const PlainGameDescriptor *g = findPlainGameDescriptor(x->game.gameid, gameDescriptions);
assert(g);
GameDescriptor dg(x->game.gameid, g->description, x->language, x->game.platform);
- dg.updateDesc(x->extra); // Append additional information, if set, to the description.
+
+ // Append additional information, if set, to the description.
+ dg.updateDesc(x->extra);
// Compute and set the preferred target name for this game.
// Based on generateComplexID() in advancedDetector.cpp.
- Common::String res(x->game.gameid);
-
- if (x->game.preferredTag) {
- res = res + "-" + x->game.preferredTag;
- }
-
- if (x->game.features & GF_DEMO) {
- res = res + "-demo";
- }
-
- // Append the platform, if a non-standard one has been specified.
- if (x->game.platform != Common::kPlatformPC && x->game.platform != Common::kPlatformUnknown) {
- // HACK: For CoMI, it's pointless to encode the fact that it's for Windows
- if (x->game.id != GID_CMI)
- res = res + "-" + Common::getPlatformAbbrev(x->game.platform);
- }
-
- // Append the language, if a non-standard one has been specified
- if (x->language != Common::EN_ANY && x->language != Common::UNK_LANG) {
- res = res + "-" + Common::getLanguageCode(x->language);
+ 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["preferredtarget"] = res;
-
dg.setGUIOptions(x->game.guioptions);
detectedGames.push_back(dg);
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 92024a21cc..5054bffd30 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -230,14 +230,14 @@ static const GameSettings gameVariantsTable[] = {
{"monkey2", 0, 0, GID_MONKEY2, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH},
- {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH},
- {"atlantis", "CD" , 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NONE},
+ {"atlantis", "" , 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NONE},
+ {"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH},
- {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
- {"tentacle", "CD", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
- {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
- {"samnmax", "CD", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
#ifdef ENABLE_SCUMM_7_8
{"ft", 0, 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO_NOMIDI},
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index 880fab04a5..42e49afcc1 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -439,7 +439,7 @@ ScummMenuDialog::ScummMenuDialog(ScummEngine *scumm)
new GUI::ButtonWidget(this, "ScummMain.Resume", "Resume", kPlayCmd, 'P');
new GUI::ButtonWidget(this, "ScummMain.Load", "Load", kLoadCmd, 'L');
- new GUI::ButtonWidget(this, "ScummMain.Save", "Save", kSaveCmd, 'S');
+ _saveButton = new GUI::ButtonWidget(this, "ScummMain.Save", "Save", kSaveCmd, 'S');
new GUI::ButtonWidget(this, "ScummMain.Options", "Options", kOptionsCmd, 'O');
#ifndef DISABLE_HELP
@@ -471,6 +471,13 @@ ScummMenuDialog::~ScummMenuDialog() {
delete _loadDialog;
}
+void ScummMenuDialog::reflowLayout() {
+ if (!_vm->canSaveGameStateCurrently())
+ _saveButton->setEnabled(false);
+
+ Dialog::reflowLayout();
+}
+
void ScummMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kSaveCmd:
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index af844272fa..d4ecbde534 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -88,6 +88,8 @@ public:
~ScummMenuDialog();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+ virtual void reflowLayout();
+
protected:
ScummEngine *_vm;
@@ -99,6 +101,8 @@ protected:
SaveLoadChooser *_saveDialog;
SaveLoadChooser *_loadDialog;
+ GUI::ButtonWidget *_saveButton;
+
void save();
void load();
};
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 3f101691c7..6dc31b09ef 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -126,7 +126,7 @@ bool ScummFile::openSubFile(const Common::String &filename) {
bool ScummFile::eos() const {
- return _subFileLen ? (pos() >= _subFileLen) : File::eos(); // FIXME
+ return _subFileLen ? _myEos : File::eos();
}
int32 ScummFile::pos() const {
@@ -154,7 +154,10 @@ bool ScummFile::seek(int32 offs, int whence) {
assert((int32)_subFileStart <= offs && offs <= (int32)(_subFileStart + _subFileLen));
whence = SEEK_SET;
}
- return File::seek(offs, whence);
+ bool ret = File::seek(offs, whence);
+ if (ret)
+ _myEos = false;
+ return ret;
}
uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
@@ -167,7 +170,7 @@ uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
int32 newPos = curPos + dataSize;
if (newPos > _subFileLen) {
dataSize = _subFileLen - curPos;
- _myIoFailed = true;
+ _myEos = true;
}
}
diff --git a/engines/scumm/file.h b/engines/scumm/file.h
index aa52dd069f..c37c2f036e 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -55,7 +55,7 @@ private:
byte _encbyte;
int32 _subFileStart;
int32 _subFileLen;
- bool _myIoFailed;
+ bool _myEos; // Have we read past the end of the subfile?
void setSubfileRange(int32 start, int32 len);
void resetSubfile();
@@ -67,8 +67,7 @@ public:
bool open(const Common::String &filename);
bool openSubFile(const Common::String &filename);
- bool ioFailed() const { return _myIoFailed || BaseScummFile::ioFailed(); }
- void clearIOFailed() { _myIoFailed = false; BaseScummFile::clearIOFailed(); }
+ void clearErr() { _myEos = false; BaseScummFile::clearErr(); }
bool eos() const;
int32 pos() const;
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index a54199272f..3839a75261 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -774,18 +774,18 @@ void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *wid
}
void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
- byte *dstL1 = dst;
- byte *dstL2 = dst + dstPitch;
+ uint16 *dstL1 = (uint16 *)dst;
+ uint16 *dstL2 = (uint16 *)(dst + dstPitch);
- int dstAdd = dstPitch * 2 - w * 2;
- int srcAdd = srcPitch - w;
+ const int dstAdd = dstPitch - w;
+ const int srcAdd = srcPitch - w;
while (h--) {
- for (int x = 0; x < w; ++x, dstL1 += 2, dstL2 += 2) {
+ for (int x = 0; x < w; ++x) {
uint16 col = *src++;
col |= col << 8;
- *(uint16*)(dstL1) = col;
- *(uint16*)(dstL2) = col;
+ *dstL1++ = col;
+ *dstL2++ = col;
}
dstL1 += dstAdd; dstL2 += dstAdd;
src += srcAdd;
diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp
index 51176c5df9..39615edb6a 100644
--- a/engines/scumm/he/cup_player_he.cpp
+++ b/engines/scumm/he/cup_player_he.cpp
@@ -91,20 +91,19 @@ void CUP_Player::close() {
}
void CUP_Player::play() {
- while (parseNextHeaderTag(_fileStream)) {
- if (_fileStream.ioFailed()) {
- return;
- }
- }
+ while (parseNextHeaderTag(_fileStream)) { }
+
+ if (_fileStream.eos() || _fileStream.err())
+ return;
+
debug(1, "rate %d width %d height %d", _playbackRate, _width, _height);
int ticks = _system->getMillis();
while (_dataSize != 0 && !_vm->shouldQuit()) {
- while (parseNextBlockTag(_fileStream)) {
- if (_fileStream.ioFailed()) {
- return;
- }
- }
+ while (parseNextBlockTag(_fileStream)) { }
+ if (_fileStream.eos() || _fileStream.err())
+ return;
+
int diff = _system->getMillis() - ticks;
if (diff >= 0 && diff <= _playbackRate) {
_system->delayMillis(_playbackRate - diff);
@@ -200,6 +199,10 @@ void CUP_Player::waitForSfxChannel(int channel) {
bool CUP_Player::parseNextHeaderTag(Common::SeekableReadStream &dataStream) {
uint32 tag = dataStream.readUint32BE();
uint32 size = dataStream.readUint32BE() - 8;
+
+ if (dataStream.eos())
+ return false;
+
uint32 next = dataStream.pos() + size;
debug(1, "New header tag %s %d dataSize %d", tag2str(tag), size, _dataSize);
switch (tag) {
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index 8aa8a8d3f5..2f7f539ee3 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -78,7 +78,7 @@ protected:
int virtScreenSave(byte *dst, int x1, int y1, int x2, int y2);
void virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2);
- int convertFilePath(byte *dst);
+ int convertFilePath(byte *dst, int dstSize);
virtual void decodeParseString(int a, int b);
void swapObjects(int object1, int object2);
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 58a858ede4..2748633bdc 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -1624,7 +1624,7 @@ void ScummEngine_v100he::o100_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer));
- r = convertFilePath(buffer);
+ r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o100_roomOps: case 137: filename %s", _saveLoadFileName);
@@ -2243,7 +2243,7 @@ void ScummEngine_v100he::o100_videoOps() {
if (_videoParams.flags == 0)
_videoParams.flags = 4;
- const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename);
+ const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags == 2) {
VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
} else {
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index b416a0e75d..79b589df00 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -93,7 +93,7 @@ void ScummEngine_v60he::setupOpcodes() {
_opcodes[0xed].setProc(0, 0);
}
-int ScummEngine_v60he::convertFilePath(byte *dst) {
+int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) {
debug(1, "convertFilePath: original filePath is %s", dst);
int len = resStrLen(dst);
@@ -113,18 +113,27 @@ int ScummEngine_v60he::convertFilePath(byte *dst) {
// Strip path
int r = 0;
- if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
+ if (dst[len - 3] == 's' && dst[len - 2] == 'g') { // Save Game File
+ // Change filename prefix to target name, for save game files.
+ char saveName[20];
+ sprintf(saveName, "%s.sg%c", _targetName.c_str(), dst[len - 1]);
+ memcpy(dst, saveName, 20);
+ } else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
+ // The default game data path is set to './' by ScummVM
r = 2;
} else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI
r = 13;
} else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (HE72 - HE100)
+ // The default save game path is set to '*/' by ScummVM
r = 2;
} else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71)
+ // The default save path is game path (DOS) or 'c:/hegames/' (Windows)
for (r = len; r != 0; r--) {
if (dst[r - 1] == '/')
break;
}
} else if (dst[0] == 'u' && dst[1] == 's') { // Save Game Path (Moonbase Commander)
+ // The default save path is 'user/'
r = 5;
}
@@ -271,7 +280,7 @@ void ScummEngine_v60he::o60_roomOps() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- r = convertFilePath(buffer);
+ r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o60_roomOps: case 221: filename %s", _saveLoadFileName);
@@ -686,7 +695,7 @@ void ScummEngine_v60he::o60_openFile() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- filename = (char *)buffer + convertFilePath(buffer);
+ filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "Final filename to %s", filename);
mode = pop();
@@ -740,7 +749,7 @@ void ScummEngine_v60he::o60_deleteFile() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- filename = (char *)buffer + convertFilePath(buffer);
+ filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "o60_deleteFile (\"%s\")", filename);
@@ -762,8 +771,8 @@ void ScummEngine_v60he::o60_rename() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- oldFilename = (char *)buffer1 + convertFilePath(buffer1);
- newFilename = (char *)buffer2 + convertFilePath(buffer2);
+ oldFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
+ newFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
debug(1, "o60_rename (\"%s\" to \"%s\")", oldFilename, newFilename);
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 9d5bd0b23d..c6489004d7 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -713,7 +713,7 @@ void ScummEngine_v72he::o72_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer));
- r = convertFilePath(buffer);
+ r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o72_roomOps: case 221: filename %s", _saveLoadFileName);
@@ -1401,7 +1401,7 @@ void ScummEngine_v72he::o72_openFile() {
strcpy((char *)buffer, "moonbase.ini");
}
- const char *filename = (char *)buffer + convertFilePath(buffer);
+ const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "Final filename to %s", filename);
slot = -1;
@@ -1548,7 +1548,7 @@ void ScummEngine_v72he::o72_deleteFile() {
byte buffer[256];
copyScriptString(buffer, sizeof(buffer));
- const char *filename = (char *)buffer + convertFilePath(buffer);
+ const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "o72_deleteFile(%s)", filename);
@@ -1563,8 +1563,8 @@ void ScummEngine_v72he::o72_rename() {
copyScriptString(buffer1, sizeof(buffer1));
copyScriptString(buffer2, sizeof(buffer2));
- const char *newFilename = (char *)buffer1 + convertFilePath(buffer1);
- const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2);
+ const char *newFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
+ const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
_saveFileMan->renameSavefile(oldFilename, newFilename);
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index 4b759dec53..fb63568e9f 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -89,7 +89,7 @@ void ScummEngine_v80he::o80_getFileSize() {
byte buffer[256];
copyScriptString(buffer, sizeof(buffer));
- const char *filename = (char *)buffer + convertFilePath(buffer);
+ const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
Common::SeekableReadStream *f = 0;
if (!_saveFileMan->listSavefiles(filename).empty()) {
@@ -154,7 +154,7 @@ void ScummEngine_v80he::o80_readConfigFile() {
copyScriptString(section, sizeof(section));
copyScriptString(filename, sizeof(filename));
- r = convertFilePath(filename);
+ r = convertFilePath(filename, sizeof(filename));
if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters
@@ -222,7 +222,7 @@ void ScummEngine_v80he::o80_writeConfigFile() {
error("o80_writeConfigFile: default type %d", subOp);
}
- r = convertFilePath(filename);
+ r = convertFilePath(filename, sizeof(filename));
if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 7a7a1ff58b..8c50dfecc3 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -1427,7 +1427,7 @@ void ScummEngine_v90he::o90_videoOps() {
if (_videoParams.flags == 0)
_videoParams.flags = 4;
- const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename);
+ const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags & 2) {
VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
} else {
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index a6dab366ee..b79c35740e 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -2345,7 +2345,7 @@ void Wiz::processWizImage(const WizParameters *params) {
if (params->processFlags & kWPFUseFile) {
Common::SeekableReadStream *f = NULL;
memcpy(buffer, params->filename, 260);
- const char *filename = (char *)buffer + _vm->convertFilePath(buffer);
+ const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer));
if (!_vm->_saveFileMan->listSavefiles(filename).empty()) {
f = _vm->_saveFileMan->openForLoading(filename);
@@ -2390,7 +2390,7 @@ void Wiz::processWizImage(const WizParameters *params) {
if (params->processFlags & kWPFUseFile) {
Common::OutSaveFile *f;
memcpy(buffer, params->filename, 260);
- const char *filename = (char *)buffer + _vm->convertFilePath(buffer);
+ const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer));
switch (params->fileWriteMode) {
case 2:
diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
index 4577a11fe1..be5f7623ca 100644
--- a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
@@ -225,7 +225,7 @@ bool BundleMgr::loadCompTable(int32 index) {
_file->seek(8, SEEK_CUR);
if (tag != MKID_BE('COMP')) {
- error("BundleMgr::loadCompTable() Compressed sound %d invalid (%s)", index, tag2str(tag));
+ error("BundleMgr::loadCompTable() Compressed sound %d (%s:%d) invalid (%s)", index, _file->getName(), _bundleTable[index].offset, tag2str(tag));
return false;
}
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 61b714a3e2..ab32992b03 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -110,9 +110,9 @@ void ScummEngine_v80he::parseEvent(Common::Event event) {
void ScummEngine::parseEvent(Common::Event event) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9'
- && (event.kbd.flags == Common::KBD_ALT ||
- event.kbd.flags == Common::KBD_CTRL)) {
+ if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9' &&
+ ((event.kbd.flags == Common::KBD_ALT && canSaveGameStateCurrently()) ||
+ (event.kbd.flags == Common::KBD_CTRL && canLoadGameStateCurrently()))) {
_saveLoadSlot = event.kbd.keycode - '0';
// don't overwrite autosave (slot 0)
@@ -302,17 +302,6 @@ void ScummEngine::processInput() {
//
_mouseAndKeyboardStat = 0;
- // Interpret 'return' as left click and 'tab' as right click
- if (lastKeyHit.keycode && _cursor.state > 0) {
- if (lastKeyHit.keycode == Common::KEYCODE_TAB) {
- _mouseAndKeyboardStat = MBS_RIGHT_CLICK;
- lastKeyHit.reset();
- } else if (lastKeyHit.keycode == Common::KEYCODE_RETURN) {
- _mouseAndKeyboardStat = MBS_LEFT_CLICK;
- lastKeyHit.reset();
- }
- }
-
if ((_leftBtnPressed & msClicked) && (_rightBtnPressed & msClicked) && _game.version >= 4) {
// Pressing both mouse buttons is treated as if you pressed
// the cutscene exit key (ESC) in V4+ games. That mimicks
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index f29be071e0..2eab2cfa3a 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -181,7 +181,11 @@ 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) {
- assert(WIO_INVENTORY == whereIsObject(obj));
+ if (_game.version == 0)
+ assert(WIO_INVENTORY == whereIsObjectInventory(obj));
+ else
+ assert(WIO_INVENTORY == whereIsObject(obj));
+
// Found the object! Nuke it from the inventory.
_res->nukeResource(rtInventory, i);
_inventory[i] = 0;
@@ -286,7 +290,7 @@ int ScummEngine::getState(int obj) {
// it. Fortunately this does not prevent frustrated players from
// blowing up the mansion, should they feel the urge to.
- if (_game.id == GID_MANIAC && (obj == 182 || obj == 193))
+ if (_game.id == GID_MANIAC && _game.version != 0 && (obj == 182 || obj == 193))
_objectStateTable[obj] |= kObjectState_08;
}
@@ -317,6 +321,15 @@ int ScummEngine::getObjectIndex(int object) const {
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;
@@ -326,7 +339,7 @@ int ScummEngine::whereIsObject(int object) const {
if (object < 1)
return WIO_NOT_FOUND;
- if (_objectOwnerTable[object] != OF_OWNER_ROOM) {
+ if ((_objectOwnerTable[object] != OF_OWNER_ROOM && _game.version != 0) || _v0ObjectInInventory) {
for (i = 0; i < _numInventory; i++)
if (_inventory[i] == object)
return WIO_INVENTORY;
@@ -334,7 +347,7 @@ int ScummEngine::whereIsObject(int object) const {
}
for (i = (_numLocalObjects-1); i > 0; i--)
- if (_objs[i].obj_nr == object) {
+ if ((_objs[i].obj_nr == object && !_v0ObjectIndex) || (_v0ObjectIndex && i == object)) {
if (_objs[i].fl_object_index)
return WIO_FLOBJECT;
return WIO_ROOM;
@@ -379,7 +392,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 = getObjectIndex(object);
+ int idx = (_v0ObjectIndex) ? object : getObjectIndex(object);
assert(idx >= 0);
ObjectData &od = _objs[idx];
int state;
@@ -434,7 +447,7 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
dir = oldDirToNewDir(od.actordir & 3);
}
-static int getDist(int x, int y, int x2, int y2) {
+int ScummEngine::getDist(int x, int y, int x2, int y2) {
int a = ABS(y - y2);
int b = ABS(x - x2);
return MAX(a, b);
@@ -475,6 +488,14 @@ 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;
@@ -504,8 +525,12 @@ 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)
- return _objs[i].obj_nr;
+ _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) {
+ if (_game.version == 0 && _v0ObjectIndex)
+ return i;
+ else
+ return _objs[i].obj_nr;
+ }
break;
}
} while ((_objs[b].state & mask) == a);
@@ -811,6 +836,9 @@ 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);
}
}
@@ -1033,6 +1061,10 @@ 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)
+ continue;
+
if (od->obj_nr > 0)
od->state = getState(od->obj_nr);
}
@@ -1155,7 +1187,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
void ScummEngine::setObjectName(int obj) {
int i;
- if (obj < _numActors)
+ if (obj < _numActors && _game.version != 0)
error("Can't set actor %d name with new-name-of", obj);
for (i = 0; i < _numNewNames; i++) {
@@ -1181,8 +1213,13 @@ void ScummEngine::setObjectName(int obj) {
uint32 ScummEngine::getOBCDOffs(int object) const {
int i;
- if (_objectOwnerTable[object] != OF_OWNER_ROOM)
+ if ((_objectOwnerTable[object] != OF_OWNER_ROOM && (_game.version != 0)) || _v0ObjectInInventory)
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)
@@ -1194,17 +1231,20 @@ uint32 ScummEngine::getOBCDOffs(int object) const {
}
byte *ScummEngine::getOBCDFromObject(int obj) {
+ bool useInventory = _v0ObjectInInventory;
int i;
byte *ptr;
- if (_objectOwnerTable[obj] != OF_OWNER_ROOM) {
+ _v0ObjectInInventory = false;
+
+ if ((_objectOwnerTable[obj] != OF_OWNER_ROOM && (_game.version != 0)) || useInventory) {
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) {
+ if ((_objs[i].obj_nr == obj && !_v0ObjectIndex) || (_v0ObjectIndex && i == obj)) {
if (_objs[i].fl_object_index) {
assert(_objs[i].OBCDoffset == 8);
ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index);
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 8359675032..d3faa15c10 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -229,7 +229,7 @@ void ScummEngine::askForDisk(const char *filename, int disknum) {
sprintf(buf, "Cannot find file: '%s'\nInsert disc %d into drive %s\nPress OK to retry, Quit to exit", filename, disknum, _gameDataDir.getPath().c_str());
#endif
- result = displayMessage("Quit", buf);
+ result = displayMessage("Quit", "%s", buf);
if (!result) {
error("Cannot find file: '%s'", filename);
}
@@ -253,10 +253,10 @@ void ScummEngine::readIndexFile() {
if (_game.version <= 5) {
// Figure out the sizes of various resources
- while (!_fileHandle->eos()) {
+ while (true) {
blocktype = _fileHandle->readUint32BE();
itemsize = _fileHandle->readUint32BE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
switch (blocktype) {
case MKID_BE('DOBJ'):
@@ -285,7 +285,6 @@ void ScummEngine::readIndexFile() {
}
_fileHandle->seek(itemsize - 8, SEEK_CUR);
}
- _fileHandle->clearIOFailed();
_fileHandle->seek(0, SEEK_SET);
}
@@ -300,7 +299,7 @@ void ScummEngine::readIndexFile() {
blocktype = _fileHandle->readUint32BE();
itemsize = _fileHandle->readUint32BE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
numblock++;
@@ -689,7 +688,7 @@ int ScummEngine::loadResource(int type, int idx) {
dumpResource("script-", idx, getResourceAddress(rtScript, idx));
}
- if (!_fileHandle->ioFailed()) {
+ if (!_fileHandle->err() && !_fileHandle->eos()) {
return 1;
}
diff --git a/engines/scumm/resource_v2.cpp b/engines/scumm/resource_v2.cpp
index 184f3d94df..e469c721b1 100644
--- a/engines/scumm/resource_v2.cpp
+++ b/engines/scumm/resource_v2.cpp
@@ -138,7 +138,7 @@ void ScummEngine_v2::readEnhancedIndexFile() {
_fileHandle->seek(_numScripts * 3, SEEK_CUR);
_numSounds = _fileHandle->readByte();
- _fileHandle->clearIOFailed();
+ _fileHandle->clearErr();
_fileHandle->seek(0, SEEK_SET);
readMAXS(0);
diff --git a/engines/scumm/resource_v3.cpp b/engines/scumm/resource_v3.cpp
index 420f71cf03..0728395055 100644
--- a/engines/scumm/resource_v3.cpp
+++ b/engines/scumm/resource_v3.cpp
@@ -80,7 +80,7 @@ void ScummEngine_v3old::readIndexFile() {
_fileHandle->seek(_numScripts * 3, SEEK_CUR);
_numSounds = _fileHandle->readByte();
- _fileHandle->clearIOFailed();
+ _fileHandle->clearErr();
_fileHandle->seek(0, SEEK_SET);
readMAXS(0);
diff --git a/engines/scumm/resource_v4.cpp b/engines/scumm/resource_v4.cpp
index 28e0fb05b5..75858f7b42 100644
--- a/engines/scumm/resource_v4.cpp
+++ b/engines/scumm/resource_v4.cpp
@@ -61,11 +61,11 @@ void ScummEngine_v4::readIndexFile() {
closeRoom();
openRoom(0);
- while (!_fileHandle->eos()) {
+ while (true) {
// Figure out the sizes of various resources
itemsize = _fileHandle->readUint32LE();
blocktype = _fileHandle->readUint16LE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
switch (blocktype) {
@@ -95,16 +95,15 @@ void ScummEngine_v4::readIndexFile() {
_fileHandle->seek(itemsize - 8, SEEK_CUR);
}
- _fileHandle->clearIOFailed();
_fileHandle->seek(0, SEEK_SET);
readMAXS(0);
allocateArrays();
- while (1) {
+ while (true) {
itemsize = _fileHandle->readUint32LE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
blocktype = _fileHandle->readUint16LE();
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 144de2f5f1..7bf61a8762 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -86,6 +86,19 @@ bool ScummEngine::canLoadGameStateCurrently() {
// FIXME: Actually, we might wish to support loading in more places.
// As long as we are sure it won't cause any problems... Are we
// aware of *any* spots where loading is not supported?
+
+ // HE games are limited to original load and save interface only,
+ // due to numerous glitches (see bug #1726909) that can occur.
+ if (_game.heversion >= 60)
+ return false;
+
+ // COMI always disables saving/loading (to tell the truth:
+ // the main menu) via its scripts, thus we need to make an
+ // exception here. This the same forced overwriting of the
+ // script decisions as in ScummEngine::processKeyboard.
+ if (_game.id == GID_CMI)
+ return true;
+
return (VAR_MAINMENU_KEY == 0xFF || VAR(VAR_MAINMENU_KEY) != 0);
}
@@ -99,7 +112,22 @@ bool ScummEngine::canSaveGameStateCurrently() {
// TODO: Should we disallow saving in some more places,
// e.g. when a SAN movie is playing? Not sure whether the
// original EXE allowed this.
- return (VAR_MAINMENU_KEY == 0xFF || VAR(VAR_MAINMENU_KEY) != 0);
+
+ // HE games are limited to original load and save interface only,
+ // due to numerous glitches (see bug #1726909) that can occur.
+ if (_game.heversion >= 60)
+ return false;
+
+ // COMI always disables saving/loading (to tell the truth:
+ // the main menu) via its scripts, thus we need to make an
+ // exception here. This the same forced overwriting of the
+ // script decisions as in ScummEngine::processKeyboard.
+ if (_game.id == GID_CMI)
+ return true;
+
+ // SCUMM v4+ doesn't allow saving in room 0 or if
+ // VAR(VAR_MAINMENU_KEY) to set to zero.
+ return (VAR_MAINMENU_KEY == 0xFF || (VAR(VAR_MAINMENU_KEY) != 0 && _currentRoom != 0));
}
@@ -1368,11 +1396,31 @@ void ScummEngine::saveOrLoad(Serializer *s) {
}
void ScummEngine_v0::saveOrLoad(Serializer *s) {
+ ScummEngine_v2::saveOrLoad(s);
+
+ const SaveLoadEntry v0Entrys[] = {
+ MKLINE(ScummEngine_v0, _currentMode, sleByte, VER(78)),
+ MKLINE(ScummEngine_v0, _currentLights, sleByte, VER(78)),
+ MKEND()
+ };
+ s->saveLoadEntries(this, v0Entrys);
+}
+
+
+void ScummEngine_v2::saveOrLoad(Serializer *s) {
ScummEngine::saveOrLoad(s);
- // TODO: Save additional variables
- // _currentMode
- // _currentLights
+ const SaveLoadEntry v2Entrys[] = {
+ MKLINE(ScummEngine_v2, _inventoryOffset, sleUint16, VER(79)),
+ MKEND()
+ };
+ s->saveLoadEntries(this, v2Entrys);
+
+ // In old saves we didn't store _inventoryOffset -> reset it to
+ // a sane default when loading one of those.
+ if (s->getVersion() < 79 && s->isLoading()) {
+ _inventoryOffset = 0;
+ }
}
void ScummEngine_v5::saveOrLoad(Serializer *s) {
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 49bfe39b21..4f6adc5570 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -50,7 +50,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 78
+#define CURRENT_VER 79
/**
* An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 4d9447bee5..2c3fe09db2 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -23,10 +23,9 @@
*
*/
-
-
#include "common/config-manager.h"
#include "common/util.h"
+#include "common/system.h"
#include "scumm/actor.h"
#include "scumm/object.h"
@@ -133,6 +132,8 @@ 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);
}
@@ -786,92 +787,65 @@ void ScummEngine::runInventoryScript(int i) {
}
void ScummEngine::inventoryScriptIndy3Mac() {
- VerbSlot *vs;
- int args[24];
- int j, slot;
+ int slot;
- memset(args, 0, sizeof(args));
+ // VAR(67) controls the scroll offset of the inventory in Indy3 for Macintosh.
+ // The inventory consists of two columns with three items visible in each,
+ // so a maximum of six items are visible at once.
- if (VAR(67) < 0) {
- VAR(67) = 0;
- }
- args[5] = getInventoryCount(VAR(VAR_EGO));
- if (args[5] <= 6) {
+ // The scroll offset must be non-negative and if there are six or less items
+ // in the inventory, the inventory is fixed in the top position.
+ const int invCount = getInventoryCount(VAR(VAR_EGO));
+ if (VAR(67) < 0 || invCount <= 6) {
VAR(67) = 0;
}
- if (args[5] >= 6) {
- args[5] -= 6;
- }
- args[6] = 0;
- if (VAR(67) >= args[5]) {
- VAR(67) = args[5];
- args[4] = args[5];
- args[5] /= 2;
- args[5] *= 2;
- args[4] -= args[5];
- if (args[4]) {
+
+ // If there are more than six items in the inventory, clamp the scroll position
+ // to be at most invCount-6, rounded up to the next even integer.
+ bool scrolledToBottom = false;
+ if (invCount > 6 && VAR(67) >= invCount - 6) {
+ VAR(67) = invCount - 6;
+ // Odd number of inventory items? -> increment VAR(67) to make it even
+ if (invCount & 1) {
VAR(67)++;
}
- args[6]++;
- }
- args[2] = 1;
- for (j = 1; j < 7; j++) {
- args[1] = (VAR(67) + args[2]);
- args[3] = findInventory(VAR(VAR_EGO),args[1]);
- VAR(82 + args[2]) = args[3];
- args[2]++;
+ scrolledToBottom = true;
}
- byte tmp[6];
-
- tmp[0] = 0xFF;
- tmp[1] = 0x06;
- tmp[3] = 0x00;
- tmp[4] = 0x00;
-
- for (j = 0; j < 6; j++) {
- tmp[2] = 0x53 + j;
-
- slot = getVerbSlot(101 + j, 0);
- vs = &_verbs[slot];
+ // Now update var 83 till 89 to contain the inventory IDs of the
+ // corresponding inventory slots.
+ // Also setup fake verbs for the inventory
+ byte tmp[6] = { 0xFF, 0x06, 0x52, 0x00, 0x00, 0x00 };
+ for (int j = 1; j < 7; j++) {
+ int tmpA = (VAR(67) + j);
+ int tmpB = findInventory(VAR(VAR_EGO), tmpA);
+ VAR(82 + j) = tmpB;
+
+ // Setup fake verb
+ tmp[2] = 0x52 + j;
+ slot = getVerbSlot(100 + j, 0);
loadPtrToResource(rtVerb, slot, tmp);
+
+ VerbSlot *vs = &_verbs[slot];
vs->type = kTextVerbType;
vs->imgindex = 0;
vs->curmode = 1;
drawVerb(slot, 0);
}
- args[5] = getInventoryCount(VAR(VAR_EGO));
- if (args[5] > 6) {
- slot = getVerbSlot(107, 0);
- if (VAR(67)) {
- vs = &_verbs[slot];
- vs->curmode = 1;
- } else {
- vs = &_verbs[slot];
- vs->curmode = 0;
- }
- drawVerb(slot, 0);
- slot = getVerbSlot(108, 0);
- if (!args[6]) {
- vs = &_verbs[slot];
- vs->curmode = 1;
- } else {
- vs = &_verbs[slot];
- vs->curmode = 0;
- }
- drawVerb(slot, 0);
- } else {
- slot = getVerbSlot(107, 0);
- vs = &_verbs[slot];
- vs->curmode = 0;
- drawVerb(slot, 0);
- slot = getVerbSlot(108, 0);
- vs = &_verbs[slot];
- vs->curmode = 0;
- drawVerb(slot, 0);
- }
+ // Enable up arrow if there are more than six items and we are not already
+ // scrolled all the way up.
+ slot = getVerbSlot(107, 0);
+ _verbs[slot].curmode = (invCount > 6 && VAR(67)) ? 1 : 0;
+ drawVerb(slot, 0);
+
+ // Enable down arrow if there are more than six items and we are not already
+ // scrolled all the way down.
+ slot = getVerbSlot(108, 0);
+ _verbs[slot].curmode = (invCount > 6 && !scrolledToBottom) ? 1 : 0;
+ drawVerb(slot, 0);
+ // Redraw!
verbMouseOver(0);
}
@@ -1204,7 +1178,7 @@ void ScummEngine::runInputScript(int clickArea, int val, int mode) {
args[4] = VAR(VAR_VIRT_MOUSE_Y);
}
- // Macintosh verison of indy3ega used different interface, so adjust values.
+ // Macintosh version of indy3ega used different interface, so adjust values.
if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh) {
if (clickArea == kVerbClickArea && (val >= 101 && val <= 108)) {
if (val == 107) {
@@ -1216,10 +1190,16 @@ void ScummEngine::runInputScript(int clickArea, int val, int mode) {
inventoryScriptIndy3Mac();
return;
} else {
- args[0] = 3;
- args[1] = VAR(83 + (val - 101));
+ args[0] = kInventoryClickArea;
+ args[1] = VAR(82 + (val - 100));
}
}
+
+ // Clicks are handled differently in Indy3 mac: param 2 of the
+ // input script is set to 0 for normal clicks, and to 1 for double clicks.
+ uint32 time = _system->getMillis();
+ args[2] = (time < _lastInputScriptTime + 500); // 500 ms double click delay
+ _lastInputScriptTime = time;
}
if (verbScript)
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 1b8368d636..873f2fa281 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -410,41 +410,43 @@ void ScummEngine_v0::decodeParseString() {
actorTalk(buffer);
}
-void ScummEngine_v0::drawSentence() {
- Common::Rect sentenceline;
+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;
- if (!(_userState & 32))
- return;
+ temp = getObjOrActorName(object);
- if (getResourceAddress(rtVerb, _activeVerb)) {
- strcpy(_sentenceBuf, (char*)getResourceAddress(rtVerb, _activeVerb));
- } else {
- return;
+ _v0ObjectInInventory = false;
+ _v0ObjectIndex = false;
+
+ // Append the 'object-name'
+ if (temp) {
+ strcat(_sentenceBuf, " ");
+ strcat(_sentenceBuf, (const char*)temp);
}
- if (_activeObject > 0) {
- temp = getObjOrActorName(_activeObject);
- if (temp) {
- strcat(_sentenceBuf, " ");
- strcat(_sentenceBuf, (const char*)temp);
- }
+ // Append the modifier? (With / On / To / In)
+ if (!usePrep)
+ return;
- if (_verbs[_activeVerb].prep == 0xFF) {
- byte *ptr = getOBCDFromObject(_activeObject);
- assert(ptr);
- sentencePrep = (*(ptr + 11) >> 5);
- } else {
- sentencePrep = _verbs[_activeVerb].prep;
- }
+ if (_verbs[_activeVerb].prep == 0xFF) {
+ _v0ObjectInInventory = objInInventory;
+ sentencePrep = verbPrep(object);
+ } else {
+ sentencePrep = _verbs[_activeVerb].prep;
}
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.
- const char *prepositions[][5] = {
+ static const char *prepositions[][5] = {
{ " ", " in", " with", " on", " to" }, // English
{ " ", " mit", " mit", " mit", " zu" }, // German
{ " ", " dans", " avec", " sur", " <" }, // French
@@ -471,13 +473,65 @@ void ScummEngine_v0::drawSentence() {
strcat(_sentenceBuf, prepositions[lang][sentencePrep]);
}
+}
+
+void ScummEngine_v0::drawSentence() {
+ Common::Rect sentenceline;
+ bool inventoryFirst = false;
+
+ if (!(_userState & 32))
+ return;
+
+ // Current Verb, Walk/Use
+ if (getResourceAddress(rtVerb, _activeVerb)) {
+ strcpy(_sentenceBuf, (char*)getResourceAddress(rtVerb, _activeVerb));
+ } else {
+ return;
+ }
- if (_activeInventory > 0) {
- temp = getObjOrActorName(_activeInventory);
- if (temp) {
- strcat(_sentenceBuf, " ");
- strcat(_sentenceBuf, (const char*)temp);
+ // 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);
+ }
+ }
+
+ // Draw the active actor
+ if (_activeActor) {
+ Actor *a = derefActor(_activeActor, "");
+
+ strcat(_sentenceBuf, " ");
+ strcat(_sentenceBuf, (const char*)a->getActorName());
}
_string[2].charset = 1;
@@ -664,9 +718,22 @@ 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);
- Actor *a = derefActor(act, "o_animateActor");
+ 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;
+ }
+
a->animateActor(anim);
}
@@ -713,9 +780,9 @@ void ScummEngine_v0::o_pickupObject() {
if (getObjectIndex(obj) == -1)
return;
- if (whereIsObject(obj) == WIO_INVENTORY) /* Don't take an */
+ if (whereIsObjectInventory(_activeObject2) == WIO_INVENTORY) /* Don't take an */
return; /* object twice */
-
+
addObjectToInventory(obj, _roomResource);
markObjectRectAsDirty(obj);
putOwner(obj, VAR(VAR_EGO));
@@ -738,8 +805,13 @@ void ScummEngine_v0::o_setActorBitVar() {
byte act = getVarOrDirectByte(PARAM_1);
byte mask = getVarOrDirectByte(PARAM_2);
byte mod = getVarOrDirectByte(PARAM_3);
+
+ // 0x63ED
+ if (act >= _numActors)
+ return;
ActorC64 *a = (ActorC64 *)derefActor(act, "o_setActorBitVar");
+
if (mod)
a->_miscflags |= mask;
else
@@ -900,10 +972,25 @@ void ScummEngine_v0::o_setOwnerOf() {
setOwnerOf(obj, owner);
}
-void ScummEngine_v0::resetSentence() {
- _activeInventory = 0;
- _activeObject = 0;
+void ScummEngine_v0::resetSentence(bool walking) {
_activeVerb = 13;
+
+ if (!walking) {
+ _activeInventory = 0;
+ _activeObject = 0;
+ _activeObject2 = 0;
+ _activeObjectIndex = 0;
+ _activeObject2Index = 0;
+ }
+
+ _verbExecuting = false;
+ _verbPickup = false;
+
+ _activeActor = 0;
+ _activeInvExecute = false;
+ _activeObject2Inv = false;
+ _activeObjectObtained = false;
+ _activeObject2Obtained = false;
}
} // End of namespace Scumm
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 1ce38fd800..f83e7f2879 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1138,9 +1138,19 @@ void ScummEngine_v5::o5_ifClassOfIs() {
while ((_opcode = fetchScriptByte()) != 0xFF) {
cls = getVarOrDirectWord(PARAM_1);
- b = getClass(obj, cls);
- if (((cls & 0x80) && !b) || (!(cls & 0x80) && b))
- cond = false;
+
+ // WORKAROUND bug #1668393: Due to a script bug, the wrong opcode is used
+ // to check the state of the inside door (object 465) of the Hostel on Mars,
+ // when opening the Hostel door from the outside.
+ if (_game.id == GID_ZAK && _game.platform == Common::kPlatformFMTowns &&
+ vm.slot[_currentScript].number == 205 && _currentRoom == 185 &&
+ obj == 465 && cls == 0) {
+ cond = (getState(obj) == 0);
+ } else {
+ b = getClass(obj, cls);
+ if (((cls & 0x80) && !b) || (!(cls & 0x80) && b))
+ cond = false;
+ }
}
jumpRelative(cond);
}
@@ -1775,7 +1785,7 @@ void ScummEngine_v5::o5_roomOps() {
while ((chr = fetchScriptByte()))
filename += chr;
- if (filename.hasPrefix("iq-") || filename.hasPrefix("IQ-") || filename.hasSuffix("-iq")) {
+ if (filename.hasPrefix("iq-") || filename.hasPrefix("IQ-") || filename.hasSuffix("-iq") || filename.hasSuffix("-IQ")) {
filename = _targetName + ".iq";
} else {
error("SO_LOAD_STRING: Unsupported filename %s", filename.c_str());
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index dcd60352c7..6df3c0c494 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -701,6 +701,14 @@ void ScummEngine_v6::o6_ifNot() {
void ScummEngine_v6::o6_jump() {
int offset = fetchScriptWordSigned();
+
+ // WORKAROUND bug #2826144: Talking to the guard at the bigfoot party, after
+ // he's let you inside, will cause the game to hang, if you end the conversation.
+ // This is a script bug, due to a missing jump in one segment of the script.
+ if (_game.id == GID_SAMNMAX && vm.slot[_currentScript].number == 101 && readVar(0x8000 + 97) == 1 && offset == 1) {
+ offset = -18;
+ }
+
_scriptPointer += offset;
}
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 5bb0e097dc..cb7f906f13 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 Sat Jul 11 01:37:44 2009
+ This file was generated by the md5table tool on Thu Jul 30 10:23:41 2009
DO NOT EDIT MANUALLY!
*/
@@ -17,20 +17,20 @@ 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 },
- { "035deab53b47bc43abc763560d0f8d4b", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "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 },
- { "0425954a9db5c340861672892c3e678d", "samnmax", "CD", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
+ { "0425954a9db5c340861672892c3e678d", "samnmax", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "04401d747f1a2c1c4b388daff71ed378", "ft", "", "", 535405461, Common::DE_DEU, Common::kPlatformMacintosh },
{ "04687cdf7f975a89d2474929f7b80946", "indy3", "FM-TOWNS", "", 7552, Common::EN_ANY, Common::kPlatformFMTowns },
{ "0557df19f046a84c2fdc63507c6616cb", "farm", "HE 72", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "055ffe4f47753e47594ac67823220c54", "puttrace", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "057c9b456dedcc4d71b991a3072a20b3", "monkey", "SEGA", "", 9465, Common::JA_JPN, Common::kPlatformSegaCD },
{ "0650e8ab1432564607cd651c0fa3f344", "loom", "PC-Engine", "", -1, Common::EN_ANY, Common::kPlatformPCEngine },
- { "06b187468113f9ae5a400b148a847fac", "atlantis", "", "Floppy", 12075, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "06b187468113f9ae5a400b148a847fac", "atlantis", "Floppy", "Floppy", 12075, Common::EN_ANY, Common::kPlatformMacintosh },
{ "06c3cf4f31daad8b1cd93153491db9e6", "pajama3", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "07433205acdca3bc553d0e731588b35f", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
- { "07a1eefd8ca95d77310311446c0f53d0", "brstorm", "", "Demo", 5433, Common::EN_ANY, Common::kPlatformUnknown },
+ { "07a1eefd8ca95d77310311446c0f53d0", "brstorm", "", "", 5433, Common::EN_ANY, Common::kPlatformUnknown },
{ "07b810e37be7489263f7bc7627d4765d", "freddi4", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "084ed0fa98a6d1e9368d67fe9cfbd417", "freddi", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "0855496dde35356b1a9691e22ba84cdc", "freddi", "HE 73", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -49,14 +49,14 @@ static const MD5Table md5table[] = {
{ "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "0cccfa5223099a60e76cfcca57a1a141", "freddi3", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformPC },
- { "0e4c5d54a0ad4b26132e78b5ea76642a", "samnmax", "", "Demo", 6485, Common::EN_ANY, Common::kPlatformPC },
+ { "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 },
{ "0f5935bd5e88ba6f09e558d64459746d", "thinker1", "", "Demo", 30919, Common::EN_USA, Common::kPlatformWindows },
- { "0f6f2e716ba896a44e5059bba1de7ca9", "samnmax", "CD", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
+ { "0f6f2e716ba896a44e5059bba1de7ca9", "samnmax", "", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "0f9c7a76657f0840b8f7ccb5bffeb9f4", "indy3", "No Adlib", "EGA", -1, Common::FR_FRA, Common::kPlatformAtariST },
{ "0f9d3317910ac7a9f449243118884ada", "puttzoo", "", "", 42070, Common::DE_DEU, Common::kPlatformWindows },
- { "0fb73eddfcf584c02ba097984df131ba", "samnmax", "CD", "CD", 9080, Common::DE_DEU, Common::kPlatformUnknown },
+ { "0fb73eddfcf584c02ba097984df131ba", "samnmax", "", "CD", 9080, Common::DE_DEU, Common::kPlatformUnknown },
{ "1005456bfe351c1b679e1ff2dc2849e9", "puttzoo", "", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
{ "100b4c8403ad6a83d4bf7dbf83e44dc4", "spyfox", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "10d8e66cd11049ce64815ebb9fd76eb3", "spyozon", "", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
@@ -72,22 +72,22 @@ static const MD5Table md5table[] = {
{ "15240c59d3681ed53f714f8d925cb2d6", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformAtariST },
{ "157367c3c21e0d03a0cba44361b4cf65", "indy3", "No Adlib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
{ "15e03ffbfeddb9c2aebc13dcb2a4a8f4", "monkey", "VGA", "VGA", 8357, Common::EN_ANY, Common::kPlatformPC },
- { "15f588e887e857e8c56fe6ade4956168", "atlantis", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformAmiga },
+ { "15f588e887e857e8c56fe6ade4956168", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "16542a7342a918bfe4ba512007d36c47", "FreddisFunShop", "HE 99L", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "166553538ff320c69edafeee29525419", "samnmax", "CD", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "166553538ff320c69edafeee29525419", "samnmax", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "16effd200aa6b8abe9c569c3e578814d", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "179879b6e35c1ead0d93aab26db0951b", "fbear", "HE 70", "", 13381, Common::EN_ANY, Common::kPlatformWindows },
{ "17b5d5e6af4ae89d62631641d66d5a05", "indy3", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformPC },
{ "17f7296f63c78642724f057fd8e736a7", "maniac", "NES", "extracted", -1, Common::EN_GRB, Common::kPlatformNES },
- { "17fa250eb72dae2dad511ba79c0b6b0a", "tentacle", "CD", "Demo", -1, Common::FR_FRA, Common::kPlatformPC },
- { "182344899c2e2998fca0bebcd82aa81a", "atlantis", "CD", "CD", 12035, Common::EN_ANY, Common::kPlatformPC },
+ { "17fa250eb72dae2dad511ba79c0b6b0a", "tentacle", "", "Demo", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "182344899c2e2998fca0bebcd82aa81a", "atlantis", "", "CD", 12035, Common::EN_ANY, Common::kPlatformPC },
{ "183d7464902d40d00800e8ee1f04117c", "maniac", "V2", "V2", 1988, Common::DE_DEU, Common::kPlatformPC },
{ "1875b90fade138c9253a8e967007031a", "indy3", "VGA", "VGA", 6295, Common::EN_ANY, Common::kPlatformPC },
{ "187d315f6b5168f68680dfe8c3d76a3e", "loom", "EGA", "EGA", -1, Common::HB_ISR, Common::kPlatformPC },
{ "1900e501a52fbf55bde6e4196f6d2aa6", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "19263586f749a560c1adf8b3393a9593", "socks", "HE 85", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "19bf6938a94698296bcb0c99c31c91a7", "spyfox2", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
- { "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "CD", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "1c792d28376d45e145cb916bca0400a2", "spyfox2", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "1c7e7db2cfab1ad62746ab680a634204", "maniac", "NES", "extracted", -1, Common::FR_FRA, Common::kPlatformNES },
{ "1ca86e2cf9aaa2068738a1e5ba477e60", "zak", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
@@ -97,12 +97,12 @@ static const MD5Table md5table[] = {
{ "1dd7aa088e09f96d06818aa9a9deabe0", "indy3", "No Adlib", "EGA", 5361, Common::EN_ANY, Common::kPlatformMacintosh },
{ "1ed22f601f8b3695804a6583cc3083f1", "puttrace", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "1f2e62b5a9c50589fc342285a6bb3a27", "freddi", "HE 73", "", -1, Common::HB_ISR, Common::kPlatformWindows },
- { "1fbebd7b2b692df5297870447a80cfed", "atlantis", "", "Floppy", 12030, Common::DE_DEU, Common::kPlatformPC },
+ { "1fbebd7b2b692df5297870447a80cfed", "atlantis", "Floppy", "Floppy", 12030, Common::DE_DEU, Common::kPlatformPC },
{ "1ff5997c78fbd0a841a75ef15a05d9d5", "BluesBirthday", "", "Red", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "2012f854d83d9cc6f73b2b544cd8bbf8", "water", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "20176076d708bf14407bcc9bdcd7a418", "pajama3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "204453e33456c4faa26e276229fe5b76", "spyfox2", "", "Demo", 14689, Common::DE_DEU, Common::kPlatformWindows },
- { "20da6fce37805423966aaa8f3c2426aa", "atlantis", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformAmiga },
+ { "20da6fce37805423966aaa8f3c2426aa", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "2108d83dcf09f8adb4bc524669c8cf51", "PuttTime", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "21a6592322f92550f144f68a8a4e685e", "dig", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "21abe302e1b1e2b66d6f5c12e241ebfd", "freddicove", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows },
@@ -114,14 +114,14 @@ static const MD5Table md5table[] = {
{ "22f4ea88a09da12df9308ba30bcb7d0f", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC },
{ "23394c8d29cc63c61313959431a12476", "spyfox", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "257f8c14d8c584f7ddd601bcb00920c7", "maniac", "NES", "", 262144, Common::DE_DEU, Common::kPlatformNES },
- { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "", "Floppy", 7932, Common::EN_ANY, Common::kPlatformPC },
+ { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformPC },
{ "27b2ef1653089fe5b897d9cc89ce784f", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "27b3a4224ad63d5b04627595c1c1a025", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformAmiga },
- { "28d24a33448fab6795850bc9f159a4a2", "atlantis", "CD", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns },
+ { "28d24a33448fab6795850bc9f159a4a2", "atlantis", "", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns },
{ "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformPC },
{ "28f07458f1b6c24e118a1ea056827701", "lost", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "2a208ffbcd0e83e86f4356e6f64aa6e1", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC },
- { "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", "CD", "Demo", 2439158, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", "", "Demo", 2439158, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "2a8658dbd13d84d1bce64a71a35995eb", "pajama2", "HE 99", "Demo", -1, Common::HB_ISR, Common::kPlatformWindows },
{ "2c04aacffb8428f30ccf4f734fbe3adc", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformPC },
@@ -130,7 +130,7 @@ static const MD5Table md5table[] = {
{ "2d388339d6050d8ccaa757b64633954e", "zak", "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 },
- { "2d9d46f23cb07bbc90b8ad464d3e4ff8", "atlantis", "CD", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "2d9d46f23cb07bbc90b8ad464d3e4ff8", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2e85f7aa054930c692a5b1bed1dfc295", "football2002", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "2e8a1f76ea33bc5e04347646feee173d", "pajama3", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "2fe369ad70f52a8cf7ad6077ee64f81a", "loom", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformAmiga },
@@ -157,18 +157,18 @@ static const MD5Table md5table[] = {
{ "3824e60cdf639d22f6df92a03dc4b131", "fbear", "HE 61", "", 7732, Common::EN_ANY, Common::kPlatformPC },
{ "387a544b8b10b26912d8413bab63a853", "monkey2", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "3905799e081b80a61d4460b7b733c206", "maniac", "NES", "", 262144, Common::EN_USA, Common::kPlatformNES },
- { "3938ee1aa4433fca9d9308c9891172b1", "zak", "FM-TOWNS", "Demo", -1, Common::EN_ANY, Common::kPlatformFMTowns },
+ { "3938ee1aa4433fca9d9308c9891172b1", "zak", "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 },
{ "39fd6db10d0222d817025c4d3346e3b4", "farm", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "3a03dab514e4038df192d8a8de469788", "atlantis", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformAmiga },
+ { "3a03dab514e4038df192d8a8de469788", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "3a0c35f3c147b98a2bdf8d400cfc4ab5", "indy3", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
{ "3a3e592b074f595489f7f11e150c398d", "puttzoo", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformWindows },
- { "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "CD", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
+ { "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "3a5ec90d556d4920976c5578bfbfaf79", "maniac", "NES", "extracted", -1, Common::DE_DEU, Common::kPlatformNES },
{ "3af61c5edf8e15b43dbafd285b2e9777", "puttcircus", "", "Demo", -1, Common::HB_ISR, Common::kPlatformWindows },
- { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
{ "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "3cce1913a3bc586b51a75c3892ff18dd", "indy3", "VGA", "VGA", -1, Common::RU_RUS, Common::kPlatformPC },
{ "3d219e7546039543307b55a91282bf18", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC },
@@ -176,7 +176,7 @@ static const MD5Table md5table[] = {
{ "3df6ead57930488bc61e6e41901d0e97", "fbear", "HE 61", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "3e48298920fab9b7aec5a971e1bd1fab", "pajama3", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "40564ec47da48a67787d1f9bd043902a", "maniac", "V2 Demo", "V2 Demo", 1988, Common::EN_ANY, Common::kPlatformPC },
- { "4167a92a1d46baa4f4127d918d561f88", "tentacle", "CD", "CD", 7932, Common::EN_ANY, Common::kPlatformUnknown },
+ { "4167a92a1d46baa4f4127d918d561f88", "tentacle", "", "CD", 7932, Common::EN_ANY, Common::kPlatformUnknown },
{ "41958e24d03181ff9a381a66d048a581", "ft", "", "", -1, Common::PT_BRA, Common::kPlatformUnknown },
{ "425205754fa749f4f0b0dd9d09fa45fd", "football", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "430bc518017b6fac046f58bab6baad5d", "monkey2", "", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
@@ -195,13 +195,13 @@ static const MD5Table md5table[] = {
{ "4aa93cb30e485b728504ba3a693f12bf", "pajama", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "4af4a6b248103c1fe9edef619677f540", "puttmoon", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "4ba37f835be11a59d969f90f272f575b", "water", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "4ba7fb331296c283e73d8f5b2096e551", "samnmax", "CD", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
+ { "4ba7fb331296c283e73d8f5b2096e551", "samnmax", "", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
{ "4bedb49943df95a9c900a5a82ccbe9de", "ft", "", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "4bfa4a43684bcb437f7fb47f457a0aa5", "socks", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "4c4820518e16e1a0e3616a3b021a04f3", "catalog", "HE CUP", "Preview", 10927456, Common::DE_DEU, Common::kPlatformUnknown },
{ "4cb9c3618f71668f8e4346c8f323fa82", "monkey2", "", "", 10700, Common::EN_ANY, Common::kPlatformMacintosh },
{ "4ce2d5b355964bbcb5e5ce73236ef868", "freddicove", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows },
- { "4d34042713958b971cb139fba4658586", "atlantis", "CD", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
+ { "4d34042713958b971cb139fba4658586", "atlantis", "", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
{ "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 },
@@ -209,15 +209,15 @@ static const MD5Table md5table[] = {
{ "4f04b321a95d4315ce6d65f8e1dd0368", "maze", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "4f138ac6f9b2ac5a41bc68b2c3296064", "freddi4", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "4f1d6f8b38343dba405472538b5037ed", "fbear", "HE 61", "", 7717, Common::EN_ANY, Common::kPlatformPC },
- { "4f267a901719623de7dde83e47d5b474", "atlantis", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
+ { "4f267a901719623de7dde83e47d5b474", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "4f580a021eee026f3b4589e17d130d78", "freddi4", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown },
{ "4fa6870d9bc8c313b65d54b1da5a1891", "pajama", "", "", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "4fbbe9f64b8bc547503a379a301183ce", "tentacle", "CD", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
+ { "4fbbe9f64b8bc547503a379a301183ce", "tentacle", "", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "5057fb0e99e5aa29df1836329232f101", "freddi2", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
{ "507bb360688dc4180fdf0d7597352a69", "freddi", "HE 73", "", 26402, Common::SE_SWE, Common::kPlatformWindows },
{ "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
- { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
+ { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
{ "51305e929e330e24a75a0351c8f9975e", "freddi2", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "513f91a9dbe8d5490b39e56a3ac5bbdf", "pajama2", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "5262a27afcaee04e5c4900220bd463e7", "PuttsFunShop", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -229,10 +229,10 @@ static const MD5Table md5table[] = {
{ "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows },
{ "5719fc8a13b4638b78d9d8d12f091f94", "puttrace", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
- { "5798972220cd458be2626d54c80f71d7", "atlantis", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga },
+ { "5798972220cd458be2626d54c80f71d7", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "57a17febe2183f521250e55d55b83e60", "PuttTime", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "57a5cfec9ef231a007043cc1917e8988", "freddi", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
- { "57b0d89af79befe1cabce3bece869e7f", "tentacle", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "57b0d89af79befe1cabce3bece869e7f", "tentacle", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
{ "58436e634f4fae1d9973591c2ffa1fcb", "spyfox", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "589601b676c98b1c0c987bc031ab68b3", "chase", "HE 95", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "58fdf4c7ad13540a734e18f8584cad89", "puttzoo", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
@@ -289,9 +289,9 @@ static const MD5Table md5table[] = {
{ "6bf70eee5de3d24d2403e0dd3d267e8a", "spyfox", "", "", 49221, Common::UNK_LANG, Common::kPlatformWindows },
{ "6c2bff0e327f2962e809c2e1a82d7309", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "6d1baa1065ac5f7b210be8ebe4235e49", "freddi", "HE 73", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
- { "6dead580b0ff14d5f7b33b4219f04159", "samnmax", "CD", "Demo", 16556335, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "6dead580b0ff14d5f7b33b4219f04159", "samnmax", "", "Demo", 16556335, Common::EN_ANY, Common::kPlatformMacintosh },
{ "6df20c50c1ab19799de9be7ae7716881", "fbear", "HE 61", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "CD", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown },
+ { "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown },
{ "6ea966b4d660c870b9ee790d1fbfc535", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "6f0be328c64d689bb606d22a389e1b0f", "loom", "No Adlib", "EGA", 5748, Common::EN_ANY, Common::kPlatformMacintosh },
{ "6f6ef668c608c7f534fea6e6d3878dde", "indy3", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformPC },
@@ -332,7 +332,7 @@ static const MD5Table md5table[] = {
{ "7ddeaf52c8b9a50551ce0aa2ac811d07", "BluesABCTime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "7e151c17adf624f1966c8fc5827c95e9", "puttputt", "HE 61", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "7ea2da67ebabea4ac20cee9f4f9d2934", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "CD", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown },
+ { "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", "V1", "V1", 1972, Common::EN_ANY, Common::kPlatformPC },
{ "7f945525abcd48015adf1632637a44a1", "pajama", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7fc6cdb46b4c9d384c52327f4bca6416", "football", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -354,12 +354,12 @@ static const MD5Table md5table[] = {
{ "87df3e0074624040407764b7c5e710b9", "pajama", "", "Demo", 18354, Common::NL_NLD, Common::kPlatformWindows },
{ "87f6e8037b7cc996e13474b491a7a98e", "maniac", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "8801fb4a1200b347f7a38523339526dd", "jungle", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
- { "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", "CD", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
+ { "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", "", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
{ "898ce8eb1234a955ef75e87141902bb3", "freddi3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "898eaa21f79cf8d4f08db856244689ff", "pajama", "HE 99", "Updated", 66505, Common::EN_ANY, Common::kPlatformWindows },
{ "89cfc425566003ff74b7dc7b3e6fd469", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC },
{ "8a484262363a8e18be87112454f1456b", "pjgames", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "8aa05d3cdb0e795436043f0546af2da2", "tentacle", "CD", "CD?", -1, Common::FR_FRA, Common::kPlatformUnknown },
+ { "8aa05d3cdb0e795436043f0546af2da2", "tentacle", "", "CD?", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "8aed489aba45d2b9fb8a04079c9c6e6a", "baseball", "HE CUP", "Preview", 12876596, Common::UNK_LANG, Common::kPlatformUnknown },
{ "8afb3cf9f95abf208358e984f0c9e738", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "8bdb0bf87b5e303dd35693afb9351215", "ft", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
@@ -367,11 +367,11 @@ static const MD5Table md5table[] = {
{ "8de13897f0121c79d29a2377159f9ad0", "socks", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "8e3241ddd6c8dadf64305e8740d45e13", "balloon", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "8e4ee4db46954bfe2912e259a16fad82", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformPC },
- { "8e9417564f33790815445b2136efa667", "atlantis", "CD", "CD", 11915, Common::JA_JPN, Common::kPlatformMacintosh },
+ { "8e9417564f33790815445b2136efa667", "atlantis", "", "CD", 11915, Common::JA_JPN, Common::kPlatformMacintosh },
{ "8e9830a6f2702be5b22c8fa0a6aaf977", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "8eb84cee9b429314c7f0bdcf560723eb", "monkey", "FM-TOWNS", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
{ "8ee63cafb1fe9d62aa0d5a23117e70e7", "freddi2", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
+ { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
{ "8fec68383202d38c0d25e9e3b757c5df", "comi", "Demo", "Demo", 18041, Common::UNK_LANG, Common::kPlatformWindows },
{ "8ffd618a776a4c0d8922bb28b09f8ce8", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "90a329d8ad5b7ce0690429e98cfbb32f", "funpack", "", "", -1, Common::HB_ISR, Common::kPlatformPC },
@@ -381,10 +381,10 @@ static const MD5Table md5table[] = {
{ "91469353f7be1b122fa88d23480a1320", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "91d5db93187fab54d823f73bd6441cb6", "maniac", "NES", "extracted", -1, Common::EN_USA, Common::kPlatformNES },
{ "927a764615c7fcdd72f591355e089d8c", "monkey", "No Adlib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
- { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "92e7727e67f5cd979d8a1070e4eb8cb3", "puttzoo", "HE 98.5", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "92fc0073a4cf259ff36070ecb8628ba8", "thinkerk", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "94db6519da85b8d08c976d8e9a858ea7", "baseball", "HE CUP", "Preview", 10044774, Common::UNK_LANG, Common::kPlatformUnknown },
{ "95818b178d473c989ac753574e8892aa", "readtime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "95b3806e043be08668c54c3ffe98650f", "BluesABCTime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -392,13 +392,13 @@ static const MD5Table md5table[] = {
{ "9708cf716ed8bcc9ff3fcfc69413b746", "puttputt", "HE 61", "", -1, Common::EN_ANY, Common::kPlatformPC },
{ "9781422e4288dbc090720e4563168ba7", "puttzoo", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "981e1e1891f2be7e25a01f50ae55a5af", "puttrace", "HE 98", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "99128b6a5bdd9831d9682fb8b5cbf8d4", "BluesBirthday", "", "Yellow", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "99a3699f80b8f776efae592b44b9b991", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC },
- { "99b6f822b0b2612415407865438697d6", "atlantis", "CD", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "99b6f822b0b2612415407865438697d6", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "9b7452b5cd6d3ffb2b2f5118010af84f", "ft", "Demo", "Demo", 116463537, Common::EN_ANY, Common::kPlatformMacintosh },
{ "9bc548e179cdb0767009401c094d0895", "maniac", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAmiga },
- { "9bd2a8f72613e715c199246dd511e10f", "atlantis", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "9bd2a8f72613e715c199246dd511e10f", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
{ "9bda5fee51d2fda5253d02c642016bf4", "spyfox", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "9c0ee9c252785e9fca0143e42ac4b256", "freddi2", "HE 99", "Updated", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "9c0fee288ad564a7d25ec3e841810d79", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
@@ -420,7 +420,7 @@ static const MD5Table md5table[] = {
{ "a2386da005672cbd5136f4f27a626c5f", "farm", "", "", 87061, Common::NL_NLD, Common::kPlatformWindows },
{ "a28135a7ade38cc0208b04507c46efd1", "spyfox", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", "HE 99", "Demo", 15540, Common::EN_ANY, Common::kPlatformWindows },
- { "a3036878840720fbefa41e6965fa4a0a", "samnmax", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "a3036878840720fbefa41e6965fa4a0a", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
{ "a336134914eaab4892d35625aa15ad1d", "freddi4", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "a525c1753c1db5011c00417da37887ef", "PuttTime", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -441,16 +441,16 @@ static const MD5Table md5table[] = {
{ "aaa587701cde7e74692c68c1024b85eb", "puttrace", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "aaa7f36a253f277dd29dd1c051b0e4b9", "indy3", "No Adlib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
{ "ab0693e9324cfcf498fdcbb12acf8bb4", "puttcircus", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "ac1642b6edfb8521ca03760126f1c250", "tentacle", "CD", "Demo", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "ac1642b6edfb8521ca03760126f1c250", "tentacle", "", "Demo", -1, Common::DE_DEU, Common::kPlatformPC },
{ "ac62d50e39492ee3738b4e83a5ac780f", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformUnknown },
+ { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
{ "aefa244ea034b7cd2041f0a44be7d9ba", "pajama3", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "af2bd1a43b50b55915d87994e093203d", "freddi", "HE 99", "Updated", 34829, Common::DE_DEU, Common::kPlatformWindows },
{ "b100abf7ff83146df50db78dbd5e9cfa", "freddicove", "HE 100", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "b23f7cd7c304d7dff08e92a96120d5b4", "zak", "V1", "V1", -1, Common::EN_ANY, Common::kPlatformPC },
{ "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformPC },
- { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
+ { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
{ "b47be81e39a9710f6f595f7b527b60f8", "puttrace", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "b5298a5c15ffbe8b381d51ea4e26d35c", "freddi4", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "b597e0403cc0002f69170e6caba7edd9", "indy3", "EGA", "EGA Demo", 5361, Common::EN_ANY, Common::kPlatformPC },
@@ -479,7 +479,7 @@ static const MD5Table md5table[] = {
{ "c24c490373aeb48fbd54caa8e7ae376d", "loom", "No Adlib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
{ "c25755b08a8d0d47695e05f1e2111bfc", "freddi4", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "c30ef068add4277104243c31ce46c12b", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformAmiga },
- { "c3196c5349e53e387aaff1533d95e53a", "samnmax", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "c3196c5349e53e387aaff1533d95e53a", "samnmax", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "c3b22fa4654bb580b20325ebf4174841", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "c3df37df9d3b481b45f75283a9907c47", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformPC },
{ "c4787c3e8b5e2dfda90850ee800af00f", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC },
@@ -487,22 +487,22 @@ static const MD5Table md5table[] = {
{ "c4ffae9fac495475d6bc3343ccc8faf9", "Soccer2004", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "c5cc7cba02a2fbd539c4439e775b0536", "puttzoo", "HE 99", "Updated", 43470, Common::DE_DEU, Common::kPlatformWindows },
{ "c5d10e190d4b4d59114b824f2fdbd00e", "loom", "FM-TOWNS", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
- { "c63ee46143ba65f9ce14cf539ca51bd7", "atlantis", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "c63ee46143ba65f9ce14cf539ca51bd7", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
{ "c666a998af90d81db447eccba9f72c8d", "monkey", "No Adlib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
{ "c6907d44f1166941d982864cd42cdc89", "pajama2", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "c782fbbe74a987c3df8ac73cd3e289ed", "freddi", "HE 73", "", -1, Common::SE_SWE, Common::kPlatformMacintosh },
{ "c7890e038806df2bb5c0c8c6f1986ea2", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformPC },
- { "c7be10f775404fd9785a8b92a06d240c", "atlantis", "CD", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
+ { "c7be10f775404fd9785a8b92a06d240c", "atlantis", "", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
{ "c7c492a107ec520d7a7943037d0ca54a", "freddi", "HE 71", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "c83079157ec765a28de445aec9768d60", "tentacle", "CD", "Demo", 7477, Common::EN_ANY, Common::kPlatformUnknown },
+ { "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 },
{ "c8c5baadcbfc8d0372ed4335abace8a7", "pajama3", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "c9717ee6059f1e43b768b464493d2fba", "fbpack", "", "", -1, Common::JA_JPN, Common::kPlatform3DO },
{ "cb1559e8405d17a5a278a6b5ad9338d1", "freddi3", "", "Demo", 22718, Common::EN_ANY, Common::kPlatformUnknown },
- { "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", "CD", "CD", 282467632, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", "", "CD", 282467632, Common::EN_ANY, Common::kPlatformMacintosh },
{ "cc0c4111449054f1692bb3c0c5e04629", "BluesBirthday", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "", "Demo", 7485, Common::DE_DEU, Common::kPlatformPC },
+ { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "Floppy", "Demo", 7485, Common::DE_DEU, Common::kPlatformPC },
{ "cd424f143a141bc59226ad83a6e40f51", "maze", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "cd46c9f122272d02bbf79332ff521898", "loom", "EGA", "EGA", 5748, Common::RU_RUS, Common::kPlatformPC },
{ "cd9c05e755d7bf8e9b9590ad1ebe273e", "dig", "Demo", "Demo", 45156007, Common::EN_ANY, Common::kPlatformMacintosh },
@@ -525,7 +525,7 @@ static const MD5Table md5table[] = {
{ "d220d154aafbfa12bd6f3ab1b2dae420", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformMacintosh },
{ "d2cc8e31bce61e6cf2951249e10638fe", "basketball", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "d37c55388294b66e53e7ced3af88fa68", "freddi2", "HE 100", "Updated Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "d43352a805d78b5f4936c6d7779bf575", "samnmax", "CD", "CD", -1, Common::RU_RUS, Common::kPlatformPC },
+ { "d43352a805d78b5f4936c6d7779bf575", "samnmax", "", "CD", -1, Common::RU_RUS, Common::kPlatformPC },
{ "d4aac997e2f4e15341f0bfbf905419bd", "PuttTime", "HE 99", "", 62698, Common::EN_GRB, Common::kPlatformWindows },
{ "d4b8ee426b1afd3e53bc0cf020418cf6", "dog", "HE 99", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "d4cccb5af88f3e77f370896e9ba8c5f9", "freddi", "HE 71", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
@@ -535,7 +535,7 @@ static const MD5Table md5table[] = {
{ "d62047a6729349ab36f7ee065bf26509", "dig", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "d62d248c3df6ec177405e2cb23d923b2", "indy3", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformPC },
{ "d6334a5a9b61afe18c368540fdf522ca", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "d6dd0646404768a63e963891a96daadd", "atlantis", "", "Floppy", 12035, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "d6dd0646404768a63e963891a96daadd", "atlantis", "Floppy", "Floppy", 12035, Common::EN_ANY, Common::kPlatformMacintosh },
{ "d73c851b942af44deb9b6d5f416a0972", "freddi3", "HE 99", "Demo", -1, Common::HB_ISR, Common::kPlatformWindows },
{ "d74122362a77ec24525fdd50297dfd82", "freddi4", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "d7ab7cd6105546016e6a0d46fb36b964", "pajama", "HE 100", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -543,8 +543,8 @@ static const MD5Table md5table[] = {
{ "d831f7c048574dd9d5d85db2a1468099", "maniac", "C64", "", -1, Common::EN_ANY, Common::kPlatformC64 },
{ "d8323015ecb8b10bf53474f6e6b0ae33", "dig", "", "", 16304, Common::UNK_LANG, Common::kPlatformUnknown },
{ "d8d07efcb88f396bee0b402b10c3b1c9", "maniac", "NES", "", 262144, Common::EN_GRB, Common::kPlatformNES },
- { "d917f311a448e3cc7239c31bddb00dd2", "samnmax", "CD", "CD", 9080, Common::EN_ANY, Common::kPlatformUnknown },
- { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "CD", "Demo", 6478, Common::EN_ANY, Common::kPlatformPC },
+ { "d917f311a448e3cc7239c31bddb00dd2", "samnmax", "", "CD", 9080, Common::EN_ANY, Common::kPlatformUnknown },
+ { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "", "Demo", 6478, Common::EN_ANY, Common::kPlatformPC },
{ "da09e666fc8f5b78d7b0ac65d1a3b56e", "monkey2", "", "", 11135, Common::EN_ANY, Common::kPlatformFMTowns },
{ "da6269b18fcb08189c0aa9c95533cce2", "monkey", "CD", "CD", 8955, Common::IT_ITA, Common::kPlatformPC },
{ "da669b20271b85182e9c17a2a37ea02e", "monkey2", "", "", -1, Common::DE_DEU, Common::kPlatformAmiga },
@@ -566,7 +566,7 @@ static const MD5Table md5table[] = {
{ "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC },
{ "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "e44ea295a3f8fe4f41983080dab1e9ce", "freddi", "HE 90", "Updated", -1, Common::FR_FRA, Common::kPlatformMacintosh },
- { "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
+ { "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "e5563c8358443c4352fcddf7402a5e0a", "pajama2", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "e5c112140ad6574997de033a8e2a2964", "readtime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "e62056ba675ad65d8854ab3c5ad4b3c0", "spyfox2", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -584,11 +584,11 @@ static const MD5Table md5table[] = {
{ "ecc4340c2b801f5af8da4e00c0e432d9", "puttcircus", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "ed2b074bc3166087a747acb2a3c6abb0", "freddi3", "HE 98.5", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "ed361270102e355afe5236954216aba2", "lost", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "CD", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
- { "edfdb24a499d92c59f824c52987c0eec", "atlantis", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
+ { "edfdb24a499d92c59f824c52987c0eec", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "ee41f6afbc5b26fa475754b56fe92048", "puttputt", "HE 61", "", 8032, Common::JA_JPN, Common::kPlatform3DO },
{ "ee785fe2569bc9965526e774f7ab86f1", "spyfox", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
- { "ef347474f3c7be3b29584eaa133cca05", "samnmax", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "ef347474f3c7be3b29584eaa133cca05", "samnmax", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "ef71a322b6530ac45b1a070f7c0795f7", "moonbase", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "ef74d9071d4e564b037cb44bd6774de7", "fbear", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC },
{ "efe0a04a703e765ebebe92b6c8aa6b86", "baseball2003", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -598,11 +598,11 @@ static const MD5Table md5table[] = {
{ "f163cf53f7850e43fb482471e5c52e1a", "maniac", "NES", "", 262144, Common::ES_ESP, Common::kPlatformNES },
{ "f1b0e0d587b85052de5534a3847e68fe", "water", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "f237bf8a5ef9af78b2a6a4f3901da341", "pajama", "", "Demo", 18354, Common::EN_ANY, Common::kPlatformUnknown },
- { "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
{ "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", "", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows },
{ "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "f5228b0cc1c19e6ea8268ba2eeb61f60", "freddi", "HE 73", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
- { "f73883f13b5a302749a5bad31d909780", "tentacle", "CD", "CD", -1, Common::DE_DEU, Common::kPlatformMacintosh },
+ { "f73883f13b5a302749a5bad31d909780", "tentacle", "", "CD", -1, Common::DE_DEU, Common::kPlatformMacintosh },
{ "f7711f9264d4d43c2a1518ec7c10a607", "pajama3", "", "", 79382, Common::EN_USA, Common::kPlatformUnknown },
{ "f79e60c17cca601e411f1f75e8ee9b5a", "spyfox2", "", "", 51286, Common::UNK_LANG, Common::kPlatformUnknown },
{ "f8be685007a8b425ba2a455da732f59f", "pajama2", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
@@ -613,7 +613,7 @@ static const MD5Table md5table[] = {
{ "fbb697d89d2beca87360a145f467bdae", "PuttTime", "HE 90", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "fbbbb38a81fc9d6a61d509278390a290", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "fbdd947d21e8f5bac6d6f7a316af1c5a", "spyfox", "", "Demo", 15693, Common::EN_ANY, Common::kPlatformUnknown },
- { "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
{ "fc6b6148e80d67939d9a18697c0f626a", "monkey", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformPC },
{ "fc8d197a22146e74766e9cb0cfcaf1da", "freddi2", "HE 80", "Demo", 27298, Common::EN_ANY, Common::kPlatformUnknown },
{ "fcb78ebecab2757264c590890c319cc5", "PuttTime", "HE 85", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 70b2d7285e..1beda85456 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -26,6 +26,7 @@
#include "common/config-manager.h"
#include "common/md5.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "gui/message.h"
@@ -136,6 +137,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
// Init all vars
+ _v0ObjectIndex = false;
+ _v0ObjectInInventory = false;
_imuse = NULL;
_imuseDigital = NULL;
_musicEngine = NULL;
@@ -183,6 +186,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_mouseAndKeyboardStat = 0;
_leftBtnPressed = 0;
_rightBtnPressed = 0;
+ _lastInputScriptTime = 0;
_bootParam = 0;
_dumpScripts = false;
_debugMode = 0;
@@ -216,7 +220,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_roomResource = 0;
OF_OWNER_ROOM = 0;
_verbMouseOver = 0;
- _inventoryOffset = 0;
_classData = NULL;
_actorToPrintStrFor = 0;
_sentenceNum = 0;
@@ -542,7 +545,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
for (int i = 0; i < ARRAYSIZE(debugChannels); ++i)
Common::addDebugChannel(debugChannels[i].flag, debugChannels[i].channel, debugChannels[i].desc);
- syst->getEventManager()->registerRandomSource(_rnd, "scumm");
+ g_eventRec.registerRandomSource(_rnd, "scumm");
}
@@ -651,6 +654,8 @@ ScummEngine_v3old::ScummEngine_v3old(OSystem *syst, const DetectorResult &dr)
ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
: ScummEngine_v3old(syst, dr) {
+ _inventoryOffset = 0;
+
_activeInventory = 0;
_activeObject = 0;
_activeVerb = 0;
@@ -669,7 +674,17 @@ 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;
+
+ _activeObject2 = 0;
+ _activeObjectIndex = 0;
+ _activeObject2Index = 0;
+ _activeInvExecute = false;
+ _activeObject2Inv = false;
+ _activeObjectObtained = false;
+ _activeObject2Obtained = false;
}
ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr)
@@ -1907,7 +1922,7 @@ void ScummEngine::scummLoop(int delta) {
}
// Trigger autosave if necessary.
- if (!_saveLoadFlag && shouldPerformAutoSave(_lastSaveTime)) {
+ if (!_saveLoadFlag && shouldPerformAutoSave(_lastSaveTime) && canSaveGameStateCurrently()) {
_saveLoadSlot = 0;
sprintf(_saveLoadName, "Autosave %d", _saveLoadSlot);
_saveLoadFlag = 1;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 6491f8a171..0e2031eea5 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -565,6 +565,9 @@ protected:
int32 *_scummVars;
byte *_bitVars;
+ bool _v0ObjectIndex; // V0 Use object index, instead of object number
+ bool _v0ObjectInInventory; // V0 Use object number from inventory
+
/* Global resource tables */
int _numVariables, _numBitVariables, _numLocalObjects;
int _numGlobalObjects, _numArray, _numVerbs, _numFlObject;
@@ -612,6 +615,12 @@ protected:
uint16 _mouseAndKeyboardStat;
byte _leftBtnPressed, _rightBtnPressed;
+ /**
+ * Last time runInputScript was run (measured in terms of OSystem::getMillis()).
+ * This is currently only used for Indy3 mac to detect "double clicks".
+ */
+ uint32 _lastInputScriptTime;
+
/** The bootparam, to be passed to the script 1, the bootscript. */
int _bootParam;
@@ -858,12 +867,14 @@ 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);
public:
int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public
protected:
+ int getDist(int x, int y, int x2, int y2);
int getObjActToObjActDist(int a, int b); // Not sure how to handle
const byte *getObjOrActorName(int obj); // these three..
void setObjectName(int obj);
@@ -884,7 +895,6 @@ protected:
protected:
/* Should be in Verb class */
uint16 _verbMouseOver;
- int _inventoryOffset;
int8 _userPut;
uint16 _userState;
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index ccca5df0d3..19260b6429 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -35,7 +35,20 @@ namespace Scumm {
*/
class ScummEngine_v0 : public ScummEngine_v2 {
protected:
- int _currentMode;
+ byte _currentMode;
+ bool _verbExecuting; // is a verb executing
+ bool _verbPickup; // are we picking up an object during a verb execute
+
+ int _activeActor; // Actor Number
+ int _activeObject2; // 2nd Object Number
+
+ bool _activeInvExecute; // is activeInventory first to be executed
+ bool _activeObject2Inv; // is activeobject2 in the inventory
+ bool _activeObjectObtained; // collected _activeobject?
+ bool _activeObject2Obtained; // collected _activeObject2?
+
+ int _activeObjectIndex;
+ int _activeObject2Index;
public:
ScummEngine_v0(OSystem *syst, const DetectorResult &dr);
@@ -53,12 +66,25 @@ 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 void checkExecVerbs();
virtual void handleMouseOver(bool updateInventory);
void resetVerbs();
void setNewKidVerbs();
+
+ void drawSentenceWord(int object, bool usePrep, bool objInInventory);
void drawSentence();
void switchActor(int slot);
@@ -68,7 +94,7 @@ protected:
virtual int getActiveObject();
- virtual void resetSentence();
+ virtual void resetSentence(bool walking = false);
/* Version C64 script opcodes */
void o_stopCurrentScript();
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index 338b5f6167..ee9591bc45 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -45,6 +45,7 @@ protected:
int8 _mouseOverBoxV2;
char _sentenceBuf[256];
+ uint16 _inventoryOffset;
int _activeInventory;
int _activeObject;
@@ -66,6 +67,8 @@ protected:
virtual void resetScummVars();
virtual void decodeParseString();
+ virtual void saveOrLoad(Serializer *s);
+
virtual void processKeyboard(Common::KeyState lastKeyHit);
virtual void readIndexFile();
@@ -100,7 +103,7 @@ protected:
virtual void setBuiltinCursor(int index);
- void runObject(int obj, int entry);
+ virtual void runObject(int obj, int entry);
/* Version 2 script opcodes */
void o2_actorFromPos();
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index ad48029bd2..2362427779 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -23,6 +23,9 @@
*
*/
+#include "common/config-manager.h"
+#include "common/timer.h"
+#include "common/util.h"
#include "scumm/actor.h"
#include "scumm/file.h"
@@ -32,10 +35,6 @@
#include "scumm/sound.h"
#include "scumm/util.h"
-#include "common/config-manager.h"
-#include "common/timer.h"
-#include "common/util.h"
-
#include "sound/adpcm.h"
#include "sound/audiocd.h"
#include "sound/flac.h"
@@ -46,8 +45,6 @@
#include "sound/vorbis.h"
#include "sound/wave.h"
-
-
namespace Scumm {
struct MP3OffsetTable { /* Compressed Sound (.SO3) */
@@ -420,17 +417,16 @@ void Sound::playSound(int soundID) {
sound = (char *)malloc(size);
int vol = ptr[24] * 4;
int loopStart = 0, loopEnd = 0;
-#if 0 // Disabling this until after 0.11.0
int loopcount = ptr[27];
if (loopcount > 1) {
// TODO: We can only loop once, or infinitely many times, but
// have no support for a finite number of repetitions.
- // This is
+ // So far, I have seen only 1 and 255 (for infinite repetitions),
+ // so maybe this is not really a problem.
loopStart = READ_BE_UINT16(ptr + 10) - READ_BE_UINT16(ptr + 8);
loopEnd = READ_BE_UINT16(ptr + 14);
flags |= Audio::Mixer::FLAG_LOOP;
}
-#endif
memcpy(sound, ptr + READ_BE_UINT16(ptr + 8), size);
_mixer->playRaw(Audio::Mixer::kSFXSoundType, NULL, sound, size, rate,
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index f00f4ff33b..e99bea87de 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -995,6 +995,11 @@ void ScummEngine::drawString(int a, const byte *msg) {
}
_string[a].xpos = _charset->_str.right;
+
+ if (_game.heversion >= 60) {
+ _string[a]._default.xpos = _string[a].xpos;
+ _string[a]._default.ypos = _string[a].ypos;
+ }
}
int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) {
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 22487b43a3..98e088365e 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -538,9 +538,7 @@ void ScummEngine_v8::setupScummVars() {
#endif
void ScummEngine_v0::resetScummVars() {
- _activeInventory = 0;
- _activeObject = 0;
- _activeVerb = 13;
+ resetSentence();
VAR(VAR_EGO) = 3;
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 81b28ce563..1ab9d72a58 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -155,6 +155,7 @@ void ScummEngine_v0::switchActor(int slot) {
VAR(VAR_EGO) = VAR(97 + slot);
actorFollowCamera(VAR(VAR_EGO));
resetVerbs();
+ resetSentence(false);
setUserState(247);
}
@@ -376,14 +377,8 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) {
if (object > 0) {
if (_game.version == 0) {
- if (_activeInventory != object) {
- _activeInventory = object;
- } else if (_activeVerb != 3 && _activeVerb != 13) {
- if (_activeObject)
- runObject(_activeObject, _activeVerb);
- else
- runObject(_activeInventory, _activeVerb);
- }
+ _activeInventory = object;
+
} else {
runInputScript(kInventoryClickArea, object, 0);
}
@@ -425,7 +420,9 @@ 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
@@ -629,14 +626,14 @@ void ScummEngine_v2::checkExecVerbs() {
if (vs->verbid && vs->saveid == 0 && vs->curmode == 1) {
if (_mouseAndKeyboardStat == vs->key) {
// Trigger verb as if the user clicked it
- runInputScript(1, vs->verbid, 1);
+ runInputScript(kVerbClickArea, vs->verbid, 1);
return;
}
}
}
// Generic keyboard input
- runInputScript(4, _mouseAndKeyboardStat, 1);
+ runInputScript(kKeyClickArea, _mouseAndKeyboardStat, 1);
} else if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
VirtScreen *zone = findVirtScreen(_mouse.y);
const byte code = _mouseAndKeyboardStat & MBS_LEFT_CLICK ? 1 : 2;
@@ -649,7 +646,7 @@ void ScummEngine_v2::checkExecVerbs() {
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
// Click into V2 sentence line
- runInputScript(5, 0, 0);
+ runInputScript(kSentenceClickArea, 0, 0);
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + inventoryArea) {
// Click into V2 inventory
checkV2Inventory(_mouse.x, _mouse.y);
@@ -657,7 +654,7 @@ void ScummEngine_v2::checkExecVerbs() {
over = findVerbAtPos(_mouse.x, _mouse.y);
if (over != 0) {
// Verb was clicked
- runInputScript(1, _verbs[over].verbid, code);
+ runInputScript(kVerbClickArea, _verbs[over].verbid, code);
} else {
// Scene was clicked
runInputScript((zone->number == kMainVirtScreen) ? kSceneClickArea : kVerbClickArea, 0, code);
@@ -666,6 +663,25 @@ void ScummEngine_v2::checkExecVerbs() {
}
}
+void ScummEngine_v0::runObject(int obj, int entry) {
+ int prev = _v0ObjectInInventory;
+
+ if (getVerbEntrypoint(obj, entry) != 0) {
+ _v0ObjectInInventory = prev;
+ runObjectScript(obj, entry, false, false, NULL);
+ } else if (entry != 13 && entry != 15) {
+ if (_activeVerb != 3) {
+ VAR(9) = entry;
+ runScript(3, 0, 0, 0);
+
+ // For some reasons, certain objects don't have a "give" script
+ } else if (VAR(5) > 0 && VAR(5) < 8) {
+ if (_activeInventory)
+ setOwnerOf(_activeInventory, VAR(5));
+ }
+ }
+}
+
void ScummEngine_v2::runObject(int obj, int entry) {
if (getVerbEntrypoint(obj, entry) != 0) {
runObjectScript(obj, entry, false, false, NULL);
@@ -679,10 +695,293 @@ void ScummEngine_v2::runObject(int obj, int entry) {
_activeVerb = 13;
}
+bool ScummEngine_v0::verbMoveToActor(int actor) {
+ Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+ Actor *a2 =derefActor(actor, "checkExecVerbs");
+
+ if (!a->_moving) {
+ int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
+ if (dist > 5)
+ a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, 1);
+ else
+ return false;
+
+ return true;
+ }
+
+ return true;
+}
+
+bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
+ int x, y, dir;
+ Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+
+ if (_currentMode != 3 && _currentMode != 2)
+ return false;
+
+ if (a->_moving)
+ return true;
+
+ _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);
+
+ // FIXME: This should be changed once the walkbox problem is fixed
+ if (dist > 0x5) {
+ 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;
+}
+
+bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
+ bool didPickup = false;
+
+ int prep, where = whereIsObjectInventory(obj);
+
+ if (objIndex == 0)
+ return false;
+
+ 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;
+ }
+
+ if (verbMove(obj, objIndex, false))
+ return true;
+
+ if (didPickup && (prep == 1 || prep == 4))
+ if (_activeVerb != 13 && _activeVerb != 14)
+ _activeInventory = obj;
+ }
+
+ return false;
+}
+
+int ScummEngine_v0::verbPrep(int object) {
+ if (!_v0ObjectInInventory)
+ _v0ObjectIndex = true;
+ else
+ _v0ObjectIndex = false;
+ byte *ptr = getOBCDFromObject(object);
+ _v0ObjectIndex = false;
+ assert(ptr);
+ return (*(ptr + 11) >> 5);
+}
+
+bool ScummEngine_v0::verbExecutes(int object, bool inventory) {
+ _v0ObjectInInventory = inventory;
+ int prep = verbPrep(object);
+
+ if (prep == 2 || prep == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+bool ScummEngine_v0::verbExec() {
+ int prep = 0;
+ int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
+
+ if ((!_activeInvExecute && _activeObject && getObjectIndex(_activeObject) == -1)) {
+ resetSentence();
+ return false;
+ }
+
+ // Lets try walk to the object
+ if (_activeObject && _activeObjectIndex && !_activeObjectObtained && _currentMode != 0) {
+ prep = verbPrep(_activeObjectIndex);
+
+ if (verbObtain(_activeObject, _activeObjectIndex))
+ return true;
+
+ _activeObjectObtained = true;
+ }
+
+ 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
+ // And walk to each other
+ if (verbMoveToActor(_activeActor))
+ return true;
+
+ _v0ObjectInInventory = true;
+ VAR(5) = _activeActor;
+ runObject(_activeInventory , 3);
+ _v0ObjectInInventory = false;
+
+ resetSentence();
+ return false;
+ }
+
+ if (_activeActor) {
+ _v0ObjectIndex = true;
+ runObject(_activeActor, entry);
+ _v0ObjectIndex = false;
+ _verbExecuting = false;
+
+ resetSentence();
+ 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();
+ return false;
+ }
+
+ // We acted on an inventory item
+ if (_activeInventory && verbExecutes(_activeInventory, true) && _activeVerb != 3) {
+ _v0ObjectInInventory = true;
+ runObject(_activeInventory, _activeVerb);
+
+ _verbExecuting = false;
+
+ if (_currentMode == 3 && _activeVerb == 13) {
+ resetSentence(true);
+ return false;
+ }
+
+ resetSentence();
+ return false;
+ }
+
+ if (_activeObject) {
+ _v0ObjectIndex = true;
+ runObject(_activeObjectIndex, entry);
+ _v0ObjectIndex = false;
+ } else if (_activeInventory) {
+ if (verbExecutes(_activeInventory, true) == false) {
+ if (_activeObject2 && verbExecutes(_activeObject2, true)) {
+ _v0ObjectInInventory = true;
+
+ _activeObject = _activeInventory;
+ _activeInventory = _activeObject2;
+
+ runObject(_activeObject, _activeVerb);
+ } else {
+ _v0ObjectInInventory = true;
+ runObject(_activeInventory, _activeVerb);
+ }
+ } else {
+ runObject(_activeInventory, _activeVerb);
+ _v0ObjectInInventory = true;
+ }
+ }
+
+ _verbExecuting = false;
+
+ if (_activeVerb == 13) {
+ resetSentence(true);
+ return false;
+ }
+
+ resetSentence();
+
+ return false;
+}
+
void ScummEngine_v0::checkExecVerbs() {
Actor *a;
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) {
+ _activeVerb = over;
+ _verbExecuting = false;
+ return;
+ }
+
+ if (!obj && !act && !over) {
+ resetSentence(false);
+ } else {
+ a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+ a->stopActorMoving();
+ }
+ } 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 (_userPut <= 0 || _mouseAndKeyboardStat == 0)
return;
@@ -693,61 +992,147 @@ void ScummEngine_v0::checkExecVerbs() {
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
// TODO
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
+ int prevInventory = _activeInventory;
+
// Click into V2 inventory
checkV2Inventory(_mouse.x, _mouse.y);
+ if (!_activeInventory)
+ return;
+
+ // Did we just change the selected inventory item?
+ if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) {
+ _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 ((_activeObject || _activeInventory) && act) {
+ obj = 0;
+ objIdx = 0;
+ }
// Handle New Kid verb options
- if (_activeVerb == 7) {
+ if (_activeVerb == 7 || over == 7) {
+ // Disable New-Kid (in the secret lab)
+ if (_currentMode == 2 || _currentMode == 0)
+ return;
+
+ if (_activeVerb != 7) {
+ _activeVerb = over;
+ over = 0;
+ }
+
if (over) {
_activeVerb = 13;
switchActor(_verbs[over].verbid - 1);
+ return;
}
+
+ setNewKidVerbs();
+
return;
}
+
+ // Clicked on nothing, walk here?
+ if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) {
+ // Clear all selected
+ resetSentence();
- if (over) {
- _activeVerb = _verbs[over].verbid;
- // Selected New Kid verb
- if (_activeVerb == 7)
- setNewKidVerbs();
+ // 0xB31
+ VAR(6) = _virtualMouse.x / V12_X_MULTIPLIER;
+ VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
+ if (zone->number == kMainVirtScreen) {
+ a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+ a->stopActorMoving();
+ a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1);
+ }
return;
}
- int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
- int obj = findObject(_virtualMouse.x, _virtualMouse.y);
- if (act != 0 && _activeVerb == 3 && _activeInventory != 0) {
- // Give inventory item to actor
- VAR(5) = act;
- runObject(_activeInventory, _activeVerb);
- } else if (obj) {
- if (_currentMode == 3 && _activeVerb != 13 && obj != _activeObject) {
- _activeObject = obj;
- return;
- }
+ // No new verb, use previous
+ if (over == 0)
+ over = _activeVerb;
- _activeObject = obj;
- if (_currentMode == 3) {
- int x, y, dir;
- a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
- getObjectXYPos(obj, x, y, dir);
- a->startWalkActor(x, y, dir);
+ // 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();
}
+ return;
+ }
- int entry = (_currentMode == 3) ? _activeVerb : 15;
- runObject(_activeObject, entry);
- } else if (zone->number == kMainVirtScreen) {
- a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
- a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1);
+ // 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;
+ }
+ }
}
- _activeInventory = 0;
- _activeObject = 0;
- _activeVerb = 13;
+ if (obj && obj != _activeObject) {
+ if (!_activeObject)
+ if (_activeInventory)
+ _activeInvExecute = true;
+
+ // USE
+ if (_activeVerb == 11 || _activeVerb == 8) {
+ if (obj != _activeObject || obj != _activeObject2) {
+ if (!_activeObject || _activeInventory) {
+ _activeObject = obj;
+ _activeObjectIndex = objIdx;
+ return;
+ } else {
+ if (_activeObject2 != obj) {
+ _activeObject2 = obj;
+ _activeObject2Index = objIdx;
+ return;
+ }
+ }
+ }
+ } else {
+ _activeObject = obj;
+ _activeObjectIndex = objIdx;
+
+ if (_activeVerb != 13)
+ return;
+
+ //return;
+ }
+ }
}
- }
+
+ _verbExecuting = true;
+
+ } // mouse k/b action
}
void ScummEngine::verbMouseOver(int verb) {
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index 991fbe19d0..5924197d96 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -27,6 +27,7 @@
#include "common/endian.h"
#include "common/rect.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "sky/autoroute.h"
@@ -73,7 +74,7 @@ void Logic::setupLogicTable() {
}
Logic::Logic(SkyCompact *skyCompact, Screen *skyScreen, Disk *skyDisk, Text *skyText, MusicBase *skyMusic, Mouse *skyMouse, Sound *skySound) {
- g_system->getEventManager()->registerRandomSource(_rnd, "sky");
+ g_eventRec.registerRandomSource(_rnd, "sky");
_skyCompact = skyCompact;
_skyScreen = skyScreen;
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 2d0d081ef6..7ed50461af 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -160,6 +160,9 @@ void MoviePlayer::play(void) {
stopEvent.kbd = Common::KEYCODE_ESCAPE;
stopEvents.push_back(stopEvent);
+ _textX = 0;
+ _textY = 0;
+
terminated = !playVideo(stopEvents);
if (terminated)
@@ -200,12 +203,15 @@ void MoviePlayer::performPostProcessing(byte *screen) {
}
}
+ byte *src, *dst;
+ int x, y;
+
if (_textMan->giveSpriteData(2)) {
- byte *src = (byte *)_textMan->giveSpriteData(2) + sizeof(FrameHeader);
- byte *dst = screen + _textY * _decoder->getWidth() + _textX * 1;
+ src = (byte *)_textMan->giveSpriteData(2) + sizeof(FrameHeader);
+ dst = screen + _textY * SCREEN_WIDTH + _textX * 1;
- for (int y = 0; y < _textHeight; y++) {
- for (int x = 0; x < _textWidth; x++) {
+ for (y = 0; y < _textHeight; y++) {
+ for (x = 0; x < _textWidth; x++) {
switch (src[x]) {
case BORDER_COL:
dst[x] = _decoder->getBlack();
@@ -216,8 +222,34 @@ void MoviePlayer::performPostProcessing(byte *screen) {
}
}
src += _textWidth;
- dst += _decoder->getWidth();
+ dst += SCREEN_WIDTH;
+ }
+ } else if (_textX && _textY) {
+ // If the frame doesn't cover the entire screen, we have to
+ // erase the subtitles manually.
+
+ int frameWidth = _decoder->getWidth();
+ int frameHeight = _decoder->getHeight();
+ int frameX = (_system->getWidth() - frameWidth) / 2;
+ int frameY = (_system->getHeight() - frameHeight) / 2;
+
+ dst = screen + _textY * _system->getWidth();
+
+ for (y = 0; y < _textHeight; y++) {
+ if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
+ memset(dst + _textX, _decoder->getBlack(), _textWidth);
+ } else {
+ if (frameX > _textX)
+ memset(dst + _textX, _decoder->getBlack(), frameX - _textX);
+ if (frameX + frameWidth < _textX + _textWidth)
+ memset(dst + frameX + frameWidth, _decoder->getBlack(), _textX + _textWidth - (frameX + frameWidth));
+ }
+
+ dst += _system->getWidth();
}
+
+ _textX = 0;
+ _textY = 0;
}
}
diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 756ce3a5cc..09d2197f2a 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -1207,7 +1207,7 @@ bool Control::restoreGameFromFile(uint8 slot) {
for (uint32 cnt2 = 0; cnt2 < playerSize; cnt2++)
playerBuf[cnt2] = inf->readUint32LE();
- if (inf->ioFailed()) {
+ if (inf->err() || inf->eos()) {
displayMessage(0, "Can't read from file '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
delete inf;
free(_restoreBuf);
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index 7e911bd197..be3797b0bd 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -28,6 +28,7 @@
#include "common/util.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "sword1/logic.h"
#include "sword1/text.h"
@@ -55,7 +56,7 @@ namespace Sword1 {
uint32 Logic::_scriptVars[NUM_SCRIPT_VARS];
Logic::Logic(SwordEngine *vm, ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Music *pMusic, Menu *pMenu, OSystem *system, Audio::Mixer *mixer) {
- g_system->getEventManager()->registerRandomSource(_rnd, "sword1");
+ g_eventRec.registerRandomSource(_rnd, "sword1");
_vm = vm;
_objMan = pObjMan;
diff --git a/engines/sword1/resman.cpp b/engines/sword1/resman.cpp
index 979bd3210a..90ea5fe677 100644
--- a/engines/sword1/resman.cpp
+++ b/engines/sword1/resman.cpp
@@ -263,9 +263,9 @@ void ResMan::resOpen(uint32 id) { // load resource ID into memory
_memMan->alloc(memHandle, size);
Common::File *clusFile = resFile(id);
assert(clusFile);
- clusFile->seek( resOffset(id) );
- clusFile->read( memHandle->data, size);
- if (clusFile->ioFailed()) {
+ clusFile->seek(resOffset(id));
+ clusFile->read(memHandle->data, size);
+ if (clusFile->err() || clusFile->eos()) {
error("Can't read %d bytes from offset %d from cluster file %s\nResource ID: %d (%08X)", size, resOffset(id), _prj.clu[(id >> 24) - 1].label, id, id);
}
} else
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index b23bf71445..6ad946b28d 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -28,6 +28,7 @@
#include "common/util.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "sword1/sound.h"
@@ -47,7 +48,7 @@ namespace Sword1 {
#define SPEECH_FLAGS (Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_LITTLE_ENDIAN)
Sound::Sound(const char *searchPath, Audio::Mixer *mixer, ResMan *pResMan) {
- g_system->getEventManager()->registerRandomSource(_rnd, "sword1sound");
+ g_eventRec.registerRandomSource(_rnd, "sword1sound");
strcpy(_filePath, searchPath);
_mixer = mixer;
_resMan = pResMan;
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 21ab645bfe..4a235315b6 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -116,7 +116,7 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI
terminated = !playVideo(stopEvents);
- closeTextObject(_currentMovieText);
+ closeTextObject(_currentMovieText, NULL);
if (terminated) {
_snd->stopHandle(*_bgSoundHandle);
@@ -171,7 +171,7 @@ void MoviePlayer::openTextObject(uint32 index) {
}
}
-void MoviePlayer::closeTextObject(uint32 index) {
+void MoviePlayer::closeTextObject(uint32 index, byte *screen) {
if (index < _numMovieTexts) {
MovieText *text = &_movieTexts[index];
@@ -179,6 +179,32 @@ void MoviePlayer::closeTextObject(uint32 index) {
text->_textMem = NULL;
if (_textSurface) {
+ if (screen) {
+ // If the frame doesn't cover the entire
+ // screen, we have to erase the subtitles
+ // manually.
+
+ int frameWidth = _decoder->getWidth();
+ int frameHeight = _decoder->getHeight();
+ int frameX = (_system->getWidth() - frameWidth) / 2;
+ int frameY = (_system->getHeight() - frameHeight) / 2;
+
+ byte *dst = screen + _textY * _system->getWidth();
+
+ for (int y = 0; y < text->_textSprite.h; y++) {
+ if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
+ memset(dst + _textX, _decoder->getBlack(), text->_textSprite.w);
+ } else {
+ if (frameX > _textX)
+ memset(dst + _textX, _decoder->getBlack(), frameX - _textX);
+ if (frameX + frameWidth < _textX + text->_textSprite.w)
+ memset(dst + frameX + frameWidth, _decoder->getBlack(), _textX + text->_textSprite.w - (frameX + frameWidth));
+ }
+
+ dst += _system->getWidth();
+ }
+ }
+
_vm->_screen->deleteSurface(_textSurface);
_textSurface = NULL;
}
@@ -204,7 +230,7 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
src = buffer;
}
- byte *dst = screen + _textY * _decoder->getWidth() + _textX;
+ byte *dst = screen + _textY * RENDERWIDE + _textX;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
@@ -214,15 +240,11 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
dst[x] = white;
}
src += width;
- dst += _decoder->getWidth();
+ dst += RENDERWIDE;
}
}
}
-// FIXME: This assumes that the subtitles always fit within the frame of the
-// movie. In Broken Sword 2, that's a fairly safe assumption, but not
-// necessarily in all other games.
-
void MoviePlayer::performPostProcessing(byte *screen) {
MovieText *text;
int frame = _decoder->getCurFrame();
@@ -247,6 +269,7 @@ void MoviePlayer::performPostProcessing(byte *screen) {
if (frame <= text->_endFrame) {
drawTextObject(_currentMovieText, screen);
} else {
+ closeTextObject(_currentMovieText, screen);
_currentMovieText++;
}
}
diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h
index 032350d2d6..f2b44baaa0 100644
--- a/engines/sword2/animation.h
+++ b/engines/sword2/animation.h
@@ -98,7 +98,7 @@ protected:
void performPostProcessing(byte *screen);
void openTextObject(uint32 index);
- void closeTextObject(uint32 index);
+ void closeTextObject(uint32 index, byte *screen);
void drawTextObject(uint32 index, byte *screen);
};
diff --git a/engines/sword2/resman.cpp b/engines/sword2/resman.cpp
index 6741be33f1..c49fb8e786 100644
--- a/engines/sword2/resman.cpp
+++ b/engines/sword2/resman.cpp
@@ -151,7 +151,7 @@ bool ResourceManager::init() {
for (i = 0; i < size / 2; i++)
_resConvTable[i] = file.readUint16LE();
- if (file.ioFailed()) {
+ if (file.eos() || file.err()) {
file.close();
GUIErrorMessage("Broken Sword 2: Cannot read resource.tab");
return false;
@@ -178,7 +178,7 @@ bool ResourceManager::init() {
cdInf[i].cd = file.readByte();
- if (file.ioFailed()) {
+ if (file.eos() || file.err()) {
delete cdInf;
file.close();
GUIErrorMessage("Broken Sword 2: Cannot read cd.inf");
@@ -477,7 +477,7 @@ void ResourceManager::readCluIndex(uint16 fileNum, Common::File *file) {
_resFiles[fileNum].entryTab = (uint32*)malloc(tableSize);
_resFiles[fileNum].numEntries = tableSize / 8;
file->read(_resFiles[fileNum].entryTab, tableSize);
- if (file->ioFailed())
+ if (file->eos() || file->err())
error("unable to read index table from file %s", _resFiles[fileNum].fileName);
#ifdef SCUMM_BIG_ENDIAN
diff --git a/engines/sword2/startup.cpp b/engines/sword2/startup.cpp
index 09bf65bf75..e4572d3c1a 100644
--- a/engines/sword2/startup.cpp
+++ b/engines/sword2/startup.cpp
@@ -66,7 +66,7 @@ bool Sword2Engine::initStartMenu() {
int start_ids[MAX_starts];
int lineno = 0;
- while (!fp.eos() && !fp.ioFailed()) {
+ while (!fp.eos() && !fp.err()) {
Common::String line = fp.readLine();
// Skip empty lines or, more likely, the end of the stream.
@@ -103,7 +103,7 @@ bool Sword2Engine::initStartMenu() {
}
// An I/O error before EOS? That's bad, but this is not a vital file.
- if (fp.ioFailed() && !fp.eos())
+ if (fp.err() && !fp.eos())
warning("I/O error while reading startup.inf");
fp.close();
diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
index cf44b4c99c..e368f257a2 100644
--- a/engines/sword2/sword2.cpp
+++ b/engines/sword2/sword2.cpp
@@ -33,6 +33,7 @@
#include "common/file.h"
#include "common/fs.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -305,7 +306,7 @@ Sword2Engine::Sword2Engine(OSystem *syst) : Engine(syst) {
_gmmLoadSlot = -1; // Used to manage GMM Loading
- syst->getEventManager()->registerRandomSource(_rnd, "sword2");
+ g_eventRec.registerRandomSource(_rnd, "sword2");
}
Sword2Engine::~Sword2Engine() {
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index a3f921505a..df3f95ca13 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -79,6 +79,8 @@ namespace Tinsel {
using Common::GUIO_NONE;
using Common::GUIO_NOSPEECH;
+using Common::GUIO_NOSFX;
+using Common::GUIO_NOMUSIC;
static const TinselGameDescription gameDescriptions[] = {
@@ -101,7 +103,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOSFX | GUIO_NOMUSIC
},
GID_DW1,
0,
diff --git a/engines/tinsel/heapmem.cpp b/engines/tinsel/heapmem.cpp
index e77f505edb..5db2918d2f 100644
--- a/engines/tinsel/heapmem.cpp
+++ b/engines/tinsel/heapmem.cpp
@@ -285,7 +285,8 @@ MEM_NODE *MemoryAlloc(int flags, long size) {
}
#ifdef SCUMM_NEED_ALIGNMENT
- size = (size + 3) & ~3; //round up to nearest multiple of 4, this ensures the addresses that are returned are 4-byte aligned as well.
+ 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
while ((flags & DWM_NOALLOC) == 0 && bCompacted) {
@@ -521,7 +522,7 @@ MEM_NODE *MemoryReAlloc(MEM_NODE *pMemNode, long size, int flags) {
assert(flags & (DWM_FIXED | DWM_MOVEABLE));
// align the size to machine boundary requirements
- size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1);
+ size = (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
// validate the size
assert(size);
diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp
index 62bcc732a8..0069778531 100644
--- a/engines/tinsel/saveload.cpp
+++ b/engines/tinsel/saveload.cpp
@@ -37,6 +37,8 @@
#include "common/serializer.h"
#include "common/savefile.h"
+#include "gui/message.h"
+
namespace Tinsel {
@@ -84,6 +86,8 @@ extern void syncGlobInfo(Common::Serializer &s);
// in POLYGONS.C
extern void syncPolyInfo(Common::Serializer &s);
+extern int sceneCtr;
+
//----------------- LOCAL DEFINES --------------------
struct SaveGameHeader {
@@ -450,6 +454,11 @@ static bool DoRestore() {
delete f;
+ if (failed) {
+ GUI::MessageDialog dialog("Failed to load game state from file.");
+ dialog.runModal();
+ }
+
return !failed;
}
@@ -471,11 +480,11 @@ static void DoSave(void) {
fname = SaveSceneName;
f = _vm->getSaveFileMan()->openForSaving(fname);
- if (f == NULL)
- return;
-
Common::Serializer s(0, f);
+ if (f == NULL)
+ goto save_failure;
+
// Write out a savegame header
SaveGameHeader hdr;
hdr.id = SAVEGAME_ID;
@@ -500,8 +509,12 @@ static void DoSave(void) {
return;
save_failure:
- delete f;
- _vm->getSaveFileMan()->removeSavefile(fname);
+ if (f) {
+ delete f;
+ _vm->getSaveFileMan()->removeSavefile(fname);
+ }
+ GUI::MessageDialog dialog("Failed to save game state to file.");
+ dialog.runModal();
}
/**
@@ -510,6 +523,10 @@ save_failure:
void ProcessSRQueue(void) {
switch (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 (DoRestore()) {
DoRestoreScene(srsd, false);
}
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 95541e3287..5f056351b6 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -26,6 +26,7 @@
#include "common/endian.h"
#include "common/error.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/keyboard.h"
#include "common/file.h"
#include "common/savefile.h"
@@ -934,7 +935,7 @@ Common::Error TinselEngine::run() {
_screenSurface.create(320, 200, 1);
}
- g_system->getEventManager()->registerRandomSource(_random, "tinsel");
+ g_eventRec.registerRandomSource(_random, "tinsel");
_console = new Console();
diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
index 5d79e0fb9a..1a6546cb4c 100644
--- a/engines/touche/touche.cpp
+++ b/engines/touche/touche.cpp
@@ -26,6 +26,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "graphics/cursorman.h"
@@ -73,7 +74,7 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
Common::addDebugChannel(kDebugOpcodes, "Opcodes", "Opcodes debug level");
Common::addDebugChannel(kDebugMenu, "Menu", "Menu debug level");
- _eventMan->registerRandomSource(_rnd, "touche");
+ g_eventRec.registerRandomSource(_rnd, "touche");
}
ToucheEngine::~ToucheEngine() {
diff --git a/engines/tucker/locations.cpp b/engines/tucker/locations.cpp
index 4117391cdf..011410fe07 100644
--- a/engines/tucker/locations.cpp
+++ b/engines/tucker/locations.cpp
@@ -1671,7 +1671,7 @@ void TuckerEngine::execData3PreUpdate_locationNum26() {
void TuckerEngine::updateSprite_locationNum27(int i) {
int state;
- if (_flagsTable[155] < 3 || _flagsTable[125] == 5) {
+ if (_flagsTable[155] < 3 || _flagsTable[155] == 5) {
state = -1;
} else if (_flagsTable[155] == 3) {
state = 1;
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index b68f4822d8..a575ee8b94 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -366,22 +366,24 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) {
uint8 r, g, b;
uint lum;
- const uint32 shiftMask = (uint32)~(
- (1 << _format.rShift) | (1 << _format.gShift) | (1 << _format.bShift) | (_format.aLoss == 8 ? 0 : (1 << _format.aShift))) >> 1;
+ // Mask to clear the last bit of every color component and all unused bits
+ const uint32 colorMask = ~((1 << _format.rShift) | (1 << _format.gShift) | (1 << _format.bShift) // R/G/B components
+ | (_format.aLoss == 8 ? 0 : (1 << _format.aShift)) // Alpha component
+ | ~(_alphaMask | _redMask | _greenMask | _blueMask)); // All unused bits
if (shadingStyle == GUI::ThemeEngine::kShadingDim) {
int n = (pixels + 7) >> 3;
switch (pixels % 8) {
case 0: do {
- *ptr = (*ptr >> 1) & shiftMask; ++ptr;
- case 7: *ptr = (*ptr >> 1) & shiftMask; ++ptr;
- case 6: *ptr = (*ptr >> 1) & shiftMask; ++ptr;
- case 5: *ptr = (*ptr >> 1) & shiftMask; ++ptr;
- case 4: *ptr = (*ptr >> 1) & shiftMask; ++ptr;
- case 3: *ptr = (*ptr >> 1) & shiftMask; ++ptr;
- case 2: *ptr = (*ptr >> 1) & shiftMask; ++ptr;
- case 1: *ptr = (*ptr >> 1) & shiftMask; ++ptr;
+ *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);
}
@@ -421,10 +423,10 @@ calcGradient(uint32 pos, uint32 max) {
PixelType output = 0;
pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max;
- 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 |= ~(_redMask | _greenMask | _blueMask);
+ 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;
return output;
}
diff --git a/graphics/module.mk b/graphics/module.mk
index 2387bb708c..ed14051243 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -37,6 +37,12 @@ MODULE_OBJS += \
scaler/scale3x.o \
scaler/scalebit.o
+ifdef USE_ARM_SCALER_ASM
+MODULE_OBJS += \
+ scaler/scale2xARM.o \
+ scaler/Normal2xARM.o
+endif
+
ifndef DISABLE_HQ_SCALERS
MODULE_OBJS += \
scaler/hq2x.o \
diff --git a/graphics/scaler.cpp b/graphics/scaler.cpp
index 082258bfc0..8c677cc083 100644
--- a/graphics/scaler.cpp
+++ b/graphics/scaler.cpp
@@ -186,6 +186,57 @@ void Normal1x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPit
}
#ifndef DISABLE_SCALERS
+#ifdef USE_ARM_SCALER_ASM
+extern "C" void Normal2xAspectMask(const uint8 *srcPtr,
+ uint32 srcPitch,
+ uint8 *dstPtr,
+ uint32 dstPitch,
+ int width,
+ int height,
+ uint32 mask);
+
+void Normal2xAspect(const uint8 *srcPtr,
+ uint32 srcPitch,
+ uint8 *dstPtr,
+ uint32 dstPitch,
+ int width,
+ int height) {
+ if (gBitFormat == 565) {
+ Normal2xAspectMask(srcPtr,
+ srcPitch,
+ dstPtr,
+ dstPitch,
+ width,
+ height,
+ 0x07e0F81F);
+ } else {
+ Normal2xAspectMask(srcPtr,
+ srcPitch,
+ dstPtr,
+ dstPitch,
+ width,
+ height,
+ 0x03e07C1F);
+ }
+}
+
+extern "C" void Normal2xARM(const uint8 *srcPtr,
+ uint32 srcPitch,
+ uint8 *dstPtr,
+ uint32 dstPitch,
+ int width,
+ int height);
+
+void Normal2x(const uint8 *srcPtr,
+ uint32 srcPitch,
+ uint8 *dstPtr,
+ uint32 dstPitch,
+ int width,
+ int height) {
+ Normal2xARM(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
+}
+
+#else
/**
* Trivial nearest-neighbour 2x scaler.
*/
@@ -209,6 +260,7 @@ void Normal2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPit
dstPtr += dstPitch << 1;
}
}
+#endif
/**
* Trivial nearest-neighbour 3x scaler.
diff --git a/graphics/scaler.h b/graphics/scaler.h
index 4cea9ee2fb..bdae161bd1 100644
--- a/graphics/scaler.h
+++ b/graphics/scaler.h
@@ -45,6 +45,9 @@ DECLARE_SCALER(AdvMame2x);
DECLARE_SCALER(AdvMame3x);
DECLARE_SCALER(Normal1x);
DECLARE_SCALER(Normal2x);
+#ifdef USE_ARM_SCALER_ASM
+DECLARE_SCALER(Normal2xAspect);
+#endif
DECLARE_SCALER(Normal3x);
DECLARE_SCALER(Normal1o5x);
DECLARE_SCALER(TV2x);
diff --git a/graphics/scaler/Normal2xARM.s b/graphics/scaler/Normal2xARM.s
new file mode 100755
index 0000000000..5de50d9c17
--- /dev/null
+++ b/graphics/scaler/Normal2xARM.s
@@ -0,0 +1,171 @@
+@ ScummVM Scumm Interpreter
+@ Copyright (C) 2009 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
+@ of the License, or (at your option) any later version.
+@
+@ This program is distributed in the hope that it will be useful,
+@ but WITHOUT ANY WARRANTY@ without even the implied warranty of
+@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+@ GNU General Public License for more details.
+@
+@ You should have received a copy of the GNU General Public License
+@ along with this program@ if not, write to the Free Software
+@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+@
+@ $URL$
+@ $Id$
+@
+@ @author Robin Watts (robin@wss.co.uk)
+
+ .text
+
+ .global Normal2xARM
+ .global Normal2xAspectMask
+
+
+ @ Assumes dst is aligned (so did the C)
+ @ Assumes 16bit (so did the C)
+Normal2xARM:
+ @ r0 = src
+ @ r1 = srcPitch
+ @ r2 = dst
+ @ r3 = dstPitch
+ @ r4 = w
+ @ r5 = h
+ STMFD r13!,{r4-r11,r14}
+ LDR r4, [r13,#4*9] @ r4 = w
+ LDR r5, [r13,#4*10] @ r5 = h
+ ADD r12,r2, r3
+ SUB r1, r1, r4, LSL #1
+ SUB r6, r3, r4, LSL #2
+ ADD r3, r3, r6
+yloop:
+ SUBS r14,r4, #4
+ BLT thin
+xloop:
+ LDRH r6, [r0], #2
+ LDRH r7, [r0], #2
+ LDRH r8, [r0], #2
+ LDRH r9, [r0], #2
+ ORR r6, r6, r6, LSL #16
+ ORR r7, r7, r7, LSL #16
+ ORR r8, r8, r8, LSL #16
+ ORR r9, r9, r9, LSL #16
+ STMIA r2!, {r6-r9}
+ STMIA r12!,{r6-r9}
+ SUBS r14,r14,#4
+ BGE xloop
+ ADDS r14,r14,#4
+ BNE thin
+ ADD r0, r0, r1
+ ADD r2, r2, r3
+ ADD r12,r12,r3
+ SUBS r5, r5, #1
+ BGT yloop
+
+ LDMFD r13!,{r4-r11,PC}
+thin:
+ LDRH r6, [r0], #2
+ ORR r6, r6, r6, LSL #16
+ STR r6, [r2], #4
+ STR r6, [r12],#4
+ SUBS r14,r14,#1
+ BGT thin
+ ADD r0, r0, r1
+ ADD r2, r2, r3
+ ADD r12,r12,r3
+ SUBS r5, r5, #1
+ BGT yloop
+
+ LDMFD r13!,{r4-r11,PC}
+
+
+ @ Horrid filter calculations
+ @ AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDDDDDDDDDDDDEEEEEEEEEEEE
+ @ <-+-><-+-><-+-><-+-><-+-><-+-><-+-><-+-><-+-><-+-><-+-><-+->
+ @ Ideal: A,A,(A*2+B*3)/5,B,(B*4+C)/5,C,C,(C+D*4)/5,D,(D*3+E*2)/5,E,E
+ @ Actual: A,A,(A*3+B*5)/8,B,(B*7+C)/8,C,C,(C+D*7)/8,D,(D*5+E*3)/8,E,E
+
+ @ Assumes dst is aligned (so did the C)
+ @ Assumes 16bit (so did the C)
+Normal2xAspectMask:
+ @ r0 = src
+ @ r1 = srcPitch
+ @ r2 = dst
+ @ r3 = dstPitch
+ @ r4 = w
+ @ r5 = h
+ @ r12= mask
+ STMFD r13!,{r4-r11,r14}
+ LDR r4, [r13,#4*9] @ r4 = w
+ LDR r5, [r13,#4*10] @ r5 = h
+ LDR r12,[r13,#4*11] @ r12= mask
+ MOV r11,#2
+ SUB r11,r11,r1, LSL #2 @ r11= 2-srcPitch*4
+ MOV r14,#4
+ SUB r14,r14,r3, LSL #3
+ SUB r14,r14,r3, LSL #1
+ SUB r14,r14,r3 @ r14 = 4-dstPitch*11
+yloop_aspect:
+xloop_aspect:
+ LDRH r6, [r0], r1 @ r6 = A
+ LDRH r7, [r0], r1 @ r7 = B
+ LDRH r8, [r0], r1 @ r8 = C
+ LDRH r9, [r0], r1 @ r9 = D
+ LDRH r10,[r0], r11 @ r10= E
+ ORR r6, r6, r6, LSL #16 @ r6 = output 0, 1
+ ORR r7, r7, r7, LSL #16 @ r7 = output 3
+ ORR r8, r8, r8, LSL #16 @ r8 = output 5,6
+ ORR r9, r9, r9, LSL #16 @ r9 = output 8
+ ORR r10,r10,r10,LSL #16 @ r10= output 10, 11
+ STR r6, [r2], r3 @ output 0 (A)
+ STR r6, [r2], r3 @ output 1 (A)
+ AND r6, r6, r12 @ r6 = A split
+ ADD r6, r6, r6, LSL #1 @ r6 = A*3
+ STR r7, [r2, r3] @ output 3 (B)
+ AND r7, r7, r12 @ r7 = B split
+ ADD r6, r6, r7 @ r6 = A*3 + B
+ ADD r6, r6, r7, LSL #2 @ r6 = A*3 + B*5
+ AND r6, r12,r6, LSR #3 @ r6 = (A*3 + B*5)>>3
+ ORR r6, r6, r6, ROR #16 @ r6 = output 2
+ STR r6, [r2], r3, LSL #1 @ output 2 (A*3+B*5)>>3
+ RSB r7, r7, r7, LSL #3 @ r7 = B*7
+ AND r6, r8, r12 @ r6 = C split
+ ADD r7, r7, r6 @ r7 = B*7+C
+ AND r7, r12,r7, LSR #3 @ r7 = (B*7 + C)>>3
+ ORR r7, r7, r7, ROR #16 @ r7 = output 4
+ STR r7, [r2], r3 @ output 4 (B*7+C)>>3
+ STR r8, [r2], r3 @ output 5 (C)
+ STR r8, [r2], r3 @ output 6 (C)
+ STR r9, [r2, r3] @ output 8 (D)
+ AND r9, r9, r12 @ r9 = D split
+ RSB r7, r9, r9, LSL #3 @ r7 = D*7
+ ADD r6, r6, r7 @ r6 = C+D*7
+ AND r6, r12,r6, LSR #3 @ r6 = (C + D*7)>>3
+ ORR r6, r6, r6, ROR #16 @ r6 = output 7
+ STR r6, [r2], r3, LSL #1 @ output 7 (C+D*7)>>3
+ ADD r9, r9, r9, LSL #2 @ r9 = D*5
+ AND r6, r10,r12 @ r6 = E split
+ ADD r9, r9, r6 @ r9 = D*5+E
+ ADD r9, r9, r6, LSL #1 @ r9 = D*5+E*3
+ AND r9, r12,r9, LSR #3 @ r9 = (D*5 + E*3)>>3
+ ORR r9, r9, r9, ROR #16 @ r9 = output 9
+ STR r9, [r2], r3 @ output 9 (D*5+E*3)>>3
+ STR r10,[r2], r3 @ output 10 (E)
+ STR r10,[r2], r14 @ output 11 (E)
+ SUBS r4, r4, #1
+ BGT xloop_aspect
+ LDR r4, [r13,#4*9] @ r4 = w
+ ADD r0, r0, r1, LSL #2
+ ADD r0, r0, r1
+ SUB r0, r0, r4, LSL #1
+ ADD r2, r2, r3, LSL #3
+ ADD r2, r2, r3, LSL #2
+ SUB r2, r2, r4, LSL #2
+ SUBS r5, r5, #5
+ BGT yloop_aspect
+
+ LDMFD r13!,{r4-r11,PC}
diff --git a/graphics/scaler/scale2x.cpp b/graphics/scaler/scale2x.cpp
index 226d379c91..877bbb9509 100644
--- a/graphics/scaler/scale2x.cpp
+++ b/graphics/scaler/scale2x.cpp
@@ -158,7 +158,7 @@ void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_ui
/***************************************************************************/
/* Scale2x MMX implementation */
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
/*
* Apply the Scale2x effect at a single row.
@@ -205,7 +205,7 @@ static inline void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8*
__asm__ __volatile__(
/* central runs */
- "shrl $3, %4\n"
+ "shr $3, %4\n"
"jz 1f\n"
"0:\n"
@@ -261,12 +261,12 @@ static inline void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8*
"movq %%mm3, 8(%3)\n"
/* next */
- "addl $8, %0\n"
- "addl $8, %1\n"
- "addl $8, %2\n"
- "addl $16, %3\n"
+ "add $8, %0\n"
+ "add $8, %1\n"
+ "add $8, %2\n"
+ "add $16, %3\n"
- "decl %4\n"
+ "dec %4\n"
"jnz 0b\n"
"1:\n"
@@ -283,7 +283,7 @@ static inline void scale2x_16_mmx_single(scale2x_uint16* dst, const scale2x_uint
__asm__ __volatile__(
/* central runs */
- "shrl $2, %4\n"
+ "shr $2, %4\n"
"jz 1f\n"
"0:\n"
@@ -339,12 +339,12 @@ static inline void scale2x_16_mmx_single(scale2x_uint16* dst, const scale2x_uint
"movq %%mm3, 8(%3)\n"
/* next */
- "addl $8, %0\n"
- "addl $8, %1\n"
- "addl $8, %2\n"
- "addl $16, %3\n"
+ "add $8, %0\n"
+ "add $8, %1\n"
+ "add $8, %2\n"
+ "add $16, %3\n"
- "decl %4\n"
+ "dec %4\n"
"jnz 0b\n"
"1:\n"
@@ -361,7 +361,7 @@ static inline void scale2x_32_mmx_single(scale2x_uint32* dst, const scale2x_uint
__asm__ __volatile__(
/* central runs */
- "shrl $1, %4\n"
+ "shr $1, %4\n"
"jz 1f\n"
"0:\n"
@@ -417,12 +417,12 @@ static inline void scale2x_32_mmx_single(scale2x_uint32* dst, const scale2x_uint
"movq %%mm3, 8(%3)\n"
/* next */
- "addl $8, %0\n"
- "addl $8, %1\n"
- "addl $8, %2\n"
- "addl $16, %3\n"
+ "add $8, %0\n"
+ "add $8, %1\n"
+ "add $8, %2\n"
+ "add $16, %3\n"
- "decl %4\n"
+ "dec %4\n"
"jnz 0b\n"
"1:\n"
diff --git a/graphics/scaler/scale2x.h b/graphics/scaler/scale2x.h
index 2101790905..cefa14f22a 100644
--- a/graphics/scaler/scale2x.h
+++ b/graphics/scaler/scale2x.h
@@ -33,7 +33,7 @@ void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
@@ -52,5 +52,13 @@ static inline void scale2x_mmx_emms(void)
#endif
+#if defined(USE_ARM_SCALER_ASM)
+
+extern "C" void scale2x_8_arm(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
+extern "C" void scale2x_16_arm(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
+extern "C" void scale2x_32_arm(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
+
+#endif
+
#endif
diff --git a/graphics/scaler/scale2xARM.s b/graphics/scaler/scale2xARM.s
new file mode 100755
index 0000000000..3ca237e02d
--- /dev/null
+++ b/graphics/scaler/scale2xARM.s
@@ -0,0 +1,182 @@
+@ ScummVM Scumm Interpreter
+@ Copyright (C) 2009 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
+@ of the License, or (at your option) any later version.
+@
+@ This program is distributed in the hope that it will be useful,
+@ but WITHOUT ANY WARRANTY@ without even the implied warranty of
+@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+@ GNU General Public License for more details.
+@
+@ You should have received a copy of the GNU General Public License
+@ along with this program@ if not, write to the Free Software
+@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+@
+@ $URL$
+@ $Id$
+@
+@ @author Robin Watts (robin@wss.co.uk)
+
+ .text
+
+ .global scale2x_8_arm
+ .global scale2x_16_arm
+ .global scale2x_32_arm
+
+ @ r0 = dst0
+ @ r1 = dst1
+ @ r2 = src
+ @ r3 = src_prev
+ @ r4 = src_next
+ @ r5 = len
+
+
+ @ We hold: r10 B
+ @ r8 r14 r7 D E F
+ @ r12 H
+scale2x_8_arm:
+ STMFD r13!,{r4-r5,r7-r8,r10-r11,r14}
+ LDR r4, [r13,#4*7]
+ LDR r5, [r13,#4*8]
+
+ LDRB r14,[r2], #1
+ CMP r3, #0 @ Set NE
+ @ Stall on Xscale
+ MOV r8, r14
+ B loop8
+same8:
+ STRB r14,[r0], #1
+ STRB r14,[r0], #1
+ STRB r14,[r1], #1
+ STRB r14,[r1], #1
+ SUBS r5, r5, #1
+ MOV r8, r14
+ MOV r14,r7
+ BLT end8
+loop8:
+ LDRNEB r7, [r3], #1 @ As long as we aren't on the last pixel
+ LDRB r10,[r2], #1
+ LDRB r12,[r4], #1
+ @ Stall on Xscale
+ CMP r7, r8
+ CMPNE r10,r12
+ BEQ same8
+ CMP r8, r10
+ STREQB r8, [r0], #1
+ STRNEB r14,[r0], #1
+ CMP r10,r7
+ STREQB r7, [r0], #1
+ STRNEB r14,[r0], #1
+ CMP r8, r12
+ STREQB r8, [r1], #1
+ STRNEB r14,[r1], #1
+ CMP r12,r7
+ STREQB r7, [r1], #1
+ STRNEB r14,[r1], #1
+
+ SUBS r5, r5, #1
+ MOV r8, r14
+ MOV r14,r7
+ BGE loop8
+end8:
+
+ LDMFD r13!,{r4-r5,r7-r8,r10-r11,PC}
+
+scale2x_16_arm:
+ STMFD r13!,{r4-r5,r7-r8,r10-r11,r14}
+ LDR r4, [r13,#4*7]
+ LDR r5, [r13,#4*8]
+
+ LDRH r14,[r3], #2
+ CMP r3, #0 @ Set NE
+ @ Stall on Xscale
+ MOV r8, r14
+ B loop16
+same16:
+ STRH r14,[r0], #2
+ STRH r14,[r0], #2
+ STRH r14,[r1], #2
+ STRH r14,[r1], #2
+ SUBS r5, r5, #1
+ MOV r8, r14
+ MOV r14,r7
+ BLT end16
+loop16:
+ LDRNEH r7, [r3], #2 @ As long as we aren't on the last pixel
+ LDRH r10,[r2], #2
+ LDRH r12,[r4], #2
+ @ Stall on Xscale
+ CMP r7, r8
+ CMPNE r10,r12
+ BEQ same16
+ CMP r8, r10
+ STREQH r8, [r0], #2
+ STRNEH r14,[r0], #2
+ CMP r10,r7
+ STREQH r7, [r0], #2
+ STRNEH r14,[r0], #2
+ CMP r8, r12
+ STREQH r8, [r1], #2
+ STRNEH r14,[r1], #2
+ CMP r12,r7
+ STREQH r7, [r1], #2
+ STRNEH r14,[r1], #2
+
+ SUBS r5, r5, #1
+ MOV r8, r14
+ MOV r14,r7
+ BGE loop16
+end16:
+
+ LDMFD r13!,{r4-r5,r7-r8,r10-r11,PC}
+
+scale2x_32_arm:
+ STMFD r13!,{r4-r5,r7-r8,r10-r11,r14}
+ LDR r4, [r13,#4*7]
+ LDR r5, [r13,#4*8]
+
+ LDR r14,[r3], #4
+ CMP r3, #0 @ Set NE
+ @ Stall on Xscale
+ MOV r8, r14
+ B loop32
+same32:
+ STR r14,[r0], #4
+ STR r14,[r0], #4
+ STR r14,[r1], #4
+ STR r14,[r1], #4
+ SUBS r5, r5, #1
+ MOV r8, r14
+ MOV r14,r7
+ BLT end32
+loop32:
+ LDRNE r7, [r3], #4 @ As long as we aren't on the last pixel
+ LDR r10,[r2], #4
+ LDR r12,[r4], #4
+ @ Stall on Xscale
+ CMP r7, r8
+ CMPNE r10,r12
+ BEQ same32
+ CMP r8, r10
+ STREQ r8, [r0], #4
+ STRNE r14,[r0], #4
+ CMP r10,r7
+ STREQ r7, [r0], #4
+ STRNE r14,[r0], #4
+ CMP r8, r12
+ STREQ r8, [r1], #4
+ STRNE r14,[r1], #4
+ CMP r12,r7
+ STREQ r7, [r1], #4
+ STRNE r14,[r1], #4
+
+ SUBS r5, r5, #1
+ MOV r8, r14
+ MOV r14,r7
+ BGE loop32
+end32:
+
+ LDMFD r13!,{r4-r5,r7-r8,r10-r11,PC}
diff --git a/graphics/scaler/scalebit.cpp b/graphics/scaler/scalebit.cpp
index a6fd8df58f..6a3b47b0f5 100644
--- a/graphics/scaler/scalebit.cpp
+++ b/graphics/scaler/scalebit.cpp
@@ -55,10 +55,14 @@
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
{
switch (pixel) {
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
case 1 : scale2x_8_mmx(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
case 2 : scale2x_16_mmx(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
case 4 : scale2x_32_mmx(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
+#elif defined(USE_ARM_SCALER_ASM)
+ case 1 : scale2x_8_arm(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
+ case 2 : scale2x_16_arm(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
+ case 4 : scale2x_32_arm(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
#else
case 1 : scale2x_8_def(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
case 2 : scale2x_16_def(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
@@ -125,7 +129,7 @@ static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, un
--count;
}
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
scale2x_mmx_emms();
#endif
}
@@ -225,7 +229,7 @@ static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsi
--count;
}
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
scale2x_mmx_emms();
#endif
}
@@ -303,7 +307,7 @@ int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned
break;
}
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
switch (scale) {
case 2 :
case 4 :
diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp
index 5392a1c9a4..405d8622c2 100644
--- a/graphics/sjis.cpp
+++ b/graphics/sjis.cpp
@@ -27,17 +27,33 @@
#ifdef GRAPHICS_SJIS_H
#include "common/debug.h"
+#include "common/archive.h"
+#include "common/endian.h"
namespace Graphics {
-bool FontTowns::loadFromStream(Common::ReadStream &stream) {
- for (uint i = 0; i < (kFontRomSize / 2); ++i)
- _fontData[i] = stream.readUint16BE();
- return !stream.err();
+FontSJIS *FontSJIS::createFont(const Common::Platform platform) {
+ FontSJIS *ret = 0;
+
+ // Try the font ROM of the specified platform
+ if (platform == Common::kPlatformFMTowns) {
+ ret = new FontTowns();
+ if (ret && ret->loadData())
+ return ret;
+ delete ret;
+ }
+
+ // Try ScummVM's font.
+ ret = new FontSjisSVM();
+ if (ret && ret->loadData())
+ return ret;
+ delete ret;
+
+ return 0;
}
template<typename Color>
-void FontTowns::drawCharInternOutline(const uint16 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const {
+void FontSJIS16x16::drawCharInternOutline(const uint16 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const {
uint32 outlineGlyph[18];
memset(outlineGlyph, 0, sizeof(outlineGlyph));
@@ -72,7 +88,7 @@ void FontTowns::drawCharInternOutline(const uint16 *glyph, uint8 *dst, int pitch
}
template<typename Color>
-void FontTowns::drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const {
+void FontSJIS16x16::drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const {
for (int y = 0; y < 16; ++y) {
Color *lineBuf = (Color *)dst;
uint16 line = *glyph++;
@@ -88,8 +104,12 @@ void FontTowns::drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color
}
}
-void FontTowns::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const {
- const uint16 *glyphSource = _fontData + sjisToChunk(ch & 0xFF, ch >> 8) * 16;
+void FontSJIS16x16::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const {
+ const uint16 *glyphSource = getCharData(ch);
+ if (!glyphSource) {
+ warning("FontSJIS16x16::drawChar: Font does not offer data for %02X %02X", ch & 0xFF, ch >> 8);
+ return;
+ }
if (bpp == 1) {
if (!_outlineEnabled)
@@ -106,7 +126,25 @@ void FontTowns::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, ui
}
}
-uint FontTowns::sjisToChunk(uint8 f, uint8 s) {
+// FM-TOWNS ROM font
+
+bool FontTowns::loadData() {
+ Common::SeekableReadStream *data = SearchMan.createReadStreamForMember("FMT_FNT.ROM");
+ if (!data)
+ return false;
+
+ for (uint i = 0; i < (kFontRomSize / 2); ++i)
+ _fontData[i] = data->readUint16BE();
+
+ bool retValue = !data->err();
+ delete data;
+ return retValue;
+}
+
+const uint16 *FontTowns::getCharData(uint16 ch) const {
+ uint8 f = ch & 0xFF;
+ uint8 s = ch >> 8;
+
// copied from scumm\charset.cpp
enum {
KANA = 0,
@@ -188,7 +226,61 @@ uint FontTowns::sjisToChunk(uint8 f, uint8 s) {
}
debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
- return ((chunk_f + chunk) * 32 + (s - base)) + cr;
+ return _fontData + (((chunk_f + chunk) * 32 + (s - base)) + cr) * 16;
+}
+
+// ScummVM SJIS font
+
+bool FontSjisSVM::loadData() {
+ Common::SeekableReadStream *data = SearchMan.createReadStreamForMember("SJIS.FNT");
+ if (!data)
+ return false;
+
+ uint32 magic1 = data->readUint32BE();
+ uint32 magic2 = data->readUint32BE();
+
+ if (magic1 != MKID_BE('SCVM') || magic2 != MKID_BE('SJIS')) {
+ delete data;
+ return false;
+ }
+
+ uint32 version = data->readUint32BE();
+ if (version != 1) {
+ delete data;
+ return false;
+ }
+ uint numChars = data->readUint16BE();
+
+ _fontData = new uint16[numChars * 16];
+ assert(_fontData);
+
+ for (uint i = 0; i < numChars * 16; ++i)
+ _fontData[i] = data->readUint16BE();
+
+ bool retValue = !data->err();
+ delete data;
+ return retValue;
+}
+
+const uint16 *FontSjisSVM::getCharData(uint16 c) const {
+ const uint8 fB = c & 0xFF;
+ const uint8 sB = c >> 8;
+
+ // We only allow 2 byte SJIS characters.
+ if (fB <= 0x80 || fB >= 0xF0 || (fB >= 0xA0 && fB <= 0xDF) || sB == 0x7F)
+ return 0;
+
+ int base = fB;
+ base -= 0x81;
+ if (base >= 0x5F)
+ base -= 0x40;
+
+ int index = sB;
+ index -= 0x40;
+ if (index >= 0x3F)
+ --index;
+
+ return _fontData + (base * 0xBC + index) * 16;
}
} // end of namespace Graphics
diff --git a/graphics/sjis.h b/graphics/sjis.h
index f7321742af..b5d997a19a 100644
--- a/graphics/sjis.h
+++ b/graphics/sjis.h
@@ -35,6 +35,7 @@
#include "common/scummsys.h"
#include "common/stream.h"
+#include "common/util.h"
#include "graphics/surface.h"
@@ -50,6 +51,24 @@ public:
virtual ~FontSJIS() {}
/**
+ * Creates the first SJIS font, which ROM/font file is present.
+ * It will also call loadData, so the user can just start
+ * using the font.
+ *
+ * It'll prefer the platform specific ROM file, when platform
+ * is set to a value, which's font ROM is supported.
+ * So far that is only kPlatformFMTowns.
+ *
+ * The last file tried is ScummVM's SJIS.FNT file.
+ */
+ static FontSJIS *createFont(const Common::Platform platform = Common::kPlatformUnknown);
+
+ /**
+ * Load the font data.
+ */
+ virtual bool loadData() = 0;
+
+ /**
* Enable outline drawing.
*
* After changing outline state, getFontHeight and getFontWidth might return
@@ -69,6 +88,10 @@ public:
/**
* Draws a SJIS encoded character on the given surface.
+ *
+ * TODO: Currently there is no assurance, that this method will only draw within
+ * the surface boundaries. Thus the caller has to assure the glyph will fit at
+ * the specified position.
*/
void drawChar(Graphics::Surface &dst, uint16 ch, int x, int y, uint32 c1, uint32 c2) const {
drawChar(dst.getBasePtr(x, y), ch, c1, c2, dst.pitch, dst.bytesPerPixel);
@@ -78,7 +101,7 @@ public:
* Draws a SJIS char on the given raw buffer.
*
* @param dst pointer to the destination
- * @param ch character to draw
+ * @param ch character to draw (in little endian)
* @param pitch pitch of the destination buffer (size in *bytes*)
* @param bpp bytes per pixel of the destination buffer
* @param c1 forground color
@@ -88,18 +111,11 @@ public:
};
/**
- * FM-TOWNS ROM based SJIS compatible font.
- *
- * This is used in KYRA and SCI.
+ * A base class to render 16x16 monochrome SJIS fonts.
*/
-class FontTowns : public FontSJIS {
+class FontSJIS16x16 : public FontSJIS {
public:
- FontTowns() : _outlineEnabled(false) {}
-
- /**
- * Loads the ROM data from the given read stream.
- */
- bool loadFromStream(Common::ReadStream &stream);
+ FontSJIS16x16() : _outlineEnabled(false) {}
void enableOutline(bool enable) { _outlineEnabled = enable; }
@@ -115,14 +131,51 @@ private:
template<typename Color>
void drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const;
+ bool _outlineEnabled;
+protected:
+
+ virtual const uint16 *getCharData(uint16 c) const = 0;
+};
+
+/**
+ * FM-TOWNS ROM based SJIS compatible font.
+ *
+ * This is used in KYRA and SCI.
+ */
+class FontTowns : public FontSJIS16x16 {
+public:
+ /**
+ * Loads the ROM data from "FMT_FNT.ROM".
+ */
+ bool loadData();
+
+private:
enum {
kFontRomSize = 262144
};
- bool _outlineEnabled;
uint16 _fontData[kFontRomSize / 2];
- static uint sjisToChunk(uint8 low, uint8 high);
+ const uint16 *getCharData(uint16 c) const;
+};
+
+/**
+ * Our custom SJIS FNT.
+ */
+class FontSjisSVM : public FontSJIS16x16 {
+public:
+ FontSjisSVM() : _fontData(0) {}
+ ~FontSjisSVM() { delete[] _fontData; }
+
+ /**
+ * Load the font data from "SJIS.FNT".
+ */
+ bool loadData();
+
+private:
+ uint16 *_fontData;
+
+ const uint16 *getCharData(uint16 c) const;
};
// TODO: Consider adding support for PC98 ROM
diff --git a/graphics/video/coktelvideo/coktelvideo.cpp b/graphics/video/coktelvideo/coktelvideo.cpp
index c88c5beee2..063ad190e6 100644
--- a/graphics/video/coktelvideo/coktelvideo.cpp
+++ b/graphics/video/coktelvideo/coktelvideo.cpp
@@ -41,52 +41,79 @@ Imd::~Imd() {
clear();
}
-bool Imd::load(Common::SeekableReadStream &stream) {
- unload();
+uint32 Imd::getFeatures() const {
+ return _features;
+}
- _stream = &stream;
+uint16 Imd::getFlags() const {
+ return _flags;
+}
- // Version
- uint16 handle = _stream->readUint16LE();
- _version = _stream->readByte();
+int16 Imd::getX() const {
+ return _x;
+}
- // Version checking
- if ((handle != 0) || (_version < 2)) {
- warning("IMD Version incorrect (%d,%X)", handle, _version);
- unload();
- return false;
- }
+int16 Imd::getY() const {
+ return _y;
+}
- // Rest header
- _features = _stream->readByte();
- _framesCount = _stream->readUint16LE();
- _x = _stream->readSint16LE();
- _y = _stream->readSint16LE();
- _width = _stream->readSint16LE();
- _height = _stream->readSint16LE();
- _flags = _stream->readUint16LE();
- _firstFramePos = _stream->readUint16LE();
+int16 Imd::getWidth() const {
+ return _width;
+}
- // IMDs always have video
- _features |= kFeaturesVideo;
- // IMDs always have palettes
- _features |= kFeaturesPalette;
+int16 Imd::getHeight() const {
+ return _height;
+}
- // Palette
- _stream->read((byte *) _palette, 768);
+uint16 Imd::getFramesCount() const {
+ return _framesCount;
+}
+
+uint16 Imd::getCurrentFrame() const {
+ return _curFrame;
+}
+
+int16 Imd::getFrameRate() const {
+ if (!_hasSound)
+ return _frameRate;
+ return 1000 / (_soundSliceLength >> 16);
+}
+
+uint32 Imd::getSyncLag() const {
+ return _skipFrames;
+}
+
+const byte *Imd::getPalette() const {
+ return _palette;
+}
+
+bool Imd::getFrameCoords(int16 frame,
+ int16 &x, int16 &y, int16 &width, int16 &height) {
+
+ return false;
+}
+
+bool Imd::hasExtraData(const char *fileName) const {
+ return false;
+}
+
+Common::MemoryReadStream *Imd::getExtraData(const char *fileName) {
+ return 0;
+}
+
+bool Imd::loadCoordinates() {
// Standard coordinates
if (_version >= 3) {
_stdX = _stream->readUint16LE();
if (_stdX > 1) {
warning("IMD: More than one standard coordinate quad found (%d)", _stdX);
- unload();
return false;
}
if (_stdX != 0) {
- _stdX = _stream->readSint16LE();
- _stdY = _stream->readSint16LE();
- _stdWidth = _stream->readSint16LE();
+ _stdX = _stream->readSint16LE();
+ _stdY = _stream->readSint16LE();
+ _stdWidth = _stream->readSint16LE();
_stdHeight = _stream->readSint16LE();
_features |= kFeaturesStdCoords;
} else
@@ -94,8 +121,14 @@ bool Imd::load(Common::SeekableReadStream &stream) {
} else
_stdX = -1;
- // Offset to frame positions table
- uint32 framesPosPos = 0;
+ return true;
+}
+
+bool Imd::loadFrameTableOffsets(uint32 &framesPosPos, uint32 &framesCoordsPos) {
+ framesPosPos = 0;
+ framesCoordsPos = 0;
+
+ // Frame positions
if (_version >= 4) {
framesPosPos = _stream->readUint32LE();
if (framesPosPos != 0) {
@@ -105,15 +138,43 @@ bool Imd::load(Common::SeekableReadStream &stream) {
}
}
- // Offset to frame coordinates
- uint32 framesCoordsPos = 0;
+ // Frame coordinates
if (_features & kFeaturesFrameCoords)
framesCoordsPos = _stream->readUint32LE();
- // Sound
+ return true;
+}
+
+bool Imd::assessVideoProperties() {
+ // Sizes of the frame data and extra video buffer
+ if (_features & kFeaturesDataSize) {
+ _frameDataSize = _stream->readUint16LE();
+ if (_frameDataSize == 0) {
+ _frameDataSize = _stream->readUint32LE();
+ _vidBufferSize = _stream->readUint32LE();
+ } else
+ _vidBufferSize = _stream->readUint16LE();
+ } else {
+ _frameDataSize = _width * _height + 500;
+ if (!(_flags & 0x100) || (_flags & 0x1000))
+ _vidBufferSize = _frameDataSize;
+ }
+
+ // Allocating working memory
+ _frameData = new byte[_frameDataSize + 500];
+ assert(_frameData);
+ memset(_frameData, 0, _frameDataSize + 500);
+ _vidBuffer = new byte[_vidBufferSize + 500];
+ assert(_vidBuffer);
+ memset(_vidBuffer, 0, _vidBufferSize + 500);
+
+ return true;
+}
+
+bool Imd::assessAudioProperties() {
if (_features & kFeaturesSound) {
- _soundFreq = _stream->readSint16LE();
- _soundSliceSize = _stream->readSint16LE();
+ _soundFreq = _stream->readSint16LE();
+ _soundSliceSize = _stream->readSint16LE();
_soundSlicesCount = _stream->readSint16LE();
if (_soundFreq < 0)
@@ -123,8 +184,7 @@ bool Imd::load(Common::SeekableReadStream &stream) {
_soundSlicesCount = -_soundSlicesCount - 1;
if (_soundSlicesCount > 40) {
- warning("IMD: More than 40 sound slices found (%d)", _soundSlicesCount);
- unload();
+ warning("Imd::load(): More than 40 sound slices found (%d)", _soundSlicesCount);
return false;
}
@@ -133,57 +193,103 @@ bool Imd::load(Common::SeekableReadStream &stream) {
_frameLength = _soundSliceLength >> 16;
_soundStage = 1;
- _hasSound = true;
+ _hasSound = true;
_audioStream = Audio::makeAppendableAudioStream(_soundFreq, 0);
} else
_frameLength = 1000 / _frameRate;
- // Sizes of the frame data and extra video buffer
- if (_features & kFeaturesDataSize) {
- _frameDataSize = _stream->readUint16LE();
- if (_frameDataSize == 0) {
- _frameDataSize = _stream->readUint32LE();
- _vidBufferSize = _stream->readUint32LE();
- } else
- _vidBufferSize = _stream->readUint16LE();
- } else {
- _frameDataSize = _width * _height + 500;
- if (!(_flags & 0x100) || (_flags & 0x1000))
- _vidBufferSize = _frameDataSize;
- }
+ return true;
+}
- // Frame positions table
+bool Imd::loadFrameTables(uint32 framesPosPos, uint32 framesCoordsPos) {
+ // Positions table
if (_framesPos) {
_stream->seek(framesPosPos, SEEK_SET);
for (int i = 0; i < _framesCount; i++)
_framesPos[i] = _stream->readUint32LE();
}
- // Frame coordinates table
+ // Coordinates table
if (_features & kFeaturesFrameCoords) {
_stream->seek(framesCoordsPos, SEEK_SET);
_frameCoords = new Coord[_framesCount];
assert(_frameCoords);
for (int i = 0; i < _framesCount; i++) {
- _frameCoords[i].left = _stream->readSint16LE();
- _frameCoords[i].top = _stream->readSint16LE();
- _frameCoords[i].right = _stream->readSint16LE();
+ _frameCoords[i].left = _stream->readSint16LE();
+ _frameCoords[i].top = _stream->readSint16LE();
+ _frameCoords[i].right = _stream->readSint16LE();
_frameCoords[i].bottom = _stream->readSint16LE();
}
}
+ return true;
+}
+
+bool Imd::load(Common::SeekableReadStream &stream) {
+ unload();
+
+ _stream = &stream;
+
+ uint16 handle;
+
+ handle = _stream->readUint16LE();
+ _version = _stream->readByte();
+
+ // Version checking
+ if ((handle != 0) || (_version < 2)) {
+ warning("Imd::load(): Version incorrect (%d,%X)", handle, _version);
+ unload();
+ return false;
+ }
+
+ // Rest header
+ _features = _stream->readByte();
+ _framesCount = _stream->readUint16LE();
+ _x = _stream->readSint16LE();
+ _y = _stream->readSint16LE();
+ _width = _stream->readSint16LE();
+ _height = _stream->readSint16LE();
+ _flags = _stream->readUint16LE();
+ _firstFramePos = _stream->readUint16LE();
+
+ // IMDs always have video
+ _features |= kFeaturesVideo;
+ // IMDs always have palettes
+ _features |= kFeaturesPalette;
+
+ // Palette
+ _stream->read((byte *) _palette, 768);
+
+ if (!loadCoordinates()) {
+ unload();
+ return false;
+ }
+
+ uint32 framesPosPos, frameCoordsPos;
+ if (!loadFrameTableOffsets(framesPosPos, frameCoordsPos)) {
+ unload();
+ return false;
+ }
+
+ if (!assessAudioProperties()) {
+ unload();
+ return false;
+ }
+
+ if (!assessVideoProperties()) {
+ unload();
+ return false;
+ }
+
+ if (!loadFrameTables(framesPosPos, frameCoordsPos)) {
+ unload();
+ return false;
+ }
+
// Seek to the first frame
_stream->seek(_firstFramePos, SEEK_SET);
- // Allocating working memory
- _frameData = new byte[_frameDataSize + 500];
- assert(_frameData);
- memset(_frameData, 0, _frameDataSize + 500);
- _vidBuffer = new byte[_vidBufferSize + 500];
- assert(_vidBuffer);
- memset(_vidBuffer, 0, _vidBufferSize + 500);
-
return true;
}
@@ -195,7 +301,7 @@ void Imd::setFrameRate(int16 frameRate) {
if (frameRate == 0)
frameRate = 1;
- _frameRate = frameRate;
+ _frameRate = frameRate;
_frameLength = 1000 / _frameRate;
}
@@ -213,11 +319,11 @@ void Imd::setXY(int16 x, int16 y) {
for (int i = 0; i < _framesCount; i++) {
if (_frameCoords[i].left != -1) {
if (x >= 0) {
- _frameCoords[i].left = _frameCoords[i].left - _x + x;
+ _frameCoords[i].left = _frameCoords[i].left - _x + x;
_frameCoords[i].right = _frameCoords[i].right - _x + x;
}
if (y >= 0) {
- _frameCoords[i].top = _frameCoords[i].top - _y + y;
+ _frameCoords[i].top = _frameCoords[i].top - _y + y;
_frameCoords[i].bottom = _frameCoords[i].bottom - _y + y;
}
}
@@ -234,8 +340,8 @@ void Imd::setVideoMemory(byte *vidMem, uint16 width, uint16 height) {
deleteVidMem();
_hasOwnVidMem = false;
- _vidMem = vidMem;
- _vidMemWidth = width;
+ _vidMem = vidMem;
+ _vidMemWidth = width;
_vidMemHeight = height;
}
@@ -245,12 +351,17 @@ void Imd::setVideoMemory() {
if ((_width > 0) && (_height > 0)) {
setXY(0, 0);
_hasOwnVidMem = true;
- _vidMem = new byte[_width * _height];
- _vidMemWidth = _width;
+ _vidMem = new byte[_width * _height];
+ _vidMemWidth = _width;
_vidMemHeight = _height;
+
+ memset(_vidMem, 0, _width * _height);
}
}
+void Imd::setDoubleMode(bool doubleMode) {
+}
+
void Imd::enableSound(Audio::Mixer &mixer) {
// Only possible on the first frame
if (_curFrame > 0)
@@ -270,7 +381,7 @@ void Imd::disableSound() {
delete _audioStream;
_audioStream = 0;
- _soundStage = 0;
+ _soundStage = 0;
}
_soundEnabled = false;
_mixer = 0;
@@ -313,8 +424,9 @@ void Imd::seekFrame(int32 frame, int16 whence, bool restart) {
} else if (restart && (_soundStage == 0)) {
for (int i = ((frame > _curFrame) ? _curFrame : 0); i <= frame; i++)
processFrame(i);
+ return;
} else
- error("Frame %d is not directly accessible", frame);
+ error("Imd::seekFrame(): Frame %d is not directly accessible", frame);
// Seek
_stream->seek(framePos);
@@ -326,7 +438,7 @@ CoktelVideo::State Imd::nextFrame() {
}
void Imd::waitEndFrame() {
- if (_soundEnabled && _hasSound) {
+ if (_soundEnabled && _hasSound) {;
if (_soundStage != 2)
return;
@@ -404,8 +516,9 @@ void Imd::deleteVidMem(bool del) {
}
_hasOwnVidMem = false;
- _vidMem = 0;
- _vidMemWidth = _vidMemHeight = 0;
+ _vidMem = 0;
+ _vidMemWidth = 0;
+ _vidMemHeight = 0;
}
void Imd::clear(bool del) {
@@ -420,42 +533,126 @@ void Imd::clear(bool del) {
_stream = 0;
- _version = 0;
+ _version = 0;
_features = 0;
- _flags = 0;
- _x = _y = _width = _height = 0;
+ _flags = 0;
+
+ _x = _y = _width = _height = 0;
_stdX = _stdY = _stdWidth = _stdHeight = 0;
+
_framesCount = _curFrame = 0;
- _framesPos = 0;
+
+ _framesPos = 0;
_firstFramePos = 0;
- _frameCoords = 0;
+ _frameCoords = 0;
_frameDataSize = _vidBufferSize = 0;
- _frameData = _vidBuffer = 0;
- _frameDataLen = 0;
+ _frameData = _vidBuffer = 0;
+ _frameDataLen = 0;
memset(_palette, 0, 768);
deleteVidMem(del);
- _hasSound = false;
+ _hasSound = false;
_soundEnabled = false;
- _soundStage = 0;
- _skipFrames = 0;
+ _soundStage = 0;
+ _skipFrames = 0;
- _soundFlags = 0;
- _soundFreq = 0;
- _soundSliceSize = 0;
+ _soundFlags = 0;
+ _soundFreq = 0;
+ _soundSliceSize = 0;
_soundSlicesCount = 0;
_soundSliceLength = 0;
+ _audioStream = 0;
- _audioStream = 0;
-
- _frameRate = 12;
- _frameLength = 0;
+ _frameRate = 12;
+ _frameLength = 0;
_lastFrameTime = 0;
}
+void Imd::nextSoundSlice(bool hasNextCmd) {
+ if (hasNextCmd || !_soundEnabled) {
+ _stream->seek(_soundSliceSize, SEEK_CUR);
+ return;
+ }
+
+ byte *soundBuf = new byte[_soundSliceSize];
+
+ _stream->read(soundBuf, _soundSliceSize);
+ unsignedToSigned(soundBuf, _soundSliceSize);
+
+ _audioStream->queueBuffer(soundBuf, _soundSliceSize);
+}
+
+bool Imd::initialSoundSlice(bool hasNextCmd) {
+ int dataLength = _soundSliceSize * _soundSlicesCount;
+
+ if (hasNextCmd || !_soundEnabled) {
+ _stream->seek(dataLength, SEEK_CUR);
+ return false;
+ }
+
+ byte *soundBuf = new byte[dataLength];
+
+ _stream->read(soundBuf, dataLength);
+ unsignedToSigned(soundBuf, dataLength);
+
+ _audioStream->queueBuffer(soundBuf, dataLength);
+
+ return _soundStage == 1;
+}
+
+void Imd::emptySoundSlice(bool hasNextCmd) {
+ if (hasNextCmd || !_soundEnabled)
+ return;
+
+ byte *soundBuf = new byte[_soundSliceSize];
+
+ memset(soundBuf, 0, _soundSliceSize);
+
+ _audioStream->queueBuffer(soundBuf, _soundSliceSize);
+}
+
+void Imd::videoData(uint32 size, State &state) {
+ _stream->read(_frameData, size);
+ _frameDataLen = size;
+
+ if (_vidMemWidth <= state.right) {
+ state.left = 0;
+ state.right -= state.left;
+ }
+ if (_vidMemWidth <= state.right)
+ state.right = _vidMemWidth - 1;
+ if (_vidMemHeight <= state.bottom) {
+ state.top = 0;
+ state.bottom -= state.top;
+ }
+ if (_vidMemHeight <= state.bottom)
+ state.bottom = _vidMemHeight -1;
+
+ state.flags |= renderFrame(state.left, state.top, state.right, state.bottom);
+ state.flags |= _frameData[0];
+}
+
+void Imd::calcFrameCoords(uint16 frame, State &state) {
+ if (_stdX != -1) {
+ state.left = _stdX;
+ state.top = _stdY;
+ state.right = _stdWidth + state.left - 1;
+ state.bottom = _stdHeight + state.top - 1;
+ state.flags |= kStateStdCoords;
+ }
+ if (_frameCoords &&
+ (_frameCoords[frame].left != -1)) {
+ state.left = _frameCoords[frame].left;
+ state.top = _frameCoords[frame].top;
+ state.right = _frameCoords[frame].right;
+ state.bottom = _frameCoords[frame].bottom;
+ state.flags |= kStateFrameCoords;
+ }
+}
+
CoktelVideo::State Imd::processFrame(uint16 frame) {
State state;
uint32 cmd = 0;
@@ -475,47 +672,35 @@ CoktelVideo::State Imd::processFrame(uint16 frame) {
if (!_vidMem)
setVideoMemory();
- state.left = _x;
- state.top = _y;
- state.right = _width + state.left - 1;
- state.bottom = _height + state.top - 1;
+ state.left = _x;
+ state.top = _y;
+ state.right = _width + state.left - 1;
+ state.bottom = _height + state.top - 1;
do {
- if (frame != 0) {
- if (_stdX != -1) {
- state.left = _stdX;
- state.top = _stdY;
- state.right = _stdWidth + state.left - 1;
- state.bottom = _stdHeight + state.top - 1;
- state.flags |= kStateStdCoords;
- }
- if (_frameCoords &&
- (_frameCoords[frame].left != -1)) {
- state.left = _frameCoords[frame].left;
- state.top = _frameCoords[frame].top;
- state.right = _frameCoords[frame].right;
- state.bottom = _frameCoords[frame].bottom;
- state.flags |= kStateFrameCoords;
- }
- }
+ if (frame != 0)
+ calcFrameCoords(frame, state);
cmd = _stream->readUint16LE();
- if ((cmd & 0xFFF8) == 0xFFF0) {
- if (cmd == 0xFFF0) {
+ if ((cmd & kCommandBreakMask) == kCommandBreak) {
+ // Flow control
+
+ if (cmd == kCommandBreak) {
_stream->seek(2, SEEK_CUR);
cmd = _stream->readUint16LE();
}
- if (cmd == 0xFFF1) {
+ // Break
+ if (cmd == kCommandBreakSkip0) {
state.flags = kStateBreak;
continue;
- } else if (cmd == 0xFFF2) { // Skip (16 bit)
+ } else if (cmd == kCommandBreakSkip16) {
cmd = _stream->readUint16LE();
_stream->seek(cmd, SEEK_CUR);
state.flags = kStateBreak;
continue;
- } else if (cmd == 0xFFF3) { // Skip (32 bit)
+ } else if (cmd == kCommandBreakSkip32) {
cmd = _stream->readUint32LE();
_stream->seek(cmd, SEEK_CUR);
state.flags = kStateBreak;
@@ -523,57 +708,24 @@ CoktelVideo::State Imd::processFrame(uint16 frame) {
}
}
+ // Audio
if (_soundStage != 0) {
- byte *soundBuf;
-
- // Next sound slice data
- if (cmd == 0xFF00) {
-
- if (!hasNextCmd && _soundEnabled) {
- soundBuf = new byte[_soundSliceSize];
- assert(soundBuf);
-
- _stream->read(soundBuf, _soundSliceSize);
- unsignedToSigned(soundBuf, _soundSliceSize);
- _audioStream->queueBuffer(soundBuf, _soundSliceSize);
- } else
- _stream->seek(_soundSliceSize, SEEK_CUR);
+ if (cmd == kCommandNextSound) {
+ nextSoundSlice(hasNextCmd);
cmd = _stream->readUint16LE();
- // Initial sound data (all slices)
- } else if (cmd == 0xFF01) {
- int dataLength = _soundSliceSize * _soundSlicesCount;
-
- if (!hasNextCmd && _soundEnabled) {
- soundBuf = new byte[dataLength];
- assert(soundBuf);
-
- _stream->read(soundBuf, dataLength);
- unsignedToSigned(soundBuf, dataLength);
-
- if (_soundStage == 1)
- startSound = true;
-
- _audioStream->queueBuffer(soundBuf, dataLength);
- } else
- _stream->seek(dataLength, SEEK_CUR);
+ } else if (cmd == kCommandStartSound) {
+ startSound = initialSoundSlice(hasNextCmd);
cmd = _stream->readUint16LE();
- // Empty sound slice
- } else if (!hasNextCmd && (_soundEnabled)) {
- soundBuf = new byte[_soundSliceSize];
- assert(soundBuf);
-
- memset(soundBuf, 0, _soundSliceSize);
-
- _audioStream->queueBuffer(soundBuf, _soundSliceSize);
- }
+ } else
+ emptySoundSlice(hasNextCmd);
}
// Set palette
- if (cmd == 0xFFF4) {
+ if (cmd == kCommandPalette) {
_stream->seek(2, SEEK_CUR);
state.flags |= kStatePalette;
@@ -583,8 +735,8 @@ CoktelVideo::State Imd::processFrame(uint16 frame) {
hasNextCmd = false;
- // Jump to frame
- if (cmd == 0xFFFD) {
+ if (cmd == kCommandJump) {
+ // Jump to frame
frame = _stream->readSint16LE();
if (_framesPos) {
@@ -595,37 +747,17 @@ CoktelVideo::State Imd::processFrame(uint16 frame) {
state.flags |= kStateJump;
}
- } else if (cmd == 0xFFFC) {
+ } else if (cmd == kCommandVideoData) {
+ uint32 size = _stream->readUint32LE() + 2;
- state.flags |= 1;
- cmd = _stream->readUint32LE();
- _stream->read(_frameData, cmd + 2);
- _frameDataLen = cmd + 2;
+ videoData(size, state);
- if (_vidMemWidth <= state.right) {
- state.left = 0;
- state.right -= state.left;
- }
- if (_vidMemWidth <= state.right)
- state.right = _vidMemWidth - 1;
- if (_vidMemHeight <= state.bottom) {
- state.top = 0;
- state.bottom -= state.top;
- }
- if (_vidMemHeight <= state.bottom)
- state.bottom = _vidMemHeight -1;
-
- state.flags |= renderFrame(state.left, state.top, state.right, state.bottom);
- state.flags |= _frameData[0];
+ state.flags |= 1;
- // Frame video data
} else if (cmd != 0) {
+ uint32 size = cmd + 2;
- _stream->read(_frameData, cmd + 2);
- _frameDataLen = cmd + 2;
-
- state.flags |= renderFrame(state.left, state.top, state.right, state.bottom);
- state.flags |= _frameData[0];
+ videoData(size, state);
} else
state.flags |= kStateNoVideoData;
@@ -643,24 +775,133 @@ CoktelVideo::State Imd::processFrame(uint16 frame) {
_audioStream->finish();
_mixer->stopHandle(_audioHandle);
_audioStream = 0;
- _soundStage = 0;
+ _soundStage = 0;
}
_lastFrameTime = g_system->getMillis();
return state;
}
+// A whole, completely filled block
+void Imd::renderBlockWhole(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight) {
+
+ int16 w = MIN(width, destWidth);
+ int16 h = MIN(height, destHeight);
+
+ for (int i = 0; i < h; i++) {
+ memcpy(dest, src, w);
+
+ src += width;
+ dest += destWidth;
+ }
+}
+
+// A quarter-wide whole, completely filled block
+void Imd::renderBlockWhole4X(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight) {
+
+ for (int i = 0; i < height; i++) {
+ byte *destBak = dest;
+
+ for (int j = 0; j < width; j += 4, dest += 4, src++)
+ memset(dest, *src, 4);
+
+ dest = destBak + destWidth;
+ }
+}
+
+// A half-high whole, completely filled block
+void Imd::renderBlockWhole2Y(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight) {
+
+ while (height > 1) {
+ memcpy(dest , src, width);
+ memcpy(dest + destWidth, src, width);
+
+ height -= 2;
+ dest += 2 * destWidth;
+ src += width;
+ }
+
+ if (height == 1)
+ memcpy(dest, src, width);
+}
+
+// A sparse block
+void Imd::renderBlockSparse(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight) {
+
+ for (int i = 0; i < height; i++) {
+ byte *destBak = dest;
+ uint16 pixWritten = 0;
+
+ while (pixWritten < width) {
+ uint16 pixCount = *src++;
+
+ if (pixCount & 0x80) { // Data
+ pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
+ memcpy(dest, src, pixCount);
+
+ pixWritten += pixCount;
+ dest += pixCount;
+ src += pixCount;
+ } else { // "Hole"
+ pixWritten += pixCount + 1;
+ dest += pixCount + 1;
+ }
+
+ }
+
+ dest = destBak + destWidth;
+ }
+}
+
+// A half-high sparse block
+void Imd::renderBlockSparse2Y(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight) {
+
+ for (int i = 0; i < height; i += 2) {
+ byte *destBak = dest;
+ uint16 pixWritten = 0;
+
+ while (pixWritten < width) {
+ uint16 pixCount = *src++;
+
+ if (pixCount & 0x80) { // Data
+ pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
+ memcpy(dest , src, pixCount);
+ memcpy(dest + destWidth, src, pixCount);
+
+ pixWritten += pixCount;
+ dest += pixCount;
+ src += pixCount;
+ } else { // "Hole"
+ pixWritten += pixCount + 1;
+ dest += pixCount + 1;
+ }
+
+ }
+
+ dest = destBak + destWidth;
+ }
+}
+
uint32 Imd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
if (!_frameData || !_vidMem || (_width <= 0) || (_height <= 0))
return 0;
uint32 retVal = 0;
- int16 width = right - left + 1;
- int16 height = bottom - top + 1;
- int16 sW = _vidMemWidth;
- byte *dataPtr = _frameData;
+
+ int16 width = right - left + 1;
+ int16 height = bottom - top + 1;
+ int16 sW = _vidMemWidth;
+ int16 sH = _vidMemHeight;
+
+ byte *dataPtr = _frameData;
byte *imdVidMem = _vidMem + sW * top + left;
byte *srcPtr;
+
uint8 type = *dataPtr++;
if (type & 0x10) { // Palette data
@@ -676,88 +917,30 @@ uint32 Imd::renderFrame(int16 left, int16 top, int16 right, int16 bottom) {
srcPtr = dataPtr;
- if (type & 0x80) { // Frame data is compressed
+ if (type & 0x80) {
+ // Frame data is compressed
+
srcPtr = _vidBuffer;
type &= 0x7F;
if ((type == 2) && (width == sW)) {
+ // Directly uncompress onto the video surface
deLZ77(imdVidMem, dataPtr);
return retVal;
} else
deLZ77(srcPtr, dataPtr);
}
- uint16 pixCount, pixWritten;
- byte *imdVidMemBak;
-
- if (type == 2) { // Whole block
- for (int i = 0; i < height; i++) {
- memcpy(imdVidMem, srcPtr, width);
- srcPtr += width;
- imdVidMem += sW;
- }
- } else if (type == 1) { // Sparse block
- imdVidMemBak = imdVidMem;
- for (int i = 0; i < height; i++) {
- pixWritten = 0;
- while (pixWritten < width) {
- pixCount = *srcPtr++;
- if (pixCount & 0x80) { // Data
- pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
- memcpy(imdVidMem, srcPtr, pixCount);
-
- pixWritten += pixCount;
- imdVidMem += pixCount;
- srcPtr += pixCount;
- } else { // "Hole"
- pixCount = (pixCount + 1) % 256;
- pixWritten += pixCount;
- imdVidMem += pixCount;
- }
- }
- imdVidMemBak += sW;
- imdVidMem = imdVidMemBak;
- }
- } else if (type == 0x42) { // Whole quarter-wide block
- for (int i = 0; i < height; i++) {
- imdVidMemBak = imdVidMem;
-
- for (int j = 0; j < width; j += 4, imdVidMem += 4, srcPtr++)
- memset(imdVidMem, *srcPtr, 4);
-
- imdVidMemBak += sW;
- imdVidMem = imdVidMemBak;
- }
- } else if ((type & 0xF) == 2) { // Whole half-high block
- for (; height > 1; height -= 2, imdVidMem += sW + sW, srcPtr += width) {
- memcpy(imdVidMem, srcPtr, width);
- memcpy(imdVidMem + sW, srcPtr, width);
- }
- if (height == -1)
- memcpy(imdVidMem, srcPtr, width);
- } else { // Sparse half-high block
- imdVidMemBak = imdVidMem;
- for (int i = 0; i < height; i += 2) {
- pixWritten = 0;
- while (pixWritten < width) {
- pixCount = *srcPtr++;
- if (pixCount & 0x80) { // Data
- pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
- memcpy(imdVidMem, srcPtr, pixCount);
- memcpy(imdVidMem + sW, srcPtr, pixCount);
-
- pixWritten += pixCount;
- imdVidMem += pixCount;
- srcPtr += pixCount;
- } else { // "Hole"
- pixCount = (pixCount + 1) % 256;
- pixWritten += pixCount;
- imdVidMem += pixCount;
- }
- }
- imdVidMemBak += sW + sW;
- imdVidMem = imdVidMemBak;
- }
- }
+ // Evaluate the block type
+ if (type == 0x01)
+ renderBlockSparse (imdVidMem, srcPtr, width, height, sW, sH);
+ else if (type == 0x02)
+ renderBlockWhole (imdVidMem, srcPtr, width, height, sW, sH);
+ else if (type == 0x42)
+ renderBlockWhole4X (imdVidMem, srcPtr, width, height, sW, sH);
+ else if ((type & 0x0F) == 0x02)
+ renderBlockWhole2Y (imdVidMem, srcPtr, width, height, sW, sH);
+ else
+ renderBlockSparse2Y(imdVidMem, srcPtr, width, height, sW, sH);
return retVal;
}
@@ -849,7 +1032,45 @@ void Imd::deLZ77(byte *dest, byte *src) {
}
}
-const uint16 Vmd::_tableADPCM[128] = {
+inline void Imd::unsignedToSigned(byte *buffer, int length) {
+ while (length-- > 0) *buffer++ ^= 0x80;
+}
+
+
+Vmd::ExtraData::ExtraData() {
+ memset(name, 0, 16);
+
+ offset = 0;
+ size = 0;
+ realSize = 0;
+}
+
+
+Vmd::Part::Part() {
+ type = kPartTypeSeparator;
+ field_1 = 0;
+ field_E = 0;
+ size = 0;
+ left = 0;
+ top = 0;
+ right = 0;
+ bottom = 0;
+ id = 0;
+ flags = 0;
+}
+
+
+Vmd::Frame::Frame() {
+ parts = 0;
+ offset = 0;
+}
+
+Vmd::Frame::~Frame() {
+ delete[] parts;
+}
+
+
+const uint16 Vmd::_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,
@@ -865,6 +1086,26 @@ const uint16 Vmd::_tableADPCM[128] = {
0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
};
+const int32 Vmd::_tableADPCM[] = {
+ 7, 8, 9, 10, 11, 12, 13, 14,
+ 16, 17, 19, 21, 23, 25, 28, 31,
+ 34, 37, 41, 45, 50, 55, 60, 66,
+ 73, 80, 88, 97, 107, 118, 130, 143,
+ 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658,
+ 724, 796, 876, 963, 1060, 1166, 1282, 1411,
+ 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
+ 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
+ 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
+ 32767, 0
+};
+
+const int32 Vmd::_tableADPCMStep[] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+};
+
Vmd::Vmd(Graphics::PaletteLUT *palLUT) : _palLUT(palLUT) {
clear(false);
}
@@ -873,84 +1114,11 @@ Vmd::~Vmd() {
clear();
}
-bool Vmd::load(Common::SeekableReadStream &stream) {
- unload();
-
- _stream = &stream;
-
- uint16 headerLength = _stream->readUint16LE();
- uint16 handle = _stream->readUint16LE();
- _version = _stream->readUint16LE();
-
- if (!(_version & 2))
- _features |= kFeaturesPalette;
- else
- _features |= kFeaturesFullColor;
-
- // 0x4 (4)
-
- // Version checking
- if (headerLength != 814) {
- warning("VMD Version incorrect (%d, %d, %d)", headerLength, handle, _version);
- unload();
- return false;
- }
-
- _framesCount = _stream->readUint16LE();
-
- // 0x6 (6)
-
- _x = _stream->readSint16LE();
- _y = _stream->readSint16LE();
- _width = _stream->readSint16LE();
- _height = _stream->readSint16LE();
-
- // 0xE (14)
-
- if ((_width != 0) && (_height != 0)) {
- _hasVideo = true;
- _features |= kFeaturesVideo;
- if (_features & kFeaturesFullColor)
- _codecIndeo3 = new Indeo3(_width, _height, _palLUT);
- } else
- _hasVideo = false;
-
- if (_width > 320) {
- if (!(_version & 4)) {
- _version |= 4;
- handle = 0;
- }
- }
-
- if (handle > 2) {
- warning("VMD Version incorrect (%d, %d, %d)", headerLength, handle, _version);
- unload();
- return false;
- }
-
- _bytesPerPixel = handle + 1;
-
- if (_bytesPerPixel > 1) {
+bool Vmd::assessVideoProperties() {
+ if (_bytesPerPixel > 1)
_features |= kFeaturesFullColor;
- _features &= ~kFeaturesPalette;
- }
-
- _flags = _stream->readUint16LE();
-
- _partsPerFrame = _stream->readUint16LE();
- _firstFramePos = _stream->readUint32LE();
- _stream->skip(4); // Unknown
-
- // 0x1A (26)
-
- _stream->read((byte *) _palette, 768);
-
- // 0x31A (794)
-
- _frameDataSize = _stream->readUint32LE();
- _vidBufferSize = _stream->readUint32LE();
-
- _doubleMode = false;
+ else
+ _features |= kFeaturesPalette;
if ((_version & 2) && !(_version & 8)) {
_externalCodec = true;
@@ -958,7 +1126,21 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
} else
_externalCodec = false;
- _preScaleX = 1;
+ if (_externalCodec) {
+ if (_videoCodec == MKID_BE('iv32')) {
+ _features &= ~kFeaturesPalette;
+ _features |= kFeaturesFullColor;
+ _codecIndeo3 = new Indeo3(_width, _height, _palLUT);
+ } else {
+ char *fourcc = (char *) &_videoCodec;
+
+ warning("Vmd::assessVideoProperties(): Unknow video codec FourCC \'%c%c%c%c\'",
+ fourcc[3], fourcc[2], fourcc[1], fourcc[0]);
+ return false;
+ }
+ }
+
+ _preScaleX = 1;
_postScaleX = 1;
if (_externalCodec)
@@ -971,10 +1153,10 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
_blitMode = n - 1;
if (_bytesPerPixel == 2) {
- _preScaleX = n;
+ _preScaleX = n;
_postScaleX = 1;
} else if (_bytesPerPixel == 3) {
- _preScaleX = 1;
+ _preScaleX = 1;
_postScaleX = n;
}
@@ -985,8 +1167,6 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
if (!_externalCodec && !(_flags & 0x1000))
_scaleExternalX = _bytesPerPixel;
- // 0x322 (802)
-
if (_hasVideo) {
if ((_frameDataSize == 0) || (_frameDataSize > 1048576))
_frameDataSize = _width * _height + 1000;
@@ -1010,42 +1190,75 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
if (_externalCodec && _codecIndeo3)
_features |= kFeaturesSupportsDouble;
- _soundFreq = _stream->readSint16LE();
- _soundSliceSize = _stream->readSint16LE();
- _soundSlicesCount = _stream->readSint16LE();
- _soundFlags = _stream->readUint16LE();
- _hasSound = (_soundFreq != 0);
+ return true;
+}
- // 0x32A (810)
+bool Vmd::assessAudioProperties() {
+ bool supportedFormat = true;
- if (_hasSound) {
- _features |= kFeaturesSound;
+ _features |= kFeaturesSound;
- _soundStereo = (_soundFlags & 0x8000) ? 1 : ((_soundFlags & 0x200) ? 2 : 0);
- if (_soundStereo > 0) {
- warning("TODO: VMD stereo");
- unload();
- return false;
- }
+ _soundStereo = (_soundFlags & 0x8000) ? 1 : ((_soundFlags & 0x200) ? 2 : 0);
+
+ if (_soundSliceSize < 0) {
+ _soundBytesPerSample = 2;
+ _soundSliceSize = -_soundSliceSize;
+
+ if (_soundFlags & 0x10) {
+ _audioFormat = kAudioFormat16bitADPCM;
+ _soundHeaderSize = 3;
+ _soundDataSize = _soundSliceSize >> 1;
+
+ if (_soundStereo > 0)
+ supportedFormat = false;
+
+ } else {
+ _audioFormat = kAudioFormat16bitDPCM;
+ _soundHeaderSize = 1;
+ _soundDataSize = _soundSliceSize;
+
+ if (_soundStereo == 1) {
+ supportedFormat = false;
+ } else if (_soundStereo == 2) {
+ _soundDataSize = 2 * _soundDataSize + 2;
+ _soundHeaderSize = 4;
+ }
- if (_soundSliceSize < 0) {
- _soundBytesPerSample = 2;
- _soundSliceSize = -_soundSliceSize;
}
+ } else {
+ _soundBytesPerSample = 1;
+ _audioFormat = kAudioFormat8bitDirect;
+ _soundHeaderSize = 0;
+ _soundDataSize = _soundSliceSize;
- _soundSliceLength = (uint32) (((double) (1000 << 16)) /
- ((double) _soundFreq / (double) _soundSliceSize));
- _frameLength = _soundSliceLength >> 16;
+ if (_soundStereo > 0)
+ supportedFormat = false;
+ }
- _soundStage = 1;
- _audioStream = Audio::makeAppendableAudioStream(_soundFreq,
- (_soundBytesPerSample == 2) ? Audio::Mixer::FLAG_16BITS : 0);
- } else
- _frameLength = 1000 / _frameRate;
+ if (!supportedFormat) {
+ warning("Vmd::assessAudioProperties(): Unsupported audio format: %d bits, encoding %d, stereo %d",
+ _soundBytesPerSample * 8, _audioFormat, _soundStereo);
+ return false;
+ }
- _frameInfoOffset = _stream->readUint32LE();
+ _soundSliceLength = (uint32) (((double) (1000 << 16)) /
+ ((double) _soundFreq / (double) _soundSliceSize));
+ _frameLength = _soundSliceLength >> 16;
+
+ _soundStage = 1;
+
+ uint32 flags = 0;
+
+ flags |= (_soundBytesPerSample == 2) ? Audio::Mixer::FLAG_16BITS : 0;
+ flags |= (_soundStereo > 0) ? Audio::Mixer::FLAG_STEREO : 0;
+
+ _audioStream = Audio::makeAppendableAudioStream(_soundFreq, flags);
- int numExtraData = 0;
+ return true;
+}
+
+void Vmd::readFrameTable(int &numExtraData) {
+ numExtraData = 0;
_stream->seek(_frameInfoOffset);
_frames = new Frame[_framesCount];
@@ -1054,14 +1267,15 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
_stream->skip(2); // Unknown
_frames[i].offset = _stream->readUint32LE();
}
+
for (uint16 i = 0; i < _framesCount; i++) {
bool separator = false;
for (uint16 j = 0; j < _partsPerFrame; j++) {
- _frames[i].parts[j].type = (PartType) _stream->readByte();
+ _frames[i].parts[j].type = (PartType) _stream->readByte();
_frames[i].parts[j].field_1 = _stream->readByte();
- _frames[i].parts[j].size = _stream->readUint32LE();
+ _frames[i].parts[j].size = _stream->readUint32LE();
if (_frames[i].parts[j].type == kPartTypeAudio) {
@@ -1070,13 +1284,17 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
} else if (_frames[i].parts[j].type == kPartTypeVideo) {
- _frames[i].parts[j].left = _stream->readUint16LE();
- _frames[i].parts[j].top = _stream->readUint16LE();
- _frames[i].parts[j].right = _stream->readUint16LE();
- _frames[i].parts[j].bottom = _stream->readUint16LE();
+ _frames[i].parts[j].left = _stream->readUint16LE();
+ _frames[i].parts[j].top = _stream->readUint16LE();
+ _frames[i].parts[j].right = _stream->readUint16LE();
+ _frames[i].parts[j].bottom = _stream->readUint16LE();
_frames[i].parts[j].field_E = _stream->readByte();
- _frames[i].parts[j].flags = _stream->readByte();
+ _frames[i].parts[j].flags = _stream->readByte();
+ } else if (_frames[i].parts[j].type == kPartTypeSpeech) {
+ _frames[i].parts[j].id = _stream->readUint16LE();
+ // Speech text file name
+ _stream->skip(8);
} else if (_frames[i].parts[j].type == kPartTypeExtraData) {
if (!separator)
numExtraData++;
@@ -1091,16 +1309,9 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
}
}
+}
- _stream->seek(_firstFramePos);
-
- if (numExtraData == 0)
- return true;
-
- _extraData.reserve(numExtraData);
-
- numExtraData = 0;
-
+void Vmd::readExtraData() {
uint32 ssize = _stream->size();
for (uint16 i = 0; i < _framesCount; i++) {
_stream->seek(_frames[i].offset);
@@ -1112,9 +1323,10 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
if (_frames[i].parts[j].type == kPartTypeExtraData) {
ExtraData data;
- data.offset = _stream->pos() + 20;
- data.size = _frames[i].parts[j].size;
+ data.offset = _stream->pos() + 20;
+ data.size = _frames[i].parts[j].size;
data.realSize = _stream->readUint32LE();
+
_stream->read(data.name, 16);
data.name[15] = '\0';
@@ -1129,6 +1341,110 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
_stream->skip(_frames[i].parts[j].size);
}
}
+}
+
+bool Vmd::load(Common::SeekableReadStream &stream) {
+ unload();
+
+ _stream = &stream;
+
+ uint16 headerLength;
+ uint16 handle;
+
+ headerLength = _stream->readUint16LE();
+ handle = _stream->readUint16LE();
+ _version = _stream->readUint16LE();
+
+ bool readPalette;
+
+ // Version checking
+ if (headerLength == 50) {
+ // Newer version, used in Addy 5 upwards
+ warning("Vmd::load(): TODO: Addy 5 videos");
+ readPalette = false;
+ } else if (headerLength == 814) {
+ // Old version
+ readPalette = true;
+ } else {
+ warning("Vmd::load(): Version incorrect (%d, %d, %d)", headerLength, handle, _version);
+ unload();
+ return false;
+ }
+
+ _framesCount = _stream->readUint16LE();
+
+ _x = _stream->readSint16LE();
+ _y = _stream->readSint16LE();
+ _width = _stream->readSint16LE();
+ _height = _stream->readSint16LE();
+
+ if ((_width != 0) && (_height != 0)) {
+
+ _hasVideo = true;
+ _features |= kFeaturesVideo;
+
+ } else
+ _hasVideo = false;
+
+ _bytesPerPixel = 1;
+ if (_version & 4)
+ _bytesPerPixel = handle + 1;
+
+ if (_bytesPerPixel > 3) {
+ warning("Vmd::load(): Requested %d bytes per pixel (%d, %d, %d)", _bytesPerPixel, headerLength, handle, _version);
+ unload();
+ return false;
+ }
+
+ _flags = _stream->readUint16LE();
+
+ _partsPerFrame = _stream->readUint16LE();
+ _firstFramePos = _stream->readUint32LE();
+
+ _videoCodec = _stream->readUint32BE();
+
+ if (readPalette)
+ _stream->read((byte *) _palette, 768);
+
+ _frameDataSize = _stream->readUint32LE();
+ _vidBufferSize = _stream->readUint32LE();
+
+ _doubleMode = false;
+
+ if (_hasVideo) {
+ if (!assessVideoProperties()) {
+ unload();
+ return false;
+ }
+ }
+
+ _soundFreq = _stream->readSint16LE();
+ _soundSliceSize = _stream->readSint16LE();
+ _soundSlicesCount = _stream->readSint16LE();
+ _soundFlags = _stream->readUint16LE();
+
+ _hasSound = (_soundFreq != 0);
+
+ if (_hasSound) {
+ if (!assessAudioProperties()) {
+ unload();
+ return false;
+ }
+ } else
+ _frameLength = 1000 / _frameRate;
+
+ _frameInfoOffset = _stream->readUint32LE();
+
+ int numExtraData;
+ readFrameTable(numExtraData);
+
+ _stream->seek(_firstFramePos);
+
+ if (numExtraData == 0)
+ return true;
+
+ _extraData.reserve(numExtraData);
+ readExtraData();
_stream->seek(_firstFramePos);
return true;
@@ -1151,11 +1467,11 @@ void Vmd::setXY(int16 x, int16 y) {
if (_frames[i].parts[j].type == kPartTypeVideo) {
if (x >= 0) {
- _frames[i].parts[j].left = _frames[i].parts[j].left - _x + x;
+ _frames[i].parts[j].left = _frames[i].parts[j].left - _x + x;
_frames[i].parts[j].right = _frames[i].parts[j].right - _x + x;
}
if (y >= 0) {
- _frames[i].parts[j].top = _frames[i].parts[j].top - _y + y;
+ _frames[i].parts[j].top = _frames[i].parts[j].top - _y + y;
_frames[i].parts[j].bottom = _frames[i].parts[j].bottom - _y + y;
}
}
@@ -1243,7 +1559,8 @@ void Vmd::clear(bool del) {
delete[] _vidMemBuffer;
}
- _hasVideo = true;
+ _hasVideo = true;
+ _videoCodec = 0;
_codecIndeo3 = 0;
@@ -1253,16 +1570,19 @@ void Vmd::clear(bool del) {
_extraData.clear();
_soundBytesPerSample = 1;
- _soundStereo = 0;
-
- _externalCodec = false;
- _doubleMode = false;
- _blitMode = 0;
- _bytesPerPixel = 1;
- _preScaleX = 1;
- _postScaleX = 1;
+ _soundStereo = 0;
+ _soundHeaderSize = 0;
+ _soundDataSize = 0;
+ _audioFormat = kAudioFormat8bitDirect;
+
+ _externalCodec = false;
+ _doubleMode = false;
+ _blitMode = 0;
+ _bytesPerPixel = 1;
+ _preScaleX = 1;
+ _postScaleX = 1;
_scaleExternalX = 1;
- _vidMemBuffer = 0;
+ _vidMemBuffer = 0;
}
CoktelVideo::State Vmd::processFrame(uint16 frame) {
@@ -1272,15 +1592,17 @@ CoktelVideo::State Vmd::processFrame(uint16 frame) {
seekFrame(frame);
state.flags |= kStateNoVideoData;
- state.left = 0x7FFF;
- state.top = 0x7FFF;
- state.right = 0;
+ state.left = 0x7FFF;
+ state.top = 0x7FFF;
+ state.right = 0;
state.bottom = 0;
if (!_vidMem)
setVideoMemory();
for (uint16 i = 0; (i < _partsPerFrame) && (frame < _framesCount); i++) {
+ uint32 pos = _stream->pos();
+
Part &part = _frames[frame].parts[i];
if (part.type == kPartTypeAudio) {
@@ -1313,20 +1635,27 @@ CoktelVideo::State Vmd::processFrame(uint16 frame) {
} else if (part.flags == 3) {
if (_soundEnabled) {
- emptySoundSlice(_soundSliceSize * _soundBytesPerSample);
+ emptySoundSlice(_soundDataSize * _soundBytesPerSample);
if (_soundStage == 1)
startSound = true;
}
_stream->skip(part.size);
+ } else if (part.flags == 4) {
+ warning("Vmd::processFrame(): TODO: Addy 5 sound type 4 (%d)", part.size);
+ disableSound();
+ _stream->skip(part.size);
} else {
- warning("Unknown sound part type %d", part.flags);
+ warning("Vmd::processFrame(): Unknown sound type %d", part.flags);
_stream->skip(part.size);
}
+ _stream->seek(pos + part.size);
+
} else if ((part.type == kPartTypeVideo) && !_hasVideo) {
- warning("Header claims there's no video, but video frame part found");
+ warning("Vmd::processFrame(): Header claims there's no video, but video found (%d)", part.size);
+ _stream->skip(part.size);
} else if ((part.type == kPartTypeVideo) && _hasVideo) {
state.flags &= ~kStateNoVideoData;
@@ -1361,12 +1690,19 @@ CoktelVideo::State Vmd::processFrame(uint16 frame) {
state.bottom = MAX(state.bottom, b);
}
- } else if (part.type == 4) {
+ } else if (part.type == kPartTypeSeparator) {
+ } else if (part.type == kPartTypeExtraData) {
+ _stream->skip(part.size);
+ } else if (part.type == kPartType4) {
// Unknown
_stream->skip(part.size);
+ } else if (part.type == kPartTypeSpeech) {
+ state.flags |= kStateSpeech;
+ state.speechId = part.id;
+ // Always triggers when speech starts
+ _stream->skip(part.size);
} else {
- // Unknow type
-// warning("Unknown frame part type %d, size %d (%d of %d)", part.type, part.size, i + 1, _partsPerFrame);
+ warning("Vmd::processFrame(): Unknown frame part type %d, size %d (%d of %d)", part.type, part.size, i + 1, _partsPerFrame);
}
}
@@ -1380,7 +1716,7 @@ CoktelVideo::State Vmd::processFrame(uint16 frame) {
_audioStream->finish();
_mixer->stopHandle(_audioHandle);
_audioStream = 0;
- _soundStage = 0;
+ _soundStage = 0;
}
// If these are still 0x7FFF, no video data has been processed
@@ -1391,7 +1727,7 @@ CoktelVideo::State Vmd::processFrame(uint16 frame) {
return state;
}
-void Vmd::deRLE(byte *&srcPtr, byte *&destPtr, int16 len) {
+void Vmd::deRLE(byte *&destPtr, const byte *&srcPtr, int16 len) {
srcPtr++;
if (len & 1)
@@ -1418,23 +1754,60 @@ void Vmd::deRLE(byte *&srcPtr, byte *&destPtr, int16 len) {
}
}
+// A run-length-encoded sparse block
+void Vmd::renderBlockRLE(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight) {
+
+ for (int i = 0; i < height; i++) {
+ byte *destBak = dest;
+ uint16 pixWritten = 0;
+
+ while (pixWritten < width) {
+ uint16 pixCount = *src++;
+
+ if (pixCount & 0x80) {
+ pixCount = (pixCount & 0x7F) + 1;
+
+ if (*src != 0xFF) { // Normal copy
+ memcpy(dest, src, pixCount);
+ dest += pixCount;
+ src += pixCount;
+ } else
+ deRLE(dest, src, pixCount);
+
+ pixWritten += pixCount;
+ } else { // "Hole"
+ dest += pixCount + 1;
+ pixWritten += pixCount + 1;
+ }
+
+ }
+
+ dest = destBak + destWidth;
+ }
+
+}
+
uint32 Vmd::renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom) {
if (!_frameData || !_vidMem || (_width <= 0) || (_height <= 0))
return 0;
- int16 width = right - left + 1;
- int16 height = bottom - top + 1;
- int16 sW = _vidMemWidth;
- int16 sH = _vidMemHeight;
+ int16 width = right - left + 1;
+ int16 height = bottom - top + 1;
+ int16 sW = _vidMemWidth;
+ int16 sH = _vidMemHeight;
uint32 dataLen = _frameDataLen;
- byte *dataPtr = _frameData;
+
+ byte *dataPtr = _frameData;
byte *imdVidMem = _vidMem + sW * top + left;
byte *srcPtr;
- uint8 type;
- if ((width < 0) || (height < 0))
+ if ((left < 0) || (top < 0) || (right < 0) || (bottom < 0))
+ return 1;
+ if ((width <= 0) || (height <= 0))
return 1;
+ uint8 type;
byte *dest = imdVidMem;
if (Indeo3::isIndeo3(dataPtr, dataLen)) {
@@ -1445,12 +1818,12 @@ uint32 Vmd::renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom) {
width * (_doubleMode ? 2 : 1), height * (_doubleMode ? 2 : 1)))
return 0;
- type = 2;
+ type = 2;
srcPtr = _vidBuffer;
- width = _width * (_doubleMode ? 2 : 1);
+ width = _width * (_doubleMode ? 2 : 1);
height = _height * (_doubleMode ? 2 : 1);
- right = left + width - 1;
- bottom = top + height - 1;
+ right = left + width - 1;
+ bottom = top + height - 1;
} else {
@@ -1459,8 +1832,8 @@ uint32 Vmd::renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom) {
return 0;
}
- type = *dataPtr++;
- srcPtr = dataPtr;
+ type = *dataPtr++;
+ srcPtr = dataPtr;
if (_blitMode > 0) {
dest = _vidMemBuffer + postScaleX(_width) * (top - _y) + postScaleX((left - _x));
@@ -1469,10 +1842,13 @@ uint32 Vmd::renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom) {
sH = _height;
}
- if (type & 0x80) { // Frame data is compressed
+ if (type & 0x80) {
+ // Frame data is compressed
+
srcPtr = _vidBuffer;
type &= 0x7F;
if ((type == 2) && (postScaleX(width) == sW)) {
+ // Directly uncompress onto the video surface
deLZ77(dest, dataPtr);
blit(imdVidMem, dest, width, height);
return 1;
@@ -1482,109 +1858,22 @@ uint32 Vmd::renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom) {
}
- uint16 pixCount, pixWritten;
- byte *destBak;
-
- if (type == 1) { // Sparse block
- destBak = dest;
- for (int i = 0; i < height; i++) {
- pixWritten = 0;
- while (pixWritten < postScaleX(width)) {
- pixCount = *srcPtr++;
- if (pixCount & 0x80) { // Data
- pixCount = MIN<int>((pixCount & 0x7F) + 1, postScaleX(width) - pixWritten);
- memcpy(dest, srcPtr, pixCount);
-
- pixWritten += pixCount;
- dest += pixCount;
- srcPtr += pixCount;
- } else { // "Hole"
- pixCount = (pixCount + 1) % 256;
- pixWritten += pixCount;
- dest += pixCount;
- }
- }
- destBak += sW;
- dest = destBak;
- }
- } else if (type == 2) { // Whole block
- int16 w = MIN<int32>(postScaleX(width), sW);
- int16 h = MIN(height, sH);
-
- for (int i = 0; i < h; i++) {
- memcpy(dest, srcPtr, w);
- srcPtr += postScaleX(width);
- dest += sW;
- }
-
- } else if (type == 3) { // RLE block
- for (int i = 0; i < height; i++) {
- destBak = dest;
-
- pixWritten = 0;
- while (pixWritten < width) {
- pixCount = *srcPtr++;
- if (pixCount & 0x80) {
- pixCount = (pixCount & 0x7F) + 1;
-
- if (*srcPtr != 0xFF) { // Normal copy
- memcpy(dest, srcPtr, pixCount);
- dest += pixCount;
- srcPtr += pixCount;
- } else
- deRLE(srcPtr, dest, pixCount);
-
- pixWritten += pixCount;
- } else { // "Hole"
- dest += pixCount + 1;
- pixWritten += pixCount + 1;
- }
-
- }
- destBak += sW;
- dest = destBak;
- }
- } else if (type == 0x42) { // Whole quarter-wide block
- for (int i = 0; i < height; i++) {
- destBak = dest;
+ width = postScaleX(width);
+
+ // Evaluate the block type
+ if (type == 0x01)
+ renderBlockSparse (dest, srcPtr, width, height, sW, sH);
+ else if (type == 0x02)
+ renderBlockWhole (dest, srcPtr, width, height, sW, sH);
+ else if (type == 0x03)
+ renderBlockRLE (dest, srcPtr, width, height, sW, sH);
+ else if (type == 0x42)
+ renderBlockWhole4X (dest, srcPtr, width, height, sW, sH);
+ else if ((type & 0x0F) == 0x02)
+ renderBlockWhole2Y (dest, srcPtr, width, height, sW, sH);
+ else
+ renderBlockSparse2Y(dest, srcPtr, width, height, sW, sH);
- for (int j = 0; j < width; j += 4, dest += 4, srcPtr++)
- memset(dest, *srcPtr, 4);
-
- destBak += sW;
- dest = destBak;
- }
- } else if ((type & 0xF) == 2) { // Whole half-high block
- for (; height > 1; height -= 2, dest += sW + sW, srcPtr += width) {
- memcpy(dest, srcPtr, width);
- memcpy(dest + sW, srcPtr, width);
- }
- if (height == -1)
- memcpy(dest, srcPtr, width);
- } else { // Sparse half-high block
- destBak = dest;
- for (int i = 0; i < height; i += 2) {
- pixWritten = 0;
- while (pixWritten < width) {
- pixCount = *srcPtr++;
- if (pixCount & 0x80) { // Data
- pixCount = MIN((pixCount & 0x7F) + 1, width - pixWritten);
- memcpy(dest, srcPtr, pixCount);
- memcpy(dest + sW, srcPtr, pixCount);
-
- pixWritten += pixCount;
- dest += pixCount;
- srcPtr += pixCount;
- } else { // "Hole"
- pixCount = (pixCount + 1) % 256;
- pixWritten += pixCount;
- dest += pixCount;
- }
- }
- destBak += sW + sW;
- dest = destBak;
- }
- }
dest = _vidMemBuffer + postScaleX(_width) * (top - _y) + postScaleX(left - _x);
blit(imdVidMem, dest, width, height);
@@ -1673,129 +1962,278 @@ void Vmd::blit24(byte *dest, byte *src, int16 srcPitch, int16 width, int16 heigh
dither->nextLine();
dest += _vidMemWidth;
- src += 3 * srcPitch;
+ src += 3 * srcPitch;
}
delete dither;
}
-void Vmd::emptySoundSlice(uint32 size) {
- if (!_audioStream)
- return;
+byte *Vmd::deDPCM(const byte *data, uint32 &size, int32 init[2]) {
+ if (!data || (size == 0))
+ return 0;
- byte *soundBuf = new byte[size];
- assert(soundBuf);
+ int channels = (_soundStereo > 0) ? 2 : 1;
- memset(soundBuf, 0, size);
+ uint32 inSize = size;
+ uint32 outSize = size + channels;
+
+ int16 *out = new int16[outSize];
+ byte *sound = (byte *) out;
+
+ int channel = 0;
+
+ for (int i = 0; i < channels; i++) {
+ *out++ = TO_BE_16(init[channel]);
- _audioStream->queueBuffer(soundBuf, size);
+ channel = (channel + 1) % channels;
+ }
+
+ 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;
+ }
+
+ size = outSize * 2;
+ return sound;
}
-void Vmd::soundSlice8bit(uint32 size) {
+// Yet another IMA ADPCM variant
+byte *Vmd::deADPCM(const byte *data, uint32 &size, int32 init, int32 index) {
+ if (!data || (size == 0))
+ return 0;
+
+ uint32 outSize = size * 2;
+
+ int16 *out = new int16[outSize];
+ byte *sound = (byte *) out;
+
+ index = CLIP<int32>(index, 0, 88);
+
+ int32 predictor = _tableADPCM[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 += _tableADPCMStep[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 = _tableADPCM[index];
+
+ *out++ = TO_BE_16(init);
+ }
+
+ size = outSize * 2;
+ return sound;
+}
+
+byte *Vmd::soundEmpty(uint32 &size) {
if (!_audioStream)
- return;
+ return 0;
byte *soundBuf = new byte[size];
- assert(soundBuf);
+ memset(soundBuf, 0, size);
+
+ return soundBuf;
+}
+byte *Vmd::sound8bitDirect(uint32 &size) {
+ if (!_audioStream) {
+ _stream->skip(size);
+ return 0;
+ }
+
+ byte *soundBuf = new byte[size];
_stream->read(soundBuf, size);
unsignedToSigned(soundBuf, size);
- _audioStream->queueBuffer(soundBuf, size);
+ return soundBuf;
}
-void Vmd::soundSlice16bit(uint32 size, int16 &init) {
- if (!_audioStream)
- return;
+byte *Vmd::sound16bitDPCM(uint32 &size) {
+ if (!_audioStream) {
+ _stream->skip(size);
+ return 0;
+ }
- byte *dataBuf = new byte[size];
- byte *soundBuf = new byte[size * 2];
+ int32 init[2];
- _stream->read(dataBuf, size);
- deADPCM(soundBuf, dataBuf, init, size);
- _audioStream->queueBuffer(soundBuf, size * 2);
+ init[0] = _stream->readSint16LE();
+ size -= 2;
+
+ if (_soundStereo > 0) {
+ init[1] = _stream->readSint16LE();
+ size -= 2;
+ }
- delete[] dataBuf;
+ byte *data = new byte[size];
+ byte *sound = 0;
+
+ if (_stream->read(data, size) == size)
+ sound = deDPCM(data, size, init);
+
+ delete[] data;
+
+ return sound;
}
-void Vmd::filledSoundSlice(uint32 size) {
- if (_soundBytesPerSample == 1) {
- soundSlice8bit(size);
- } else if (_soundBytesPerSample == 2) {
- int16 init = _stream->readSint16LE();
- soundSlice16bit(size - 2, init);
+byte *Vmd::sound16bitADPCM(uint32 &size) {
+ if (!_audioStream) {
+ _stream->skip(size);
+ return 0;
}
+
+ 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;
}
-void Vmd::filledSoundSlices(uint32 size, uint32 mask) {
- int n = MIN<int>(_soundSlicesCount - 1, 31);
- for (int i = 0; i < n; i++) {
+void Vmd::emptySoundSlice(uint32 size) {
+ byte *sound = soundEmpty(size);
- if (mask & 1)
- emptySoundSlice(_soundSliceSize * _soundBytesPerSample);
- else
- filledSoundSlice(_soundSliceSize + 1);
+ if (sound)
+ _audioStream->queueBuffer(sound, size);
+}
+
+void Vmd::filledSoundSlice(uint32 size) {
+ byte *sound = 0;
+ if (_audioFormat == kAudioFormat8bitDirect)
+ sound = sound8bitDirect(size);
+ else if (_audioFormat == kAudioFormat16bitDPCM)
+ sound = sound16bitDPCM(size);
+ else if (_audioFormat == kAudioFormat16bitADPCM)
+ sound = sound16bitADPCM(size);
+
+ if (sound)
+ _audioStream->queueBuffer(sound, size);
+}
+
+uint8 Vmd::evaluateMask(uint32 mask, bool *fillInfo, uint8 &max) {
+ max = MIN<int>(_soundSlicesCount - 1, 31);
+
+ uint8 n = 0;
+ for (int i = 0; i < max; i++) {
+
+ if (!(mask & 1)) {
+ n++;
+ *fillInfo++ = true;
+ } else
+ *fillInfo++ = false;
mask >>= 1;
}
- if (_soundSlicesCount > 32)
- filledSoundSlice((_soundSlicesCount - 32) * _soundSliceSize);
+
+ return n;
}
-void Vmd::deADPCM(byte *soundBuf, byte *dataBuf, int16 &init, uint32 n) {
- int16 *out = (int16 *) soundBuf;
+void Vmd::filledSoundSlices(uint32 size, uint32 mask) {
+ bool fillInfo[32];
+
+ uint8 max;
+ uint8 n = evaluateMask(mask, fillInfo, max);
+
+ int32 extraSize;
+
+ extraSize = size - n * _soundDataSize;
+
+ if (_soundSlicesCount > 32)
+ extraSize -= (_soundSlicesCount - 32) * _soundDataSize;
+
+ if (n > 0)
+ extraSize /= n;
- int32 s = init;
- for (uint32 i = 0; i < n; i++) {
- if (dataBuf[i] & 0x80)
- s -= _tableADPCM[dataBuf[i] & 0x7F];
+ for (uint8 i = 0; i < max; i++)
+ if (fillInfo[i])
+ filledSoundSlice(_soundDataSize + extraSize);
else
- s += _tableADPCM[dataBuf[i]];
+ emptySoundSlice(_soundDataSize * _soundBytesPerSample);
- s = CLIP<int32>(s, -32768, 32767);
- *out++ = TO_BE_16(s);
- }
+ if (_soundSlicesCount > 32)
+ filledSoundSlice((_soundSlicesCount - 32) * _soundDataSize + _soundHeaderSize);
}
-bool Vmd::getAnchor(int16 frame, uint16 partType,
+bool Vmd::getPartCoords(int16 frame, PartType type,
int16 &x, int16 &y, int16 &width, int16 &height) {
- uint32 pos = _stream->pos();
+ if (frame >= _framesCount)
+ return false;
- _stream->seek(_frameInfoOffset);
- // Offsets to frames
- _stream->skip(_framesCount * 6);
- // Jump to the specified frame
- _stream->skip(_partsPerFrame * frame * 16);
+ Frame &f = _frames[frame];
- // Find the anchor part
- uint16 i;
- for (i = 0; i < _partsPerFrame; i++) {
- byte type = _stream->readByte();
+ // Look for a part matching the requested type, stopping at a separator
+ Part *part = 0;
+ for (int i = 0; i < _partsPerFrame; i++) {
+ Part &p = f.parts[i];
- if ((type == kPartTypeSeparator) || (type == partType))
+ if ((p.type == kPartTypeSeparator) || (p.type == type)) {
+ part = &p;
break;
-
- _stream->skip(15);
+ }
}
- if (i == _partsPerFrame) {
- // No anchor
-
- _stream->seek(pos);
+ if (!part)
return false;
- }
- _stream->skip(5);
- x = _stream->readSint16LE();
- y = _stream->readSint16LE();
- width = _stream->readSint16LE() - x + 1;
- height = _stream->readSint16LE() - y + 1;
+ x = part->left;
+ y = part->top;
+ width = part->right - part->left + 1;
+ height = part->bottom - part->top + 1;
- _stream->seek(pos);
return true;
}
+bool Vmd::getFrameCoords(int16 frame,
+ int16 &x, int16 &y, int16 &width, int16 &height) {
+
+ return getPartCoords(frame, kPartTypeVideo, x, y, width, height);
+}
+
bool Vmd::hasExtraData(const char *fileName) const {
for (uint i = 0; i < _extraData.size(); i++)
if (!scumm_stricmp(_extraData[i].name, fileName))
diff --git a/graphics/video/coktelvideo/coktelvideo.h b/graphics/video/coktelvideo/coktelvideo.h
index 58b56e18ec..db80b4c43d 100644
--- a/graphics/video/coktelvideo/coktelvideo.h
+++ b/graphics/video/coktelvideo/coktelvideo.h
@@ -76,7 +76,9 @@ public:
/** Had to explicitely seek to the frame. */
kStateSeeked = 0x2000,
/** Reached a break-point. */
- kStateBreak = 0x8000
+ kStateBreak = 0x8000,
+ /** Frame marks the beginning of speech. */
+ kStateSpeech = 0x4000000
};
struct State {
@@ -90,8 +92,10 @@ public:
int16 bottom;
/** Set accordingly to what was done. */
uint32 flags;
+ /** The id of the spoken words. */
+ uint16 speechId;
- State() : left(0), top(0), right(0), bottom(0), flags(0) { }
+ State() : left(0), top(0), right(0), bottom(0), flags(0), speechId(0) { }
};
virtual ~CoktelVideo() { }
@@ -123,8 +127,8 @@ public:
/** Returns the current frame's palette. */
virtual const byte *getPalette() const = 0;
- /** Reads the video's anchor pointer */
- virtual bool getAnchor(int16 frame, uint16 partType,
+ /** Returns the frame's coordinates */
+ virtual bool getFrameCoords(int16 frame,
int16 &x, int16 &y, int16 &width, int16 &height) = 0;
/** Returns whether that extra data file exists */
@@ -171,9 +175,6 @@ public:
/** Wait for the frame to end. */
virtual void waitEndFrame() = 0;
- /** Notifies the video that it was paused for duration ms. */
- virtual void notifyPaused(uint32 duration) = 0;
-
/** Copy the current frame.
*
* @param dest The memory to which to copy the current frame.
@@ -198,29 +199,26 @@ public:
Imd();
~Imd();
- uint32 getFeatures() const { return _features; }
- uint16 getFlags() const { return _flags; }
- int16 getX() const { return _x; }
- int16 getY() const { return _y; }
- int16 getWidth() const { return _width; }
- int16 getHeight() const { return _height; }
- uint16 getFramesCount() const { return _framesCount; }
- uint16 getCurrentFrame() const { return _curFrame; }
- int16 getFrameRate() const {
- if (_hasSound)
- return 1000 / (_soundSliceLength >> 16);
- return _frameRate;
- }
- uint32 getSyncLag() const { return _skipFrames; }
- const byte *getPalette() const { return _palette; }
-
- bool getAnchor(int16 frame, uint16 partType,
- int16 &x, int16 &y, int16 &width, int16 &height) { return false; }
-
- bool hasExtraData(const char *fileName) const { return false; }
- Common::MemoryReadStream *getExtraData(const char *fileName) { return 0; }
-
- void notifyPaused(uint32 duration) { }
+ uint32 getFeatures() const;
+ uint16 getFlags() const;
+
+ int16 getX() const;
+ int16 getY() const;
+ int16 getWidth() const;
+ int16 getHeight() const;
+
+ uint16 getFramesCount() const;
+ uint16 getCurrentFrame() const;
+ int16 getFrameRate() const;
+ uint32 getSyncLag() const;
+
+ const byte *getPalette() const;
+
+ bool getFrameCoords(int16 frame,
+ int16 &x, int16 &y, int16 &width, int16 &height);
+
+ bool hasExtraData(const char *fileName) const;
+ Common::MemoryReadStream *getExtraData(const char *fileName);
void setFrameRate(int16 frameRate);
@@ -231,7 +229,7 @@ public:
void setVideoMemory(byte *vidMem, uint16 width, uint16 height);
void setVideoMemory();
- void setDoubleMode(bool doubleMode) { }
+ void setDoubleMode(bool doubleMode);
void enableSound(Audio::Mixer &mixer);
void disableSound();
@@ -248,6 +246,22 @@ public:
uint16 x, uint16 y, uint16 pitch, int16 transp = -1);
protected:
+ enum Command {
+ kCommandNextSound = 0xFF00,
+ kCommandStartSound = 0xFF01,
+
+ kCommandBreak = 0xFFF0,
+ kCommandBreakSkip0 = 0xFFF1,
+ kCommandBreakSkip16 = 0xFFF2,
+ kCommandBreakSkip32 = 0xFFF3,
+ kCommandBreakMask = 0xFFF8,
+
+ kCommandPalette = 0xFFF4,
+ kCommandVideoData = 0xFFFC,
+
+ kCommandJump = 0xFFFD
+ };
+
struct Coord {
int16 left;
int16 top;
@@ -256,56 +270,104 @@ protected:
} PACKED_STRUCT;
Common::SeekableReadStream *_stream;
+
+ // Properties
uint16 _version;
uint32 _features;
uint16 _flags;
- int16 _x, _y, _width, _height;
- int16 _stdX, _stdY, _stdWidth, _stdHeight;
- uint16 _framesCount, _curFrame;
+
+ // Current coordinates
+ int16 _x;
+ int16 _y;
+ int16 _width;
+ int16 _height;
+
+ // Standard coordinates gives by the header
+ int16 _stdX;
+ int16 _stdY;
+ int16 _stdWidth;
+ int16 _stdHeight;
+
+ uint16 _framesCount;
+ uint16 _curFrame;
+
uint32 *_framesPos;
- uint32 _firstFramePos;
+ uint32 _firstFramePos;
Coord *_frameCoords;
- uint32 _frameDataSize, _vidBufferSize;
- byte *_frameData, *_vidBuffer;
+ // Buffer for raw frame data
+ byte *_frameData;
+ uint32 _frameDataSize;
uint32 _frameDataLen;
- byte _palette[768];
+ // Buffer for uncompressed raw frame data
+ byte *_vidBuffer;
+ uint32 _vidBufferSize;
- bool _hasOwnVidMem;
- byte *_vidMem;
- uint16 _vidMemWidth, _vidMemHeight;
+ byte _palette[768];
- bool _hasSound;
- bool _soundEnabled;
- uint8 _soundStage; // (0: no sound, 1: loaded, 2: playing)
- uint32 _skipFrames;
+ // Video memory
+ bool _hasOwnVidMem;
+ byte *_vidMem;
+ uint16 _vidMemWidth;
+ uint16 _vidMemHeight;
+ // Sound properties
uint16 _soundFlags;
- int16 _soundFreq;
- int16 _soundSliceSize;
- int16 _soundSlicesCount;
+ int16 _soundFreq;
+ int16 _soundSliceSize;
+ int16 _soundSlicesCount;
uint32 _soundSliceLength;
+ // Current sound state
+ bool _hasSound;
+ bool _soundEnabled;
+ uint8 _soundStage; // (0: no sound, 1: loaded, 2: playing)
+ uint32 _skipFrames;
+
Audio::AppendableAudioStream *_audioStream;
Audio::SoundHandle _audioHandle;
- int16 _frameRate;
+ // Current video state
+ int16 _frameRate;
uint32 _frameLength;
uint32 _lastFrameTime;
Audio::Mixer *_mixer;
- void unsignedToSigned(byte *buffer, int length) {
- while (length-- > 0) *buffer++ ^= 0x80;
- }
+ void unsignedToSigned(byte *buffer, int length);
void deleteVidMem(bool del = true);
void clear(bool del = true);
+ bool loadCoordinates();
+ bool loadFrameTableOffsets(uint32 &framesPosPos, uint32 &framesCoordsPos);
+ bool assessVideoProperties();
+ bool assessAudioProperties();
+ bool loadFrameTables(uint32 framesPosPos, uint32 framesCoordsPos);
+
State processFrame(uint16 frame);
uint32 renderFrame(int16 left, int16 top, int16 right, int16 bottom);
void deLZ77(byte *dest, byte *src);
+
+ void renderBlockWhole (byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight);
+ void renderBlockWhole4X (byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight);
+ void renderBlockWhole2Y (byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight);
+ void renderBlockSparse (byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight);
+ void renderBlockSparse2Y(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight);
+
+ void calcFrameCoords(uint16 frame, State &state);
+
+ void nextSoundSlice(bool hasNextCmd);
+ bool initialSoundSlice(bool hasNextCmd);
+ void emptySoundSlice(bool hasNextCmd);
+
+ void videoData(uint32 size, State &state);
};
class Vmd : public Imd {
@@ -313,7 +375,7 @@ public:
Vmd(Graphics::PaletteLUT *palLUT = 0);
~Vmd();
- bool getAnchor(int16 frame, uint16 partType,
+ bool getFrameCoords(int16 frame,
int16 &x, int16 &y, int16 &width, int16 &height);
bool hasExtraData(const char *fileName) const;
@@ -335,38 +397,58 @@ public:
protected:
enum PartType {
kPartTypeSeparator = 0,
- kPartTypeAudio = 1,
- kPartTypeVideo = 2,
- kPartTypeExtraData = 3
+ kPartTypeAudio = 1,
+ kPartTypeVideo = 2,
+ kPartTypeExtraData = 3,
+ kPartType4 = 4,
+ kPartTypeSpeech = 5
};
+
+ enum AudioFormat {
+ kAudioFormat8bitDirect = 0,
+ kAudioFormat16bitDPCM = 1,
+ kAudioFormat16bitADPCM = 2
+ };
+
struct ExtraData {
- char name[16];
+ char name[16];
uint32 offset;
uint32 size;
uint32 realSize;
+
+ ExtraData();
} PACKED_STRUCT;
+
struct Part {
PartType type;
- byte field_1;
- byte field_E;
- uint32 size;
- int16 left;
- int16 top;
- int16 right;
- int16 bottom;
- byte flags;
+ byte field_1;
+ byte field_E;
+ uint32 size;
+ int16 left;
+ int16 top;
+ int16 right;
+ int16 bottom;
+ uint16 id;
+ byte flags;
+
+ Part();
} PACKED_STRUCT;
+
struct Frame {
uint32 offset;
- Part *parts;
+ Part *parts;
- Frame() : parts(0) { }
- ~Frame() { delete[] parts; }
+ Frame();
+ ~Frame();
} PACKED_STRUCT;
- static const uint16 _tableADPCM[128];
+ // Tables for the audio decompressors
+ static const uint16 _tableDPCM[128];
+ static const int32 _tableADPCM[];
+ static const int32 _tableADPCMStep[];
- bool _hasVideo;
+ bool _hasVideo;
+ uint32 _videoCodec;
uint32 _frameInfoOffset;
uint16 _partsPerFrame;
@@ -374,9 +456,14 @@ protected:
Common::Array<ExtraData> _extraData;
- byte _soundBytesPerSample;
- byte _soundStereo; // (0: mono, 1: old-style stereo, 2: new-style stereo)
+ // Sound properties
+ byte _soundBytesPerSample;
+ byte _soundStereo; // (0: mono, 1: old-style stereo, 2: new-style stereo)
+ uint32 _soundHeaderSize;
+ uint32 _soundDataSize;
+ AudioFormat _audioFormat;
+ // Video properties
bool _externalCodec;
byte _blitMode;
byte _bytesPerPixel;
@@ -392,10 +479,21 @@ protected:
void clear(bool del = true);
+ bool getPartCoords(int16 frame, PartType type,
+ int16 &x, int16 &y, int16 &width, int16 &height);
+
+ bool assessVideoProperties();
+ bool assessAudioProperties();
+ void readFrameTable(int &numExtraData);
+ void readExtraData();
+
State processFrame(uint16 frame);
uint32 renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom);
- void deRLE(byte *&srcPtr, byte *&destPtr, int16 len);
+ void renderBlockRLE(byte *dest, const byte *src, int16 width, int16 height,
+ int16 destWidth, int16 destHeight);
+
+ void deRLE(byte *&destPtr, const byte *&srcPtr, int16 len);
inline int32 preScaleX(int32 x) const;
inline int32 postScaleX(int32 x) const;
@@ -404,12 +502,18 @@ protected:
void blit16(byte *dest, byte *src, int16 srcPitch, int16 width, int16 height);
void blit24(byte *dest, byte *src, int16 srcPitch, int16 width, int16 height);
+ byte *deDPCM(const byte *data, uint32 &size, int32 init[2]);
+ byte *deADPCM(const byte *data, uint32 &size, int32 init, int32 v28);
+
+ byte *soundEmpty(uint32 &size);
+ byte *sound8bitDirect(uint32 &size);
+ byte *sound16bitDPCM(uint32 &size);
+ byte *sound16bitADPCM(uint32 &size);
+
+ uint8 evaluateMask(uint32 mask, bool *fillInfo, uint8 &max);
void emptySoundSlice(uint32 size);
- void soundSlice8bit(uint32 size);
- void soundSlice16bit(uint32 size, int16 &init);
void filledSoundSlice(uint32 size);
void filledSoundSlices(uint32 size, uint32 mask);
- void deADPCM(byte *soundBuf, byte *dataBuf, int16 &init, uint32 n);
};
} // End of namespace Graphics
diff --git a/graphics/video/smk_decoder.cpp b/graphics/video/smk_decoder.cpp
index 9db8f0c730..8952f553b7 100644
--- a/graphics/video/smk_decoder.cpp
+++ b/graphics/video/smk_decoder.cpp
@@ -348,8 +348,8 @@ uint32 BigHuffmanTree::getCode(BitStream &bs) {
return v;
}
-SmackerDecoder::SmackerDecoder(Audio::Mixer *mixer)
- : _audioStarted(false), _audioStream(0), _mixer(mixer) {
+SmackerDecoder::SmackerDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType)
+ : _audioStarted(false), _audioStream(0), _mixer(mixer), _soundType(soundType) {
}
SmackerDecoder::~SmackerDecoder() {
@@ -583,7 +583,7 @@ bool SmackerDecoder::decodeNextFrame() {
}
if (!_audioStarted) {
- _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream, -1, 255);
+ _mixer->playInputStream(_soundType, &_audioHandle, _audioStream, -1, 255);
_audioStarted = true;
}
} else {
diff --git a/graphics/video/smk_decoder.h b/graphics/video/smk_decoder.h
index e70d0e6454..e28d85119d 100644
--- a/graphics/video/smk_decoder.h
+++ b/graphics/video/smk_decoder.h
@@ -55,7 +55,8 @@ class BigHuffmanTree;
*/
class SmackerDecoder : public VideoDecoder {
public:
- SmackerDecoder(Audio::Mixer *mixer);
+ SmackerDecoder(Audio::Mixer *mixer,
+ Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType);
virtual ~SmackerDecoder();
int getHeight();
@@ -113,6 +114,7 @@ private:
// The RGB palette
byte *_palette;
+ Audio::Mixer::SoundType _soundType;
Audio::Mixer *_mixer;
bool _audioStarted;
Audio::AppendableAudioStream *_audioStream;
diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp
index 3d4c10859f..7551acac48 100644
--- a/gui/ListWidget.cpp
+++ b/gui/ListWidget.cpp
@@ -24,6 +24,8 @@
#include "common/system.h"
#include "common/events.h"
+#include "common/frac.h"
+
#include "gui/ListWidget.h"
#include "gui/ScrollBarWidget.h"
#include "gui/dialog.h"
@@ -538,13 +540,15 @@ void ListWidget::reflowLayout() {
// of the list.
// We do a rough rounding on the decimal places of Entries Per Page,
// to add another entry even if it goes a tad over the padding.
- _entriesPerPage = ((_h - _topPadding - _bottomPadding) << 16) / kLineHeight;
+ frac_t entriesPerPage = intToFrac(_h - _topPadding - _bottomPadding) / kLineHeight;
- if ((uint)(_entriesPerPage & 0xFFFF) >= 0xF000)
- _entriesPerPage += (1 << 16);
+ // Our threshold before we add another entry is 0.9375 (0xF000 with FRAC_BITS being 16).
+ const frac_t threshold = intToFrac(15) / 16;
- _entriesPerPage >>= 16;
+ if ((frac_t)(entriesPerPage & FRAC_LO_MASK) >= threshold)
+ entriesPerPage += FRAC_ONE;
+ _entriesPerPage = fracToInt(entriesPerPage);
assert(_entriesPerPage > 0);
delete[] _textWidth;
diff --git a/gui/ScrollBarWidget.cpp b/gui/ScrollBarWidget.cpp
index 6e27535bfd..f6b36b3aa0 100644
--- a/gui/ScrollBarWidget.cpp
+++ b/gui/ScrollBarWidget.cpp
@@ -63,9 +63,9 @@ void ScrollBarWidget::handleMouseDown(int x, int y, int button, int clickCount)
_currentPos++;
_draggingPart = kDownArrowPart;
} else if (y < _sliderPos) {
- _currentPos -= _entriesPerPage;
+ _currentPos -= _entriesPerPage - 1;
} else if (y >= _sliderPos + _sliderHeight) {
- _currentPos += _entriesPerPage;
+ _currentPos += _entriesPerPage - 1;
} else {
_draggingPart = kSliderPart;
_sliderDeltaMouseDownPos = y - _sliderPos;
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index c5758392a7..d7527b61dd 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -32,7 +32,7 @@
#include "graphics/surface.h"
#include "graphics/fontman.h"
-#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.5"
+#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.6"
namespace Graphics {
struct DrawStep;
diff --git a/gui/browser.cpp b/gui/browser.cpp
index 48382e880b..f4719f4850 100644
--- a/gui/browser.cpp
+++ b/gui/browser.cpp
@@ -43,7 +43,7 @@ enum {
*/
BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
- : Dialog("browser") {
+ : Dialog("Browser") {
_titleRef = CFStringCreateWithCString(0, title, CFStringGetSystemEncoding());
_isDirBrowser = dirBrowser;
}
diff --git a/gui/credits.h b/gui/credits.h
index 172d44603d..5ddae4ea37 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -16,6 +16,12 @@ static const char *credits[] = {
"C1""Engine Teams",
"C1""SCUMM",
"C0""Torbj\366rn Andersson",
+"C0""James Brown",
+"C2""(retired)",
+"C0""Jonathan Gray",
+"C2""(retired)",
+"C0""Vincent Hamm",
+"C2""(retired)",
"C0""Max Horn",
"C0""Travis Howell",
"C0""Pawel Kolodziejski",
@@ -23,8 +29,12 @@ static const char *credits[] = {
"C0""Gregory Montoir",
"C0""Eugene Sandulenko",
"C2""FT INSANE, MM NES, MM C64, game detection, Herc/CGA",
+"C0""Ludvig Strigeus",
+"C2""(retired)",
"",
"C1""HE",
+"C0""Jonathan Gray",
+"C2""(retired)",
"C0""Travis Howell",
"C0""Gregory Montoir",
"C0""Eugene Sandulenko",
@@ -37,44 +47,65 @@ static const char *credits[] = {
"C0""Walter van Niftrik",
"C0""Kari Salminen",
"C0""Eugene Sandulenko",
+"C0""David Symonds",
+"C2""(retired)",
"",
"C1""AGOS",
"C0""Torbj\366rn Andersson",
"C0""Paul Gilbert",
"C0""Travis Howell",
+"C0""Oliver Kiehl",
+"C2""(retired)",
+"C0""Ludvig Strigeus",
+"C2""(retired)",
"",
"C1""BASS",
+"C0""Robert G\366ffringmann",
+"C2""(retired)",
+"C0""Oliver Kiehl",
+"C2""(retired)",
"C0""Joost Peters",
"",
"C1""Broken Sword 1",
+"C0""Fabio Battaglia",
+"C2""PSX version support",
+"C0""Robert G\366ffringmann",
+"C2""(retired)",
"",
"C1""Broken Sword 2",
"C0""Torbj\366rn Andersson",
+"C0""Fabio Battaglia",
+"C2""PSX version support",
+"C0""Jonathan Gray",
+"C2""(retired)",
"",
"C1""Cinematique evo 1",
"C0""Vincent Hamm",
-"C2""original CinE engine author",
+"C2""(retired)",
"C0""Pawel Kolodziejski",
"C0""Gregory Montoir",
+"C0""Kari Salminen",
"C0""Eugene Sandulenko",
"",
"C1""Cinematique evo 2",
-"C0""Vincent Hamm",
-"C2""original CruisE engine author",
"C0""Paul Gilbert",
+"C0""Vincent Hamm",
+"C2""(retired)",
"",
"C1""Drascula",
"C0""Filippos Karapetis",
"C0""Pawel Kolodziejski",
"",
"C1""FOTAQ",
+"C0""David Eriksson",
+"C2""(retired)",
"C0""Gregory Montoir",
"C0""Joost Peters",
"",
"C1""Gob",
"C0""Torbj\366rn Andersson",
+"C0""Arnaud Boutonn\351",
"C0""Sven Hesse",
-"C0""Willem Jan Palenstijn",
"C0""Eugene Sandulenko",
"",
"C1""Groovie",
@@ -108,7 +139,6 @@ static const char *credits[] = {
"",
"C1""SAGA",
"C0""Torbj\366rn Andersson",
-"C0""Sven Hesse",
"C0""Filippos Karapetis",
"C0""Andrew Kurushin",
"C0""Eugene Sandulenko",
@@ -119,11 +149,14 @@ static const char *credits[] = {
"C0""Max Horn",
"C0""Filippos Karapetis",
"C0""Walter van Niftrik",
+"C0""Willem Jan Palenstijn",
"C0""Jordi Vilalta Prat",
"C0""Lars Skovlund",
"",
"C1""Tinsel",
"C0""Torbj\366rn Andersson",
+"C0""Fabio Battaglia",
+"C2""PSX version support",
"C0""Paul Gilbert",
"C0""Sven Hesse",
"C0""Max Horn",
@@ -157,9 +190,13 @@ static const char *credits[] = {
"C0""Chris Apers",
"",
"C1""PocketPC / WinCE",
+"C0""Nicolas Bacca",
+"C2""(retired)",
"C0""Kostas Nakos",
"",
"C1""PlayStation 2",
+"C0""Robert G\366ffringmann",
+"C2""(retired)",
"C0""Max Lingua",
"",
"C1""PSP (PlayStation Portable)",
@@ -185,22 +222,28 @@ static const char *credits[] = {
"C0""Eugene Sandulenko",
"",
"C1""GUI",
+"C0""Vicent Marti",
"C0""Eugene Sandulenko",
"C0""Johannes Schickel",
"",
"C1""Miscellaneous",
"C0""David Corrales-Lopez",
-"C2""Filesystem access improvements (GSoC 2007 task)",
+"C2""Filesystem access improvements (GSoC 2007 task) (retired)",
"C0""Jerome Fisher",
-"C2""MT-32 emulator",
+"C2""MT-32 emulator (retired)",
+"C0""Benjamin Haisch",
+"C2""Heavily improved de-/encoder for DXA videos",
"C0""Jochen Hoenicke",
-"C2""Speaker & PCjr sound support, AdLib work",
+"C2""Speaker & PCjr sound support, AdLib work (retired)",
"C0""Chris Page",
-"C2""Return to launcher, savestate improvements, leak fixes, ... (GSoC 2008 task)",
+"C2""Return to launcher, savestate improvements, leak fixes, ... (GSoC 2008 task) (retired)",
"C0""Robin Watts",
"C2""ARM assembly routines for nice speedups on several ports; improvements to the sound mixer",
"",
"",
+"C1""Website (code)",
+"C0""Fredrik Wendel",
+"",
"C1""Website (content)",
"C0""All active team members",
"C0""",
@@ -211,126 +254,34 @@ static const char *credits[] = {
"C0""Matthew Hoops",
"C2""Wiki editor",
"",
-"C1""FreeSCI Contributors",
-"C0""Anders Baden Nielsen",
-"C2""PPC testing",
-"C0""Bas Zoetekouw",
-"C2""Man pages, debian package management, CVS maintenance",
-"C0""Carl Muckenhoupt",
-"C2""Sources to the SCI resource viewer tools that started it all",
-"C0""Chris Kehler",
-"C2""Makefile enhancements",
-"C0""Christoph Reichenbach",
-"C2""UN*X code, VM/Graphics/Sound/other infrastructure",
-"C0""Christopher T. Lansdown",
-"C2""Original CVS maintainer, Alpha compatibility fixes",
-"C0""Claudio Matsuoka",
-"C2""CVS snapshots, daily builds, BeOS and cygwin ports",
-"C0""Dark Minister",
-"C2""SCI research (bytecode and parser)",
-"C0""Dmitry Jemerov",
-"C2""Port to the Win32 platform, numerous bugfixes",
-"C0""Emmanuel Jeandel",
-"C2""Bugfixes and bug reports",
-"C0""Francois-R Boyer",
-"C2""MT-32 information and mapping code",
-"C0""George Reid",
-"C2""FreeBSD package management",
-"C0""Hubert Maier",
-"C2""AmigaOS 4 port",
-"C0""Hugues Valois",
-"C2""Game selection menu",
-"C0""Johannes Manhave",
-"C2""Document format translation",
-"C0""Jordi Vilalta",
-"C2""Numerous code and website clean-up patches",
-"C0""Lars Skovlund",
-"C2""Project maintenance, most documentation, bugfixes, SCI1 support",
-"C0""Magnus Reftel",
-"C2""Heap implementation, Python class viewer, bugfixes",
-"C0""Matt Hargett",
-"C2""Clean-ups, bugfixes, Hardcore QA, Win32",
-"C0""Max Horn",
-"C2""SetJump implementation",
-"C0""Paul David Doherty",
-"C2""Game version information",
-"C0""Petr Vyhnak",
-"C2""The DCL-INFLATE algorithm, many Win32 improvements",
-"C0""Rainer Canavan",
-"C2""IRIX MIDI driver and bug fixes",
-"C0""Rainer De Temple",
-"C2""SCI research",
-"C0""Ravi I.",
-"C2""SCI0 sound resource specification",
-"C0""Ruediger Hanke",
-"C2""Port to the MorphOS platform",
-"C0""Rune Orsval",
-"C2""Configuration file editor",
-"C0""Rickard Lind",
-"C2""MT32->GM MIDI mapping magic, sound research",
-"C0""Rink Springer",
-"C2""Port to the DOS platform, several bug fixes",
-"C0""Robey Pointer",
-"C2""Bug tracking system hosting",
-"C0""Sergey Lapin",
-"C2""Port of Carl's type 2 decompression code",
-"C0""Solomon Peachy",
-"C2""SDL ports and much of the sound subsystem",
-"C0""Vyacheslav Dikonov",
-"C2""Config script improvements",
-"C0""Walter van Niftrik",
-"C2""Ports to the Dreamcast and GP32 platforms",
-"C0""Xiaojun Chen",
-"C0""Sean Terrell",
-"C0""Special thanks to Prof. Dr. Gary Nutt for allowing the FreeSCI VM extension as a course project in his Advanced OS course",
-"C0""",
-"C0""Special thanks to Bob Heitman and Corey Cole for their support of FreeSCI",
-"C0""",
-"",
"C1""Retired Team Members",
-"C0""Tore Anderson",
-"C2""Former Debian GNU/Linux maintainer",
-"C0""Nicolas Bacca",
-"C2""Former WinCE porter",
"C0""Ralph Brorsen",
"C2""Help with GUI implementation",
"C0""Jamieson Christian",
"C2""iMUSE, MIDI, all things musical",
-"C0""David Eriksson",
-"C2""Engines: FOTAQ",
-"C0""Hans-J\366rg Frieden",
-"C2""Former AmigaOS 4 packager",
-"C0""Robert G\366ffringmann",
-"C2""Original PS2 porter; Engines: BASS, BS1",
-"C0""Jonathan Gray",
-"C2""Engines: SCUMM, HE, BS2",
-"C0""R\374diger Hanke",
-"C2""Port: MorphOS",
"C0""Felix Jakschitsch",
"C2""Zak256 reverse engineering",
-"C0""Oliver Kiehl",
-"C2""Engines: AGOS, BASS",
"C0""Mutwin Kraus",
"C2""Original MacOS porter",
"C0""Peter Moraliyski",
"C2""Port: GP32",
-"C0""Juha Niemim\344ki",
-"C2""Former AmigaOS 4 packager",
"C0""Jeremy Newman",
"C2""Former webmaster",
"C0""Lionel Ulmer",
"C2""Port: X11",
"C0""Won Star",
"C2""Former GP32 porter",
-"C0""David Symonds",
-"C2""Engines: AGI",
"",
"",
"C1""Other contributions",
"",
"C1""Packages",
"C1""AmigaOS 4",
+"C0""Hans-J\366rg Frieden",
+"C2""(retired)",
"C0""Hubert Maier",
+"C0""Juha Niemim\344ki",
+"C2""(retired)",
"",
"C1""Atari/FreeMiNT",
"C0""Keith Scroggins",
@@ -340,6 +291,8 @@ static const char *credits[] = {
"C0""Luc Schrijvers",
"",
"C1""Debian GNU/Linux",
+"C0""Tore Anderson",
+"C2""(retired)",
"C0""David Weinehall",
"",
"C1""Fedora / RedHat",
@@ -354,6 +307,8 @@ static const char *credits[] = {
"",
"C1""MorphOS",
"C0""Fabien Coeurjoly",
+"C0""R\374diger Hanke",
+"C2""(retired)",
"",
"C1""OS/2",
"C0""Paul Smedley",
@@ -399,8 +354,6 @@ static const char *credits[] = {
"C2""CinE engine objectification",
"C0""Thomas Fach-Pedersen",
"C2""ProTracker module player",
-"C0""Benjamin Haisch",
-"C2""Heavily improved de-/encoder for DXA videos",
"C0""Janne Huttunen",
"C2""V3 actor mask support, Dig/FT SMUSH audio",
"C0""Kov\341cs Endre J\341nos",
@@ -425,6 +378,8 @@ static const char *credits[] = {
"C2""Initial MI1 CD music support",
"C0""Quietust",
"C2""Sound support for Amiga SCUMM V2/V3 games, MM NES support",
+"C0""segra",
+"C2""Improved support for Apple II/C64 versions of MM",
"C0""Andreas R\366ver",
"C2""Broken Sword 1/2 MPEG2 cutscene support",
"C0""Edward Rudd",
@@ -434,6 +389,82 @@ static const char *credits[] = {
"C0""Andr\351 Souza",
"C2""SDL-based OpenGL renderer",
"",
+"C1""FreeSCI Contributors",
+"C0""Anders Baden Nielsen",
+"C2""PPC testing",
+"C0""Bas Zoetekouw",
+"C2""Man pages, debian package management, CVS maintenance",
+"C0""Carl Muckenhoupt",
+"C2""Sources to the SCI resource viewer tools that started it all",
+"C0""Chris Kehler",
+"C2""Makefile enhancements",
+"C0""Christoph Reichenbach",
+"C2""UN*X code, VM/Graphics/Sound/other infrastructure",
+"C0""Christopher T. Lansdown",
+"C2""Original CVS maintainer, Alpha compatibility fixes",
+"C0""Claudio Matsuoka",
+"C2""CVS snapshots, daily builds, BeOS and cygwin ports",
+"C0""Dark Minister",
+"C2""SCI research (bytecode and parser)",
+"C0""Dmitry Jemerov",
+"C2""Port to the Win32 platform, numerous bugfixes",
+"C0""Emmanuel Jeandel",
+"C2""Bugfixes and bug reports",
+"C0""Francois-R Boyer",
+"C2""MT-32 information and mapping code",
+"C0""George Reid",
+"C2""FreeBSD package management",
+"C0""Hubert Maier",
+"C2""AmigaOS 4 port",
+"C0""Hugues Valois",
+"C2""Game selection menu",
+"C0""Johannes Manhave",
+"C2""Document format translation",
+"C0""Jordi Vilalta",
+"C2""Numerous code and website clean-up patches",
+"C0""Lars Skovlund",
+"C2""Project maintenance, most documentation, bugfixes, SCI1 support",
+"C0""Magnus Reftel",
+"C2""Heap implementation, Python class viewer, bugfixes",
+"C0""Matt Hargett",
+"C2""Clean-ups, bugfixes, Hardcore QA, Win32",
+"C0""Max Horn",
+"C2""SetJump implementation",
+"C0""Paul David Doherty",
+"C2""Game version information",
+"C0""Petr Vyhnak",
+"C2""The DCL-INFLATE algorithm, many Win32 improvements",
+"C0""Rainer Canavan",
+"C2""IRIX MIDI driver and bug fixes",
+"C0""Rainer De Temple",
+"C2""SCI research",
+"C0""Ravi I.",
+"C2""SCI0 sound resource specification",
+"C0""Ruediger Hanke",
+"C2""Port to the MorphOS platform",
+"C0""Rune Orsval",
+"C2""Configuration file editor",
+"C0""Rickard Lind",
+"C2""MT32->GM MIDI mapping magic, sound research",
+"C0""Rink Springer",
+"C2""Port to the DOS platform, several bug fixes",
+"C0""Robey Pointer",
+"C2""Bug tracking system hosting",
+"C0""Sergey Lapin",
+"C2""Port of Carl's type 2 decompression code",
+"C0""Solomon Peachy",
+"C2""SDL ports and much of the sound subsystem",
+"C0""Vyacheslav Dikonov",
+"C2""Config script improvements",
+"C0""Walter van Niftrik",
+"C2""Ports to the Dreamcast and GP32 platforms",
+"C0""Xiaojun Chen",
+"C0""Sean Terrell",
+"C0""Special thanks to Prof. Dr. Gary Nutt for allowing the FreeSCI VM extension as a course project in his Advanced OS course.",
+"C0""",
+"C0""Special thanks to Bob Heitman and Corey Cole for their support of FreeSCI.",
+"C0""",
+"",
"C0""And to all the contributors, users, and beta testers we've missed. Thanks!",
"C0""",
"",
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 181403484b..78ada04cd6 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -27,10 +27,14 @@
#include "common/system.h"
#include "gui/debugger.h"
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
#include "gui/console.h"
+#elif defined(USE_READLINE)
+ #include <readline/readline.h>
+ #include <readline/history.h>
#endif
+
namespace GUI {
Debugger::Debugger() {
@@ -39,9 +43,11 @@ Debugger::Debugger() {
_isAttached = false;
_errStr = NULL;
_firstTime = true;
+#ifndef USE_TEXT_CONSOLE
_debuggerDialog = new GUI::ConsoleDialog(1.0f, 0.67f);
_debuggerDialog->setInputCallback(debuggerInputCallback, this);
_debuggerDialog->setCompletionCallback(debuggerCompletionCallback, this);
+#endif
//DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
DCmd_Register("exit", WRAP_METHOD(Debugger, Cmd_Exit));
@@ -55,7 +61,9 @@ Debugger::Debugger() {
}
Debugger::~Debugger() {
+#ifndef USE_TEXT_CONSOLE
delete _debuggerDialog;
+#endif
}
@@ -65,7 +73,7 @@ int Debugger::DebugPrintf(const char *format, ...) {
va_start(argptr, format);
int count;
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
count = _debuggerDialog->vprintf(format, argptr);
#else
count = ::vprintf(format, argptr);
@@ -112,9 +120,22 @@ void Debugger::onFrame() {
}
}
+#if defined(USE_TEXT_CONSOLE) && defined(USE_READLINE)
+namespace {
+Debugger *g_readline_debugger;
+
+char *readline_completionFunction(const char *text, int state) {
+ return g_readline_debugger->readlineComplete(text, state);
+}
+} // end of anonymous namespace
+#endif
+
// Main Debugger Loop
void Debugger::enter() {
-#if USE_CONSOLE
+ // TODO: Having three I/O methods #ifdef-ed in this file is not the
+ // cleanest approach to this...
+
+#ifndef USE_TEXT_CONSOLE
if (_firstTime) {
DebugPrintf("Debugger started, type 'exit' to return to the game.\n");
DebugPrintf("Type 'help' to see a little list of commands and variables.\n");
@@ -129,18 +150,28 @@ void Debugger::enter() {
_debuggerDialog->runModal();
#else
- // TODO: compared to the console input, this here is very bare bone.
- // For example, no support for tab completion and no history. At least
- // we should re-add (optional) support for the readline library.
- // Or maybe instead of choosing between a console dialog and stdio,
- // we should move that choice into the ConsoleDialog class - that is,
- // the console dialog code could be #ifdef'ed to not print to the dialog
- // but rather to stdio. This way, we could also reuse the command history
- // and tab completion of the console. It would still require a lot of
- // work, but at least no dependency on a 3rd party library...
-
printf("Debugger entered, please switch to this console for input.\n");
+#ifdef USE_READLINE
+ // TODO: add support for saving/loading history?
+
+ g_readline_debugger = this;
+ rl_completion_entry_function = &readline_completionFunction;
+
+ char *line_read = 0;
+ do {
+ free(line_read);
+ line_read = readline("debug> ");
+
+ if (line_read && line_read[0])
+ add_history(line_read);
+
+ } while (line_read && parseCommand(line_read));
+
+ free(line_read);
+ line_read = 0;
+
+#else
int i;
char buf[256];
@@ -156,6 +187,7 @@ void Debugger::enter() {
if (i == 0)
continue;
} while (parseCommand(buf));
+#endif
#endif
}
@@ -307,7 +339,8 @@ bool Debugger::tabComplete(const char *input, Common::String &completion) const
} else {
// take common prefix of previous match and this command
for (uint j = 0; j < completion.size(); j++) {
- if (completion[j] != i->_key[inputlen + j]) {
+ if (inputlen + j >= i->_key.size() ||
+ completion[j] != i->_key[inputlen + j]) {
completion = Common::String(completion.begin(), completion.begin() + j);
// If there is no unambiguous completion, abort
if (completion.empty())
@@ -325,6 +358,29 @@ bool Debugger::tabComplete(const char *input, Common::String &completion) const
return true;
}
+#if defined(USE_TEXT_CONSOLE) && defined(USE_READLINE)
+char *Debugger::readlineComplete(const char *input, int state) {
+ static CommandsMap::const_iterator iter;
+
+ // We assume that _cmds isn't changed between calls to readlineComplete,
+ // unless state is 0.
+ if (state == 0) {
+ iter = _cmds.begin();
+ } else {
+ ++iter;
+ }
+
+ for (; iter != _cmds.end(); ++iter) {
+ if (iter->_key.hasPrefix(input)) {
+ char *ret = (char *)malloc(iter->_key.size() + 1);
+ strcpy(ret, iter->_key.c_str());
+ return ret;
+ }
+ }
+ return 0;
+}
+#endif
+
// Variable registration function
void Debugger::DVar_Register(const Common::String &varname, void *pointer, int type, int optional) {
// TODO: Filter out duplicates
@@ -356,8 +412,15 @@ bool Debugger::Cmd_Exit(int argc, const char **argv) {
// Print a list of all registered commands (and variables, if any),
// nicely word-wrapped.
bool Debugger::Cmd_Help(int argc, const char **argv) {
-
+#ifndef USE_TEXT_CONSOLE
const int charsPerLine = _debuggerDialog->getCharsPerLine();
+#elif defined(USE_READLINE)
+ int charsPerLine, rows;
+ rl_get_screen_size(&rows, &charsPerLine);
+#else
+ // Can we do better?
+ const int charsPerLine = 80;
+#endif
int width, size;
uint i;
@@ -452,7 +515,7 @@ bool Debugger::Cmd_DebugFlagDisable(int argc, const char **argv) {
}
// Console handler
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
bool Debugger::debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon) {
Debugger *debugger = (Debugger *)refCon;
diff --git a/gui/debugger.h b/gui/debugger.h
index e84da594be..07fdddb808 100644
--- a/gui/debugger.h
+++ b/gui/debugger.h
@@ -32,10 +32,7 @@
namespace GUI {
-// Choose between text console or ScummConsole
-#define USE_CONSOLE 1
-
-#ifdef USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
class ConsoleDialog;
#endif
@@ -86,7 +83,9 @@ private:
bool _isAttached;
char *_errStr;
bool _firstTime;
+#ifndef USE_TEXT_CONSOLE
GUI::ConsoleDialog *_debuggerDialog;
+#endif
protected:
// Hook for subclasses: Called just before enter() is run
@@ -118,11 +117,15 @@ protected:
bool Cmd_DebugFlagEnable(int argc, const char **argv);
bool Cmd_DebugFlagDisable(int argc, const char **argv);
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
private:
static bool debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon);
static bool debuggerCompletionCallback(GUI::ConsoleDialog *console, const char *input, Common::String &completion, void *refCon);
+#elif defined(USE_READLINE)
+public:
+ char *readlineComplete(const char *input, int state);
#endif
+
};
} // End of namespace GUI
diff --git a/gui/options.cpp b/gui/options.cpp
index 5991a204e9..0d2d6e0120 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -68,8 +68,8 @@ enum {
static const char *savePeriodLabels[] = { "Never", "every 5 mins", "every 10 mins", "every 15 mins", "every 30 mins", 0 };
static const int savePeriodValues[] = { 0, 5 * 60, 10 * 60, 15 * 60, 30 * 60, -1 };
-static const char *outputRateLabels[] = { "<default>", "22 kHz", "8 kHz", "11kHz", "44 kHz", "48 kHz", 0 };
-static const int outputRateValues[] = { 0, 22050, 8000, 11025, 44100, 48000, -1 };
+static const char *outputRateLabels[] = { "<default>", "8 kHz", "11kHz", "22 kHz", "44 kHz", "48 kHz", 0 };
+static const int outputRateValues[] = { 0, 8000, 11025, 22050, 44100, 48000, -1 };
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 0331c90fbb..64fb0e517a 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1,5 +1,5 @@
"<?xml version = '1.0'?>"
-"<layout_info resolution='-320xY,-256x240'> "
+"<layout_info resolution='-320xY,-256x240,-Xx272'> "
"<globals> "
"<def var='Line.Height' value='16' /> "
"<def var='Font.Height' value='16' /> "
@@ -1492,7 +1492,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' "
"/> "
@@ -1500,7 +1500,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' "
"/> "
@@ -1508,7 +1508,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' "
"/> "
@@ -1516,7 +1516,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' "
"/> "
@@ -1524,7 +1524,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
+"<layout type='vertical' padding='8,8,8,8'> "
"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='Id' "
"width='35' "
@@ -1569,7 +1569,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
+"<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' "
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index ce21ea5487..0e1d8c539d 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 0593de00d4..4dc5cc5982 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.5:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.6:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index e886a1a2f0..029c7479ac 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -23,7 +23,7 @@
- $Id$
-
-->
-<layout_info resolution = '-320xY, -256x240'>
+<layout_info resolution = '-320xY, -256x240, -Xx272'>
<globals>
<def var = 'Line.Height' value = '16' />
<def var = 'Font.Height' value = '16' />
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index b4143964af..da56f0178a 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -454,7 +454,7 @@
</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'
/>
@@ -463,7 +463,7 @@
</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'
/>
@@ -472,7 +472,7 @@
</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'
/>
@@ -481,7 +481,7 @@
</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'
/>
@@ -490,7 +490,7 @@
</dialog>
<dialog name = 'GameOptions_Game' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
- <layout type = 'vertical' padding = '16, 16, 16, 16'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
<widget name = 'Id'
width = '35'
@@ -536,7 +536,7 @@
</dialog>
<dialog name = 'GameOptions_Paths' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
- <layout type = 'vertical' padding = '16, 16, 16, 16'>
+ <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'
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index b38ee79e84..fb3a0b1c2d 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index 32b51c573d..3fbbdf8d46 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.5:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.6:ScummVM Modern Theme:No Author]
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index 8c13217c65..e6a01d12a1 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -23,7 +23,7 @@
- $Id$
-
-->
-<layout_info resolution = '-320xY, -256x240'>
+<layout_info resolution = '-320xY, -256x240, -Xx272'>
<globals>
<def var = 'Line.Height' value = '16' />
<def var = 'Font.Height' value = '16' />
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index 693efaaca9..c514ccc458 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -450,7 +450,7 @@
</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'
/>
@@ -459,7 +459,7 @@
</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'
/>
@@ -468,7 +468,7 @@
</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'
/>
@@ -477,7 +477,7 @@
</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'
/>
@@ -486,7 +486,7 @@
</dialog>
<dialog name = 'GameOptions_Game' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
- <layout type = 'vertical' padding = '16, 16, 16, 16'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
<widget name = 'Id'
width = '35'
@@ -532,7 +532,7 @@
</dialog>
<dialog name = 'GameOptions_Paths' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'>
- <layout type = 'vertical' padding = '16, 16, 16, 16'>
+ <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'
diff --git a/ports.mk b/ports.mk
index 8fa4e5b211..7000ae75ce 100644
--- a/ports.mk
+++ b/ports.mk
@@ -205,3 +205,31 @@ endif
$(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip wiidist/scummvm/
.PHONY: deb bundle osxsnap win32dist wiidist install uninstall
+
+#
+# ARM specific
+#
+ifdef USE_TREMOLO
+DEFINES += -DUSE_TREMOR -DUSE_VORBIS -DUSE_TREMOLO
+LIBS += -ltremolo
+endif
+
+ifdef USE_ARM_SMUSH_ASM
+DEFINES += -DUSE_ARM_SMUSH_ASM
+endif
+
+ifdef USE_ARM_SOUND_ASM
+DEFINES += -DUSE_ARM_SOUND_ASM
+endif
+
+ifdef USE_ARM_GFX_ASM
+DEFINES += -DUSE_ARM_GFX_ASM
+endif
+
+ifdef USE_ARM_COSTUME_ASM
+DEFINES += -DUSE_ARM_COSTUME_ASM
+endif
+
+ifdef USE_ARM_SCALER_ASM
+DEFINES += -DUSE_ARM_SCALER_ASM
+endif
diff --git a/sound/fmopl.h b/sound/fmopl.h
index d0b15368e0..688da4f1ba 100644
--- a/sound/fmopl.h
+++ b/sound/fmopl.h
@@ -94,7 +94,7 @@ private:
// TODO: This is part of a temporary HACK to allow only 1 instance
static bool _hasInstance;
public:
- OPL() { _hasInstance = true; }
+ OPL() { assert(!_hasInstance); _hasInstance = true; }
virtual ~OPL() { _hasInstance = false; }
/**
diff --git a/sound/softsynth/mt32/partial.cpp b/sound/softsynth/mt32/partial.cpp
index 871eff03d2..f016084d8c 100644
--- a/sound/softsynth/mt32/partial.cpp
+++ b/sound/softsynth/mt32/partial.cpp
@@ -36,7 +36,7 @@
// 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)floorf(x))
+#define floorf(x) ((float)floor(x))
#define fabsf(x) ((float)fabs(x))
#endif
diff --git a/sound/softsynth/mt32/synth.cpp b/sound/softsynth/mt32/synth.cpp
index 547b2bb9b3..c8b7abdf67 100644
--- a/sound/softsynth/mt32/synth.cpp
+++ b/sound/softsynth/mt32/synth.cpp
@@ -36,7 +36,7 @@
// 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)floorf(x))
+#define floorf(x) ((float)floor(x))
#define fabsf(x) ((float)fabs(x))
#endif
diff --git a/sound/softsynth/mt32/tables.cpp b/sound/softsynth/mt32/tables.cpp
index 16fc4f71e5..571750ee99 100644
--- a/sound/softsynth/mt32/tables.cpp
+++ b/sound/softsynth/mt32/tables.cpp
@@ -36,7 +36,7 @@
// 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)floorf(x))
+#define floorf(x) ((float)floor(x))
#define fabsf(x) ((float)fabs(x))
#endif
diff --git a/test/common/str.h b/test/common/str.h
index bf0db98b09..f65b078bdc 100644
--- a/test/common/str.h
+++ b/test/common/str.h
@@ -285,4 +285,12 @@ class StringTestSuite : public CxxTest::TestSuite
TS_ASSERT(!Common::matchString("monkey.s99", "monkey.s*1"));
TS_ASSERT(Common::matchString("monkey.s101", "monkey.s*1"));
}
+
+ void test_string_printf() {
+ TS_ASSERT( Common::String::printf("") == "" );
+ TS_ASSERT( Common::String::printf("%s", "test") == "test" );
+ TS_ASSERT( Common::String::printf("%s.s%.02d", "monkey", 1) == "monkey.s01" );
+ TS_ASSERT( Common::String::printf("%s%X", "test", 1234) == "test4D2" );
+ TS_ASSERT( Common::String::printf("Some %s to make this string longer than the default built-in %s %d", "text", "capacity", 123456) == "Some text to make this string longer than the default built-in capacity 123456" );
+ }
};
diff --git a/tools/credits.pl b/tools/credits.pl
index 3b297e961b..2b1b93e87b 100755
--- a/tools/credits.pl
+++ b/tools/credits.pl
@@ -475,14 +475,19 @@ begin_credits("Credits");
begin_section("Engine Teams");
begin_section("SCUMM");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
+ add_person("James Brown", "ender", "(retired)");
+ add_person("Jonathan Gray", "khalek", "(retired)");
+ add_person("Vincent Hamm", "yaz0r", "(retired)");
add_person("Max Horn", "Fingolfin", "");
add_person("Travis Howell", "Kirben", "");
add_person("Pawe&#322; Ko&#322;odziejski", "aquadran", "Codecs, iMUSE, Smush, etc.");
add_person("Gregory Montoir", "cyx", "");
add_person("Eugene Sandulenko", "sev", "FT INSANE, MM NES, MM C64, game detection, Herc/CGA");
+ add_person("Ludvig Strigeus", "ludde", "(retired)");
end_section();
begin_section("HE");
+ add_person("Jonathan Gray", "khalek", "(retired)");
add_person("Travis Howell", "Kirben", "");
add_person("Gregory Montoir", "cyx", "");
add_person("Eugene Sandulenko", "sev", "");
@@ -496,35 +501,45 @@ begin_credits("Credits");
add_person("Walter van Niftrik", "waltervn", "");
add_person("Kari Salminen", "Buddha^", "");
add_person("Eugene Sandulenko", "sev", "");
+ add_person("David Symonds", "dsymonds", "(retired)");
end_section();
begin_section("AGOS");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
add_person("Paul Gilbert", "dreammaster", "");
add_person("Travis Howell", "Kirben", "");
+ add_person("Oliver Kiehl", "olki", "(retired)");
+ add_person("Ludvig Strigeus", "ludde", "(retired)");
end_section();
begin_section("BASS"); # Beneath a Steel Sky
+ add_person("Robert G&ouml;ffringmann", "lavosspawn", "(retired)");
+ add_person("Oliver Kiehl", "olki", "(retired)");
add_person("Joost Peters", "joostp", "");
end_section();
begin_section("Broken Sword 1");
+ add_person("Fabio Battaglia", "Hkz", "PSX version support");
+ add_person("Robert G&ouml;ffringmann", "lavosspawn", "(retired)");
end_section();
begin_section("Broken Sword 2");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
+ add_person("Fabio Battaglia", "Hkz", "PSX version support");
+ add_person("Jonathan Gray", "khalek", "(retired)");
end_section();
begin_section("Cinematique evo 1");
- add_person("Vincent Hamm", "yazoo", "original CinE engine author");
+ add_person("Vincent Hamm", "yaz0r", "(retired)");
add_person("Pawe&#322; Ko&#322;odziejski", "aquadran", "");
add_person("Gregory Montoir", "cyx", "");
+ add_person("Kari Salminen", "Buddha^", "");
add_person("Eugene Sandulenko", "sev", "");
end_section();
begin_section("Cinematique evo 2");
- add_person("Vincent Hamm", "yazoo", "original CruisE engine author");
add_person("Paul Gilbert", "dreammaster", "");
+ add_person("Vincent Hamm", "yaz0r", "(retired)");
end_section();
begin_section("Drascula");
@@ -533,14 +548,15 @@ begin_credits("Credits");
end_section();
begin_section("FOTAQ"); # Flight of the Amazon Queen
+ add_person("David Eriksson", "twogood", "(retired)");
add_person("Gregory Montoir", "cyx", "");
add_person("Joost Peters", "joostp", "");
end_section();
begin_section("Gob");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
+ add_person("Arnaud Boutonn&eacute;", "Strangerke", "");
add_person("Sven Hesse", "DrMcCoy", "");
- add_person("Willem Jan Palenstijn", "wjp", "");
add_person("Eugene Sandulenko", "sev", "");
end_section();
@@ -565,12 +581,12 @@ begin_credits("Credits");
begin_section("M4");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
add_person("Paul Gilbert", "dreammaster", "");
- add_person("Benjamin Haisch", "johndoe", "");
+ add_person("Benjamin Haisch", "john_doe", "");
add_person("Filippos Karapetis", "[md5]", "");
end_section();
begin_section("MADE");
- add_person("Benjamin Haisch", "johndoe", "");
+ add_person("Benjamin Haisch", "john_doe", "");
add_person("Filippos Karapetis", "[md5]", "");
end_section();
@@ -580,7 +596,6 @@ begin_credits("Credits");
begin_section("SAGA");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
- add_person("Sven Hesse", "DrMcCoy", "");
add_person("Filippos Karapetis", "[md5]", "");
add_person("Andrew Kurushin", "ajax16384", "");
add_person("Eugene Sandulenko", "sev", "");
@@ -592,12 +607,14 @@ begin_credits("Credits");
add_person("Max Horn", "Fingolfin", "");
add_person("Filippos Karapetis", "[md5]", "");
add_person("Walter van Niftrik", "waltervn", "");
+ add_person("Willem Jan Palenstijn", "wjp", "");
add_person("Jordi Vilalta Prat", "jvprat", "");
add_person("Lars Skovlund", "lskovlun", "");
end_section();
begin_section("Tinsel");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
+ add_person("Fabio Battaglia", "Hkz", "PSX version support");
add_person("Paul Gilbert", "dreammaster", "");
add_person("Sven Hesse", "DrMcCoy", "");
add_person("Max Horn", "Fingolfin", "");
@@ -642,10 +659,12 @@ begin_credits("Credits");
end_section();
begin_section("PocketPC / WinCE");
+ add_person("Nicolas Bacca", "arisme", "(retired)");
add_person("Kostas Nakos", "Jubanka", "");
end_section();
begin_section("PlayStation 2");
+ add_person("Robert G&ouml;ffringmann", "lavosspawn", "(retired)");
add_person("Max Lingua", "sunmax", "");
end_section();
@@ -676,95 +695,48 @@ begin_credits("Credits");
end_section();
begin_section("GUI");
+ add_person("Vicent Marti", "tanoku", "");
add_person("Eugene Sandulenko", "sev", "");
add_person("Johannes Schickel", "LordHoto", "");
end_section();
begin_section("Miscellaneous");
- add_person("David Corrales-Lopez", "david_corrales", "Filesystem access improvements (GSoC 2007 task)");
- add_person("Jerome Fisher", "KingGuppy", "MT-32 emulator");
- add_person("Jochen Hoenicke", "hoenicke", "Speaker &amp; PCjr sound support, AdLib work");
- add_person("Chris Page", "cp88", "Return to launcher, savestate improvements, leak fixes, ... (GSoC 2008 task)");
+ add_person("David Corrales-Lopez", "david_corrales", "Filesystem access improvements (GSoC 2007 task) (retired)");
+ add_person("Jerome Fisher", "KingGuppy", "MT-32 emulator (retired)");
+ add_person("Benjamin Haisch", "john_doe", "Heavily improved de-/encoder for DXA videos");
+ add_person("Jochen Hoenicke", "hoenicke", "Speaker &amp; PCjr sound support, AdLib work (retired)");
+ add_person("Chris Page", "cp88", "Return to launcher, savestate improvements, leak fixes, ... (GSoC 2008 task) (retired)");
add_person("Robin Watts", "robinwatts", "ARM assembly routines for nice speedups on several ports; improvements to the sound mixer");
end_section();
end_section();
+ begin_section("Website (code)");
+ begin_persons();
+ add_person("Fredrik Wendel", "", "");
+ end_persons();
+ end_section();
+
begin_section("Website (content)");
add_paragraph("All active team members");
end_section();
begin_section("Documentation");
- begin_persons();
+ begin_persons();
add_person("Joachim Eberhard", "joachimeberhard", "Numerous contributions to documentation");
add_person("Matthew Hoops", "clone2727", "Wiki editor");
- end_persons();
- end_section();
-
- begin_section("FreeSCI Contributors");
- begin_persons();
- add_person("Anders Baden Nielsen", "", "PPC testing");
- add_person("Bas Zoetekouw", "", "Man pages, debian package management, CVS maintenance");
- add_person("Carl Muckenhoupt", "", "Sources to the SCI resource viewer tools that started it all");
- add_person("Chris Kehler", "", "Makefile enhancements");
- add_person("Christoph Reichenbach", "", "UN*X code, VM/Graphics/Sound/other infrastructure");
- add_person("Christopher T. Lansdown", "", "Original CVS maintainer, Alpha compatibility fixes");
- add_person("Claudio Matsuoka", "", "CVS snapshots, daily builds, BeOS and cygwin ports");
- add_person("Dark Minister", "", "SCI research (bytecode and parser)");
- add_person("Dmitry Jemerov", "", "Port to the Win32 platform, numerous bugfixes");
- add_person("Emmanuel Jeandel", "", "Bugfixes and bug reports");
- add_person("Francois-R Boyer", "", "MT-32 information and mapping code");
- add_person("George Reid", "", "FreeBSD package management");
- add_person("Hubert Maier", "", "AmigaOS 4 port");
- add_person("Hugues Valois", "", "Game selection menu");
- add_person("Johannes Manhave", "", "Document format translation");
- add_person("Jordi Vilalta", "", "Numerous code and website clean-up patches");
- add_person("Lars Skovlund", "", "Project maintenance, most documentation, bugfixes, SCI1 support");
- add_person("Magnus Reftel", "", "Heap implementation, Python class viewer, bugfixes");
- add_person("Matt Hargett", "", "Clean-ups, bugfixes, Hardcore QA, Win32");
- add_person("Max Horn", "", "SetJump implementation");
- add_person("Paul David Doherty", "", "Game version information");
- add_person("Petr Vyhnak", "", "The DCL-INFLATE algorithm, many Win32 improvements");
- add_person("Rainer Canavan", "", "IRIX MIDI driver and bug fixes");
- add_person("Rainer De Temple", "", "SCI research");
- add_person("Ravi I.", "", "SCI0 sound resource specification");
- add_person("Ruediger Hanke", "", "Port to the MorphOS platform");
- add_person("Rune Orsval", "", "Configuration file editor");
- add_person("Rickard Lind", "", "MT32->GM MIDI mapping magic, sound research");
- add_person("Rink Springer", "", "Port to the DOS platform, several bug fixes");
- add_person("Robey Pointer", "", "Bug tracking system hosting");
- add_person("Sergey Lapin", "", "Port of Carl's type 2 decompression code");
- add_person("Solomon Peachy", "", "SDL ports and much of the sound subsystem");
- add_person("Vyacheslav Dikonov", "", "Config script improvements");
- add_person("Walter van Niftrik", "", "Ports to the Dreamcast and GP32 platforms");
- add_person("Xiaojun Chen", "", "");
- add_person("Sean Terrell", "", "");
- end_persons();
- add_paragraph("Special thanks to Prof. Dr. Gary Nutt ".
- "for allowing the FreeSCI VM extension as a ".
- "course project in his Advanced OS course");
- add_paragraph("Special thanks to Bob Heitman and Corey Cole for their support of FreeSCI");
+ end_persons();
end_section();
begin_section("Retired Team Members");
begin_persons();
- add_person("Tore Anderson", "tore", "Former Debian GNU/Linux maintainer");
- add_person("Nicolas Bacca", "arisme", "Former WinCE porter");
- add_person("Ralph Brorsen", "painelf", "Help with GUI implementation");
- add_person("Jamieson Christian", "jamieson630", "iMUSE, MIDI, all things musical");
- add_person("David Eriksson", "twogood", "Engines: FOTAQ");
- add_person("Hans-J&ouml;rg Frieden", "", "Former AmigaOS 4 packager");
- add_person("Robert G&ouml;ffringmann", "lavosspawn", "Original PS2 porter; Engines: BASS, BS1");
- add_person("Jonathan Gray", "khalek", "Engines: SCUMM, HE, BS2");
- add_person("R&uuml;diger Hanke", "", "Port: MorphOS");
- add_person("Felix Jakschitsch", "yot", "Zak256 reverse engineering");
- add_person("Oliver Kiehl", "olki", "Engines: AGOS, BASS");
- add_person("Mutwin Kraus", "mutle", "Original MacOS porter");
- add_person("Peter Moraliyski", "ph0x", "Port: GP32");
- add_person("Juha Niemim&auml;ki", "", "Former AmigaOS 4 packager");
- add_person("Jeremy Newman", "laxdragon", "Former webmaster");
- add_person("Lionel Ulmer", "bbrox", "Port: X11");
- add_person("Won Star", "wonst719", "Former GP32 porter");
- add_person("David Symonds", "dsymonds", "Engines: AGI");
+ add_person("Ralph Brorsen", "painelf", "Help with GUI implementation");
+ add_person("Jamieson Christian", "jamieson630", "iMUSE, MIDI, all things musical");
+ add_person("Felix Jakschitsch", "yot", "Zak256 reverse engineering");
+ add_person("Mutwin Kraus", "mutle", "Original MacOS porter");
+ add_person("Peter Moraliyski", "ph0x", "Port: GP32");
+ add_person("Jeremy Newman", "laxdragon", "Former webmaster");
+ add_person("Lionel Ulmer", "bbrox", "Port: X11");
+ add_person("Won Star", "wonst719", "Former GP32 porter");
end_persons();
end_section();
end_section();
@@ -774,7 +746,9 @@ begin_credits("Credits");
begin_section("Packages");
begin_section("AmigaOS 4");
+ add_person("Hans-J&ouml;rg Frieden", "", "(retired)");
add_person("Hubert Maier", "Raziel_AOne", "");
+ add_person("Juha Niemim&auml;ki", "", "(retired)");
end_section();
begin_section("Atari/FreeMiNT");
@@ -787,6 +761,7 @@ begin_credits("Credits");
end_section();
begin_section("Debian GNU/Linux");
+ add_person("Tore Anderson", "tore", "(retired)");
add_person("David Weinehall", "tao", "");
end_section();
@@ -805,6 +780,7 @@ begin_credits("Credits");
begin_section("MorphOS");
add_person("Fabien Coeurjoly", "fab1", "");
+ add_person("R&uuml;diger Hanke", "", "(retired)");
end_section();
begin_section("OS/2");
@@ -850,7 +826,6 @@ begin_credits("Credits");
add_person("Thierry Crozat", "criezy", "Support for Broken Sword 1 Macintosh version");
add_person("Martin Doucha", "next_ghost", "CinE engine objectification");
add_person("Thomas Fach-Pedersen", "madmoose", "ProTracker module player");
- add_person("Benjamin Haisch", "john_doe", "Heavily improved de-/encoder for DXA videos");
add_person("Janne Huttunen", "", "V3 actor mask support, Dig/FT SMUSH audio");
add_person("Kov&aacute;cs Endre J&aacute;nos", "", "Several fixes for Simon1");
add_person("Jeroen Janssen", "japj", "Numerous readability and bugfix patches");
@@ -863,6 +838,7 @@ begin_credits("Credits");
add_person("Nicolas Noble", "pixels", "Config file and ALSA support");
add_person("Tim Phillips", "realmz", "Initial MI1 CD music support");
add_person("", "Quietust", "Sound support for Amiga SCUMM V2/V3 games, MM NES support");
+ add_person("", "segra", "Improved support for Apple II/C64 versions of MM");
add_person("Andreas R&ouml;ver", "", "Broken Sword 1/2 MPEG2 cutscene support");
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");
@@ -870,6 +846,51 @@ begin_credits("Credits");
end_persons();
end_section();
+ begin_section("FreeSCI Contributors");
+ begin_persons();
+ add_person("Anders Baden Nielsen", "", "PPC testing");
+ add_person("Bas Zoetekouw", "", "Man pages, debian package management, CVS maintenance");
+ add_person("Carl Muckenhoupt", "", "Sources to the SCI resource viewer tools that started it all");
+ add_person("Chris Kehler", "", "Makefile enhancements");
+ add_person("Christoph Reichenbach", "", "UN*X code, VM/Graphics/Sound/other infrastructure");
+ add_person("Christopher T. Lansdown", "", "Original CVS maintainer, Alpha compatibility fixes");
+ add_person("Claudio Matsuoka", "", "CVS snapshots, daily builds, BeOS and cygwin ports");
+ add_person("Dark Minister", "", "SCI research (bytecode and parser)");
+ add_person("Dmitry Jemerov", "", "Port to the Win32 platform, numerous bugfixes");
+ add_person("Emmanuel Jeandel", "", "Bugfixes and bug reports");
+ add_person("Francois-R Boyer", "", "MT-32 information and mapping code");
+ add_person("George Reid", "", "FreeBSD package management");
+ add_person("Hubert Maier", "", "AmigaOS 4 port");
+ add_person("Hugues Valois", "", "Game selection menu");
+ add_person("Johannes Manhave", "", "Document format translation");
+ add_person("Jordi Vilalta", "", "Numerous code and website clean-up patches");
+ add_person("Lars Skovlund", "", "Project maintenance, most documentation, bugfixes, SCI1 support");
+ add_person("Magnus Reftel", "", "Heap implementation, Python class viewer, bugfixes");
+ add_person("Matt Hargett", "", "Clean-ups, bugfixes, Hardcore QA, Win32");
+ add_person("Max Horn", "", "SetJump implementation");
+ add_person("Paul David Doherty", "", "Game version information");
+ add_person("Petr Vyhnak", "", "The DCL-INFLATE algorithm, many Win32 improvements");
+ add_person("Rainer Canavan", "", "IRIX MIDI driver and bug fixes");
+ add_person("Rainer De Temple", "", "SCI research");
+ add_person("Ravi I.", "", "SCI0 sound resource specification");
+ add_person("Ruediger Hanke", "", "Port to the MorphOS platform");
+ add_person("Rune Orsval", "", "Configuration file editor");
+ add_person("Rickard Lind", "", "MT32->GM MIDI mapping magic, sound research");
+ add_person("Rink Springer", "", "Port to the DOS platform, several bug fixes");
+ add_person("Robey Pointer", "", "Bug tracking system hosting");
+ add_person("Sergey Lapin", "", "Port of Carl's type 2 decompression code");
+ add_person("Solomon Peachy", "", "SDL ports and much of the sound subsystem");
+ add_person("Vyacheslav Dikonov", "", "Config script improvements");
+ add_person("Walter van Niftrik", "", "Ports to the Dreamcast and GP32 platforms");
+ add_person("Xiaojun Chen", "", "");
+ add_person("Sean Terrell", "", "");
+ end_persons();
+ add_paragraph("Special thanks to Prof. Dr. Gary Nutt ".
+ "for allowing the FreeSCI VM extension as a ".
+ "course project in his Advanced OS course.");
+ add_paragraph("Special thanks to Bob Heitman and Corey Cole for their support of FreeSCI.");
+ end_section();
+
add_paragraph("And to all the contributors, users, and beta testers we've missed. Thanks!");
end_section();
diff --git a/tools/module.mk b/tools/module.mk
index f20273f7bc..9ad972f477 100644
--- a/tools/module.mk
+++ b/tools/module.mk
@@ -54,10 +54,10 @@ tools/make-scumm-fontdata$(EXEEXT): $(srcdir)/tools/make-scumm-fontdata.c
credits:
$(srcdir)/tools/credits.pl --text > AUTHORS
- $(srcdir)/tools/credits.pl --rtf > Credits.rtf
+# $(srcdir)/tools/credits.pl --rtf > Credits.rtf
$(srcdir)/tools/credits.pl --cpp > gui/credits.h
$(srcdir)/tools/credits.pl --xml-website > ../../web/trunk/data/credits.xml
- $(srcdir)/tools/credits.pl --xml-docbook > ../../docs/trunk/docbook/credits.xml
+# $(srcdir)/tools/credits.pl --xml-docbook > ../../docs/trunk/docbook/credits.xml
md5scumm: tools/md5table$(EXEEXT)
tools/md5table$(EXEEXT) --c++ < $(srcdir)/tools/scumm-md5.txt > engines/scumm/scumm-md5.h
diff --git a/tools/scumm-md5.txt b/tools/scumm-md5.txt
index 56b1334b3e..2b937136ad 100644
--- a/tools/scumm-md5.txt
+++ b/tools/scumm-md5.txt
@@ -239,7 +239,7 @@ pass Passport to Adventure
zak Misc FM-TOWNS demos
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
- 3938ee1aa4433fca9d9308c9891172b1 -1 en FM-TOWNS FM-TOWNS Demo indy/zak (non-interactive) khalek
+ 3938ee1aa4433fca9d9308c9891172b1 7520 en FM-TOWNS FM-TOWNS Demo indy/zak (non-interactive) khalek
monkey2 Monkey Island 2: LeChuck's Revenge
132bff65e6367c09cc69318ce1b59333 11155 en Amiga - - v1.0 4/8/92 Fingolfin
@@ -262,79 +262,79 @@ monkey2 Monkey Island 2: LeChuck's Revenge
387a544b8b10b26912d8413bab63a853 -1 en DOS - Demo non-interactive khalek
atlantis Indiana Jones and the Fate of Atlantis
- 3a03dab514e4038df192d8a8de469788 -1 en Amiga - Floppy - dhewg
- 20da6fce37805423966aaa8f3c2426aa -1 fr Amiga - Floppy - Joachim Eberhard
- 4f267a901719623de7dde83e47d5b474 -1 de Amiga - Floppy - ghoostkilla
- e534d29afb3c6e0ee9dc3d53c5956714 -1 de Amiga - Floppy alt? Tobias Fleischer
- 5798972220cd458be2626d54c80f71d7 -1 it Amiga - Floppy - Andrea Petrucci
- 15f588e887e857e8c56fe6ade4956168 -1 es Amiga - Floppy - VooD
- c63ee46143ba65f9ce14cf539ca51bd7 -1 en DOS - Floppy - Andrea Petrucci
- edfdb24a499d92c59f824c52987c0eec -1 fr DOS - Floppy - Nicolas Sauz&egrave;de, Andrea Petrucci
- 1fbebd7b2b692df5297870447a80cfed 12030 de DOS - Floppy - Fingolfin
- 8f3758ff98c9c5d78e5d635222cad026 -1 it DOS - Floppy - Andrea Petrucci
- 9bd2a8f72613e715c199246dd511e10f -1 es DOS - Floppy - abnog, Andrea Petrucci
- 06b187468113f9ae5a400b148a847fac 12075 en Mac - Floppy six data files Lars N sbye Christensen
- d6dd0646404768a63e963891a96daadd 12035 en Mac - Floppy two data files Fingolfin
-
- 182344899c2e2998fca0bebcd82aa81a 12035 en DOS CD CD - Fingolfin
- 1a6e5ae2777a6a33f06ffc0226210934 -1 en Mac CD CD - Scott Summers
- 2d9d46f23cb07bbc90b8ad464d3e4ff8 -1 en Mac CD CD Mac bundle Joachim Eberhard
- 8e9417564f33790815445b2136efa667 11915 jp Mac CD CD - Petr Maruska
-
- c7be10f775404fd9785a8b92a06d240c -1 en FM-TOWNS CD - - dhewg, Andrea Petrucci
- 4d34042713958b971cb139fba4658586 -1 jp FM-TOWNS CD - - Andrea Petrucci
-
- 035deab53b47bc43abc763560d0f8d4b -1 en DOS - Demo -
- 98744fe66ff730e8c2b3b1f58803ab0b -1 en DOS - Demo - Simon Krumrein, sev
- 99b6f822b0b2612415407865438697d6 -1 en DOS CD Demo non-interactive
- 28d24a33448fab6795850bc9f159a4a2 11170 jp FM-TOWNS CD Demo non-interactive khalek, Fingolfin
+ 3a03dab514e4038df192d8a8de469788 -1 en Amiga Floppy Floppy - dhewg
+ 20da6fce37805423966aaa8f3c2426aa -1 fr Amiga Floppy Floppy - Joachim Eberhard
+ 4f267a901719623de7dde83e47d5b474 -1 de Amiga Floppy Floppy - ghoostkilla
+ e534d29afb3c6e0ee9dc3d53c5956714 -1 de Amiga Floppy Floppy alt? Tobias Fleischer
+ 5798972220cd458be2626d54c80f71d7 -1 it Amiga Floppy Floppy - Andrea Petrucci
+ 15f588e887e857e8c56fe6ade4956168 -1 es Amiga Floppy Floppy - VooD
+ c63ee46143ba65f9ce14cf539ca51bd7 -1 en DOS Floppy Floppy - Andrea Petrucci
+ edfdb24a499d92c59f824c52987c0eec -1 fr DOS Floppy Floppy - Nicolas Sauz&egrave;de, Andrea Petrucci
+ 1fbebd7b2b692df5297870447a80cfed 12030 de DOS Floppy Floppy - Fingolfin
+ 8f3758ff98c9c5d78e5d635222cad026 -1 it DOS Floppy Floppy - Andrea Petrucci
+ 9bd2a8f72613e715c199246dd511e10f -1 es DOS Floppy Floppy - abnog, Andrea Petrucci
+ 06b187468113f9ae5a400b148a847fac 12075 en Mac Floppy Floppy six data files Lars N sbye Christensen
+ d6dd0646404768a63e963891a96daadd 12035 en Mac Floppy Floppy two data files Fingolfin
+
+ 182344899c2e2998fca0bebcd82aa81a 12035 en DOS - CD - Fingolfin
+ 1a6e5ae2777a6a33f06ffc0226210934 -1 en Mac - CD - Scott Summers
+ 2d9d46f23cb07bbc90b8ad464d3e4ff8 -1 en Mac - CD Mac bundle Joachim Eberhard
+ 8e9417564f33790815445b2136efa667 11915 jp Mac - CD - Petr Maruska
+
+ c7be10f775404fd9785a8b92a06d240c -1 en FM-TOWNS - - - dhewg, Andrea Petrucci
+ 4d34042713958b971cb139fba4658586 -1 jp FM-TOWNS - - - Andrea Petrucci
+
+ 035deab53b47bc43abc763560d0f8d4b -1 en DOS Floppy Demo -
+ 98744fe66ff730e8c2b3b1f58803ab0b -1 en DOS Floppy Demo - Simon Krumrein, sev
+ 99b6f822b0b2612415407865438697d6 -1 en DOS - Demo non-interactive
+ 28d24a33448fab6795850bc9f159a4a2 11170 jp FM-TOWNS - Demo non-interactive khalek, Fingolfin
tentacle Day of the Tentacle
- acad97ab1c6fc2a5b2d98abf6db4a190 -1 en All? - Floppy Version A ?
- 2723fea3dae0cb47768c424b145ae0e7 7932 en DOS - Floppy Version B ? Andrej Sinicyn, Andrea Petrucci, Fingolfin
- 92b078d9d6d9d751da9c26b8b3075779 -1 fr DOS - Floppy - Nicolas Sauz&egrave;de, Andrea Petrucci
- 94aaedbb8f26d71ed3ad6dd34490e29e -1 fr DOS - Floppy alt? Nicolas Joly
- 57b0d89af79befe1cabce3bece869e7f -1 de DOS - Floppy - Andrej Sinicyn, Andrea Petrucci
- 50fcdc982a25063b78ad46bf389b8e8d -1 it DOS - Floppy - Andrea Petrucci
- ae94f110a14ce71fc515d5b648827a8f -1 es DOS - Floppy - abnog, Andrea Petrucci
-
- 4167a92a1d46baa4f4127d918d561f88 7932 en All? CD CD - Fingolfin
- 8aa05d3cdb0e795436043f0546af2da2 -1 fr All? CD CD? - Andrea Petrucci
- 6e959d65358eedf9b68b81e304b97fa4 7932 de All? CD CD - Fingolfin
- 4fbbe9f64b8bc547503a379a301183ce -1 it All? CD CD - Andrea Petrucci
- 883af4b0af4f77a92f1dcf1d0a283140 -1 es All? CD CD - Andrea Petrucci
- cc04a076779379524ed4d9c5ee3c6fb1 282467632 en Mac CD CD Mac bundle Fingolfin, Joachim Eberhard
- ede149fda3edfc1dbd7347e0737cb583 -1 fr Mac CD CD Mac bundle ThierryFR
- f73883f13b5a302749a5bad31d909780 -1 de Mac CD CD Mac bundle morrissey
-
- c83079157ec765a28de445aec9768d60 7477 en All CD Demo - Fingolfin
- 17fa250eb72dae2dad511ba79c0b6b0a -1 fr DOS CD Demo - cyx
- ac1642b6edfb8521ca03760126f1c250 -1 de DOS CD Demo - Simon Krumrein, sev
- 2a41b53cf1a90b6e6f26c10cc6041084 2439158 en Mac CD Demo Mac bundle Fingolfin
+ acad97ab1c6fc2a5b2d98abf6db4a190 -1 en All? Floppy Floppy Version A ?
+ 2723fea3dae0cb47768c424b145ae0e7 7932 en DOS Floppy Floppy Version B ? Andrej Sinicyn, Andrea Petrucci, Fingolfin
+ 92b078d9d6d9d751da9c26b8b3075779 -1 fr DOS Floppy Floppy - Nicolas Sauz&egrave;de, Andrea Petrucci
+ 94aaedbb8f26d71ed3ad6dd34490e29e -1 fr DOS Floppy Floppy alt? Nicolas Joly
+ 57b0d89af79befe1cabce3bece869e7f -1 de DOS Floppy Floppy - Andrej Sinicyn, Andrea Petrucci
+ 50fcdc982a25063b78ad46bf389b8e8d -1 it DOS Floppy Floppy - Andrea Petrucci
+ ae94f110a14ce71fc515d5b648827a8f -1 es DOS Floppy Floppy - abnog, Andrea Petrucci
+
+ 4167a92a1d46baa4f4127d918d561f88 7932 en All? - CD - Fingolfin
+ 8aa05d3cdb0e795436043f0546af2da2 -1 fr All? - CD? - Andrea Petrucci
+ 6e959d65358eedf9b68b81e304b97fa4 7932 de All? - CD - Fingolfin
+ 4fbbe9f64b8bc547503a379a301183ce -1 it All? - CD - Andrea Petrucci
+ 883af4b0af4f77a92f1dcf1d0a283140 -1 es All? - CD - Andrea Petrucci
+ cc04a076779379524ed4d9c5ee3c6fb1 282467632 en Mac - CD Mac bundle Fingolfin, Joachim Eberhard
+ ede149fda3edfc1dbd7347e0737cb583 -1 fr Mac - CD Mac bundle ThierryFR
+ f73883f13b5a302749a5bad31d909780 -1 de Mac - CD Mac bundle morrissey
+
+ c83079157ec765a28de445aec9768d60 7477 en All - Demo - Fingolfin
+ 17fa250eb72dae2dad511ba79c0b6b0a -1 fr DOS - Demo - cyx
+ ac1642b6edfb8521ca03760126f1c250 -1 de DOS - Demo - Simon Krumrein, sev
+ 2a41b53cf1a90b6e6f26c10cc6041084 2439158 en Mac - Demo Mac bundle Fingolfin
samnmax Sam &amp; Max Hit the Road
- 3b301b7892f883ce42ab4be6a274fea6 -1 en DOS - Floppy - Andrea Petrucci
- a3036878840720fbefa41e6965fa4a0a -1 en DOS - Floppy alt? Andrea Petrucci
- ef347474f3c7be3b29584eaa133cca05 -1 fr DOS - Floppy - Nicolas Sauz&egrave;de, Andrea Petrucci
- f27b1ba0eadaf2a6617b2b58192d1dbf -1 de DOS - Floppy - dhewg, Andrea Petrucci
- b289a2a8cbedbf45786e0b4ad2f510f1 -1 it DOS - Floppy - Andrea Petrucci
- fc53ce0e5f6562b1c1e1b4b8203acafb -1 es DOS - Floppy - Andrea Petrucci
-
- d917f311a448e3cc7239c31bddb00dd2 9080 en All? CD CD - Fingolfin
- 7edd665bbede7ea8b7233f8e650be6f8 -1 fr All? CD CD - Andrea Petrucci
- 0fb73eddfcf584c02ba097984df131ba 9080 de All? CD CD - Fingolfin
- 0f6f2e716ba896a44e5059bba1de7ca9 -1 it All? CD CD - Andrea Petrucci
- 4ba7fb331296c283e73d8f5b2096e551 -1 es All? CD CD - Andrea Petrucci
- d43352a805d78b5f4936c6d7779bf575 -1 ru DOS CD CD -
- 166553538ff320c69edafeee29525419 -1 en Mac CD CD Mac bundle Joachim Eberhard
- 3a5d13675e9a23aedac0bac7730f0ac1 -1 fr Mac CD CD Mac bundle ThierryFR
-
- c3196c5349e53e387aaff1533d95e53a -1 en DOS - Demo -
- 0e4c5d54a0ad4b26132e78b5ea76642a 6485 en DOS - Demo WIP Fingolfin
- d9d0dd93d16ab4dec55cabc2b86bbd17 6478 en DOS CD Demo non-interactive Fingolfin
- cc8ba2b0df2f9c450bcf055fe2711979 7485 de DOS - Demo - Simon Krumrein, sev, Fingolfin
- 0425954a9db5c340861672892c3e678d -1 en All CD Demo - Kirben
- 6dead580b0ff14d5f7b33b4219f04159 16556335 en Mac CD Demo Mac bundle Fingolfin
+ 3b301b7892f883ce42ab4be6a274fea6 -1 en DOS Floppy Floppy - Andrea Petrucci
+ a3036878840720fbefa41e6965fa4a0a -1 en DOS Floppy Floppy alt? Andrea Petrucci
+ ef347474f3c7be3b29584eaa133cca05 -1 fr DOS Floppy Floppy - Nicolas Sauz&egrave;de, Andrea Petrucci
+ f27b1ba0eadaf2a6617b2b58192d1dbf -1 de DOS Floppy Floppy - dhewg, Andrea Petrucci
+ b289a2a8cbedbf45786e0b4ad2f510f1 -1 it DOS Floppy Floppy - Andrea Petrucci
+ fc53ce0e5f6562b1c1e1b4b8203acafb -1 es DOS Floppy Floppy - Andrea Petrucci
+
+ d917f311a448e3cc7239c31bddb00dd2 9080 en All? - CD - Fingolfin
+ 7edd665bbede7ea8b7233f8e650be6f8 -1 fr All? - CD - Andrea Petrucci
+ 0fb73eddfcf584c02ba097984df131ba 9080 de All? - CD - Fingolfin
+ 0f6f2e716ba896a44e5059bba1de7ca9 -1 it All? - CD - Andrea Petrucci
+ 4ba7fb331296c283e73d8f5b2096e551 -1 es All? - CD - Andrea Petrucci
+ d43352a805d78b5f4936c6d7779bf575 -1 ru DOS - CD -
+ 166553538ff320c69edafeee29525419 -1 en Mac - CD Mac bundle Joachim Eberhard
+ 3a5d13675e9a23aedac0bac7730f0ac1 -1 fr Mac - CD Mac bundle ThierryFR
+
+ c3196c5349e53e387aaff1533d95e53a -1 en DOS Floppy Demo -
+ 0e4c5d54a0ad4b26132e78b5ea76642a 6485 en DOS Floppy Demo WIP Fingolfin
+ d9d0dd93d16ab4dec55cabc2b86bbd17 6478 en DOS - Demo non-interactive Fingolfin
+ cc8ba2b0df2f9c450bcf055fe2711979 7485 de DOS Floppy Demo - Simon Krumrein, sev, Fingolfin
+ 0425954a9db5c340861672892c3e678d -1 en All - Demo - Kirben
+ 6dead580b0ff14d5f7b33b4219f04159 16556335 en Mac - Demo Mac bundle Fingolfin
ft Full Throttle
41958e24d03181ff9a381a66d048a581 -1 br All? - - - Danilo E.S.
@@ -405,7 +405,7 @@ Soccer2004 Backyard Soccer 2004
c4ffae9fac495475d6bc3343ccc8faf9 -1 en All - - - Kirben, sev
brstorm Bear Stormin'
- 07a1eefd8ca95d77310311446c0f53d0 5433 en All - Demo - sev
+ 07a1eefd8ca95d77310311446c0f53d0 5433 en All - - - sev
thinker1 Big Thinkers First Grade
5c21fc49aee8f46e58fef21579e614a1 -1 us All - - - Kirben