aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--NEWS17
-rw-r--r--README4
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp4
-rw-r--r--backends/graphics/opengl/pipelines/shader.cpp4
-rw-r--r--backends/graphics/opengl/shader.cpp5
-rw-r--r--backends/graphics/opengl/texture.cpp1
-rw-r--r--backends/platform/dingux/README.GCW09
-rw-r--r--backends/platform/dingux/dingux.mk6
-rwxr-xr-xconfig.guess143
-rwxr-xr-xconfig.sub38
-rwxr-xr-xdevtools/create_classicmacfonts.sh (renamed from devtools/create_wage/create_wage.sh)6
-rw-r--r--devtools/scumm-md5.txt2
-rw-r--r--doc/de/Neues23
-rw-r--r--engines/agi/agi.cpp8
-rw-r--r--engines/agos/detection_tables.h25
-rw-r--r--engines/cge2/vga13h.cpp5
-rw-r--r--engines/cruise/dataLoader.cpp11
-rw-r--r--engines/drascula/actors.cpp20
-rw-r--r--engines/drascula/animation.cpp4
-rw-r--r--engines/drascula/drascula.cpp16
-rw-r--r--engines/drascula/graphics.cpp6
-rw-r--r--engines/drascula/interface.cpp9
-rw-r--r--engines/drascula/objects.cpp2
-rw-r--r--engines/drascula/rooms.cpp2
-rw-r--r--engines/drascula/sound.cpp25
-rw-r--r--engines/drascula/talk.cpp10
-rw-r--r--engines/fullpipe/fullpipe.cpp4
-rw-r--r--engines/fullpipe/fullpipe.h8
-rw-r--r--engines/fullpipe/sound.cpp22
-rw-r--r--engines/fullpipe/sound.h8
-rw-r--r--engines/fullpipe/statics.cpp3
-rw-r--r--engines/lastexpress/sound/entry.cpp2
-rw-r--r--engines/made/database.cpp1
-rw-r--r--engines/made/made.cpp15
-rw-r--r--engines/made/pmvplayer.cpp5
-rw-r--r--engines/made/redreader.cpp2
-rw-r--r--engines/made/resource.cpp4
-rw-r--r--engines/made/screen.cpp2
-rw-r--r--engines/made/sound.cpp5
-rw-r--r--engines/mads/mads.cpp1
-rw-r--r--engines/mads/menu_views.h8
-rw-r--r--engines/mohawk/myst.cpp3
-rw-r--r--engines/mortevielle/mortevielle.cpp1
-rw-r--r--engines/parallaction/objects.cpp2
-rw-r--r--engines/parallaction/parallaction.cpp4
-rw-r--r--engines/parallaction/parallaction_br.cpp2
-rw-r--r--engines/saga/isomap.cpp17
-rw-r--r--engines/saga/puzzle.cpp5
-rw-r--r--engines/saga/saveload.cpp2
-rw-r--r--engines/sci/detection_tables.h10
-rw-r--r--engines/scumm/detection_tables.h2
-rw-r--r--engines/scumm/he/intern_he.h7
-rw-r--r--engines/scumm/he/logic/moonbase.cpp52
-rw-r--r--engines/scumm/he/logic/moonbase_logic.cpp231
-rw-r--r--engines/scumm/he/moonbase/moonbase.cpp154
-rw-r--r--engines/scumm/he/moonbase/moonbase.h95
-rw-r--r--engines/scumm/he/moonbase/moonbase_fow.cpp435
-rw-r--r--engines/scumm/he/script_v100he.cpp39
-rw-r--r--engines/scumm/he/script_v90he.cpp32
-rw-r--r--engines/scumm/he/sound_he.cpp4
-rw-r--r--engines/scumm/he/sprite_he.cpp14
-rw-r--r--engines/scumm/he/sprite_he.h2
-rw-r--r--engines/scumm/he/wiz_he.cpp308
-rw-r--r--engines/scumm/he/wiz_he.h86
-rw-r--r--engines/scumm/module.mk6
-rw-r--r--engines/scumm/scumm-md5.h4
-rw-r--r--engines/scumm/scumm.cpp9
-rw-r--r--engines/sherlock/tattoo/tattoo_fixed_text.h2
-rw-r--r--engines/sherlock/tattoo/tattoo_journal.cpp46
-rw-r--r--engines/sherlock/tattoo/tattoo_people.h3
-rw-r--r--engines/sky/control.cpp30
-rw-r--r--engines/sky/control.h2
-rw-r--r--engines/sky/skydefs.h1
-rw-r--r--engines/sword2/screen.cpp4
-rw-r--r--engines/sword25/gfx/image/vectorimage.cpp1
-rw-r--r--engines/sword25/gfx/renderobject.cpp29
-rw-r--r--engines/teenagent/music.cpp4
-rw-r--r--engines/teenagent/music.h1
-rw-r--r--engines/teenagent/objects.h4
-rw-r--r--engines/teenagent/scene.cpp27
-rw-r--r--engines/teenagent/scene.h4
-rw-r--r--engines/teenagent/teenagent.cpp7
-rw-r--r--engines/tinsel/dialogs.cpp16
-rw-r--r--engines/toltecs/movie.cpp2
-rw-r--r--engines/toltecs/resource.cpp1
-rw-r--r--engines/toltecs/sprite.cpp3
-rw-r--r--engines/tony/gfxcore.cpp14
-rw-r--r--engines/tony/mpal/loadmpc.cpp2
-rw-r--r--engines/tony/mpal/mpal.cpp41
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp2
-rw-r--r--engines/wage/debugger.cpp2
-rw-r--r--engines/wage/design.cpp12
-rw-r--r--engines/wage/design.h3
-rw-r--r--engines/wage/dialog.cpp13
-rw-r--r--engines/wage/entities.cpp23
-rw-r--r--engines/wage/entities.h2
-rw-r--r--engines/wage/gui-console.cpp163
-rw-r--r--engines/wage/gui.cpp660
-rw-r--r--engines/wage/gui.h60
-rw-r--r--engines/wage/macmenu.cpp (renamed from engines/wage/menu.cpp)356
-rw-r--r--engines/wage/macmenu.h (renamed from engines/wage/menu.h)60
-rw-r--r--engines/wage/macwindow.cpp179
-rw-r--r--engines/wage/macwindow.h83
-rw-r--r--engines/wage/macwindowmanager.cpp298
-rw-r--r--engines/wage/macwindowmanager.h72
-rw-r--r--engines/wage/module.mk2
-rw-r--r--engines/wage/wage.cpp25
-rw-r--r--engines/wage/wage.h10
-rw-r--r--engines/wage/world.cpp12
-rw-r--r--engines/wage/world.h4
-rw-r--r--engines/wintermute/base/base_engine.cpp2
-rw-r--r--engines/wintermute/base/sound/base_sound_manager.cpp15
-rw-r--r--gui/Tooltip.h3
-rw-r--r--gui/debugger.cpp11
-rw-r--r--gui/dialog.cpp2
-rw-r--r--gui/dialog.h2
-rw-r--r--gui/gui-manager.cpp40
-rw-r--r--gui/gui-manager.h8
-rw-r--r--gui/predictivedialog.cpp16
-rw-r--r--gui/predictivedialog.h1
-rw-r--r--gui/widget.cpp27
-rw-r--r--gui/widget.h7
-rw-r--r--gui/widgets/popup.cpp2
-rw-r--r--po/de_DE.po8
-rw-r--r--[-rwxr-xr-x]po/hu_HU.po0
126 files changed, 3047 insertions, 1404 deletions
diff --git a/.gitignore b/.gitignore
index 3e80289a16..2ad104214e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -166,6 +166,7 @@ ipch/
*.vcxproj*
*.bat
*.tss
+*.VC.db
#Ignore default Visual Studio build folders
[Dd]ebug/
diff --git a/NEWS b/NEWS
index 3bbea89785..adba723022 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ For a more comprehensive changelog of the latest experimental code, see:
General:
- Removed TESTING flag from several supported games.
- Added Chinese Pinyin translation.
+ - Fixed cursor stuttering in the launcher that occured on some systems.
BBVS:
- Fixed game restart.
@@ -27,10 +28,23 @@ For a more comprehensive changelog of the latest experimental code, see:
- Fixed loading savegames in the Pendulum scene.
- Fixed wrong background for inventory items during chapter 6 in the
Spanish version.
+ - Fixed animations speed (they were running two times slower than in the
+ original engine).
+ - Fixed noise at start and/or end of speech. This was most noticeable
+ with the Spanish speech.
+ - Fixed delay when interacting with the verb menu and the inventory.
+ - Fixed possibility to pick up the axe in the castle multiple times.
Gob:
- Fixed lock up for some games during sound initialization.
+ KYRA:
+ - Fixed potential crash when using swamp snake potion on the rat in Hand
+ of Fate. (NOTE: This fix was included in version 1.8.0, but it was not
+ added to the NEWS file).
+ - Fixed missing voice reactions when hitting enemies in CD version of
+ Lands of Lore.
+
Lab:
- Fixed lock-up during ending sequence.
- Improved internal game controls.
@@ -70,6 +84,9 @@ For a more comprehensive changelog of the latest experimental code, see:
not running and allows starting those games.
- Enabled Sparkle application updater.
+ GCW0 port:
+ - Improved support for built-in ScummVM documentation.
+
1.8.0 (2016-03-04)
New Games:
- Added support for Rex Nebular and the Cosmic Gender Bender.
diff --git a/README b/README
index 3d181695c6..d734e28696 100644
--- a/README
+++ b/README
@@ -1742,8 +1742,8 @@ The platforms that currently have a different default directory are:
$HOME/Documents/ScummVM Savegames/
Other unices:
- We follow the XDG Base Directory Specification. This means our
- configuration can be found in:
+ We follow the XDG Base Directory Specification. This means by default
+ saved games can be found in:
$XDG_DATA_HOME/scummvm/saves/
If XDG_DATA_HOME is not defined or empty, ~/.local/share will be used
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
index 685ee99e6f..d536429f4e 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
@@ -1043,12 +1043,12 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
if (value & 0x10) {
_timers[0].smpTillCb = _timers[0].smpPerCb;
- _timers[0].smpTillCbRem = _timers[0].smpTillCbRem;
+ _timers[0].smpTillCbRem = _timers[0].smpPerCbRem;
}
if (value & 0x20) {
_timers[1].smpTillCb = _timers[1].smpPerCb;
- _timers[1].smpTillCbRem = _timers[1].smpTillCbRem;
+ _timers[1].smpTillCbRem = _timers[1].smpPerCbRem;
}
} else if (l == 2) {
// LFO
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
index 8e38458f73..a2dabb7c22 100644
--- a/backends/graphics/opengl/pipelines/shader.cpp
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -56,6 +56,8 @@ void ShaderPipeline::activateInternal() {
}
_activeShader->activate();
+
+ GL_CALL(glVertexAttribPointer(_colorAttribLocation, 4, GL_FLOAT, GL_FALSE, 0, _colorAttributes));
}
void ShaderPipeline::deactivateInternal() {
@@ -74,8 +76,6 @@ void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
*dst++ = b;
*dst++ = a;
}
-
- GL_CALL(glVertexAttribPointer(_colorAttribLocation, 4, GL_FLOAT, GL_FALSE, 0, _colorAttributes));
}
void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 27981f25dc..0b4c677d70 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -37,7 +37,7 @@ namespace {
#pragma mark - Builtin Shader Sources -
-const char *const g_defaultVertexShader =
+const char *const g_defaultVertexShader =
"attribute vec4 position;\n"
"attribute vec2 texCoordIn;\n"
"attribute vec4 blendColorIn;\n"
@@ -286,6 +286,9 @@ GLshader Shader::compileShader(const char *source, GLenum shaderType) {
}
ShaderManager::ShaderManager() : _initializeShaders(true) {
+ for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
+ _builtIn[i] = nullptr;
+ }
}
ShaderManager::~ShaderManager() {
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 8b94549971..33598b5488 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -509,6 +509,7 @@ TextureCLUT8GPU::TextureCLUT8GPU()
// Setup pipeline.
_clut8Pipeline->setFramebuffer(_target);
_clut8Pipeline->setPaletteTexture(&_paletteTexture);
+ _clut8Pipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
}
TextureCLUT8GPU::~TextureCLUT8GPU() {
diff --git a/backends/platform/dingux/README.GCW0 b/backends/platform/dingux/README.GCW0
index 1875e5323a..1b7e30e266 100644
--- a/backends/platform/dingux/README.GCW0
+++ b/backends/platform/dingux/README.GCW0
@@ -24,3 +24,12 @@ It's pretty simple if you are running Linux on an x86/amd64 machine:
3. Run backends/platform/dingux/build.gcw0.sh script
4. Copy the resulting file scummvm.opk to your device
5. Enjoy
+
+Troubleshooting
+===============
+In case you need to submit a bugreport, you may find the log file at the
+following path:
+
+ /var/tmp/scummvm.log
+
+The log file is being overwritten at every ScummVM run.
diff --git a/backends/platform/dingux/dingux.mk b/backends/platform/dingux/dingux.mk
index b7f700d7fd..dc87e41241 100644
--- a/backends/platform/dingux/dingux.mk
+++ b/backends/platform/dingux/dingux.mk
@@ -59,7 +59,7 @@ endif
echo >> $(gcw0_bundle)/README.man.txt
echo '[General README]' >> $(gcw0_bundle)/README.man.txt
echo >> $(gcw0_bundle)/README.man.txt
- cat README | sed -e 's/\[/⟦/g' -e 's/\]/⟧/g' -e '/^1\.1)/,$$ s/^[0-9][0-9]*\.[0-9][0-9]*.*/\[&\]/' >> $(gcw0_bundle)/README.man.txt
+ cat $(srcdir)/README | sed -e 's/\[/⟦/g' -e 's/\]/⟧/g' -e '/^1\.1)/,$$ s/^[0-9][0-9]*\.[0-9][0-9]*.*/\[&\]/' >> $(gcw0_bundle)/README.man.txt
# $(CP) GeneralUser\ GS\ FluidSynth\ v1.44.sf2 $(gcw0_bundle)/
@@ -67,12 +67,12 @@ endif
gcw0-opk-unstripped: $(gcw0_bundle)
$(CP) $(PLUGINS) $(gcw0_bundle)/plugins/
$(CP) $(EXECUTABLE) $(gcw0_bundle)/scummvm
- ./dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm
+ $(srcdir)/dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm
gcw-opk: $(gcw0_bundle)
$(STRIP) $(gcw0_bundle)/plugins/*
$(STRIP) $(gcw0_bundle)/scummvm
- ./dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm
+ $(srcdir)/dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm
GeneralUser_GS_1.44-FluidSynth.zip:
curl -s http://www.scummvm.org/frs/extras/SoundFont/GeneralUser_GS_1.44-FluidSynth.zip -o GeneralUser_GS_1.44-FluidSynth.zip
diff --git a/config.guess b/config.guess
index 6c32c8645c..0967f2afa9 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2016 Free Software Foundation, Inc.
-timestamp='2014-11-04'
+timestamp='2016-04-02'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ timestamp='2014-11-04'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
#
# Please send patches to <config-patches@gnu.org>.
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -168,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
@@ -197,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
os=netbsd
;;
esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
@@ -207,13 +221,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
release='-gnu'
;;
*)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
+ echo "${machine}-${os}${release}${abi}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -223,6 +237,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+ exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
@@ -235,6 +253,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit ;;
+ *:Sortix:*:*)
+ echo ${UNAME_MACHINE}-unknown-sortix
+ exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
@@ -251,42 +272,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
+ UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
+ UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
+ UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
+ UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
+ UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
+ UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
+ UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
+ UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
+ UNAME_MACHINE=alphaev79 ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
@@ -359,16 +380,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
- SUN_ARCH="i386"
+ SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
- SUN_ARCH="x86_64"
+ SUN_ARCH=x86_64
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
@@ -393,7 +414,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
@@ -618,13 +639,13 @@ EOF
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
@@ -663,11 +684,11 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
+ if [ ${HP_ARCH} = hppa2.0w ]
then
eval $set_cc_for_build
@@ -680,12 +701,12 @@ EOF
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
- HP_ARCH="hppa2.0w"
+ HP_ARCH=hppa2.0w
else
- HP_ARCH="hppa64"
+ HP_ARCH=hppa64
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@@ -790,14 +811,14 @@ EOF
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -879,7 +900,7 @@ EOF
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
@@ -902,7 +923,7 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
@@ -933,6 +954,9 @@ EOF
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
@@ -945,6 +969,9 @@ EOF
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
+ k1om:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
@@ -1021,7 +1048,7 @@ EOF
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
@@ -1100,7 +1127,7 @@ EOF
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
+ # prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
@@ -1249,6 +1276,9 @@ EOF
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1262,9 +1292,9 @@ EOF
UNAME_PROCESSOR=powerpc
fi
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
@@ -1286,7 +1316,7 @@ EOF
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
+ if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
@@ -1317,7 +1347,7 @@ EOF
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- if test "$cputype" = "386"; then
+ if test "$cputype" = 386; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
@@ -1359,7 +1389,7 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
@@ -1370,6 +1400,9 @@ EOF
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
+ exit ;;
esac
cat >&2 <<EOF
@@ -1379,9 +1412,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/config.sub b/config.sub
index 7ffe373784..8d39c4ba39 100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2016 Free Software Foundation, Inc.
-timestamp='2014-12-03'
+timestamp='2016-03-30'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ timestamp='2014-12-03'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@@ -53,8 +53,7 @@ timestamp='2014-12-03'
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
@@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +116,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
@@ -255,12 +254,13 @@ case $basic_machine in
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
+ | ba \
| be32 | be64 \
| bfin \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
@@ -305,7 +305,7 @@ case $basic_machine in
| riscv32 | riscv64 \
| rl78 | rx \
| score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -376,12 +376,13 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | ba-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
- | elxsi-* \
+ | e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
@@ -428,12 +429,13 @@ case $basic_machine in
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
+ | riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
@@ -518,6 +520,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-aros
;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -1373,11 +1378,11 @@ case $os in
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
@@ -1393,7 +1398,8 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1525,6 +1531,8 @@ case $os in
;;
-nacl*)
;;
+ -ios)
+ ;;
-none)
;;
*)
diff --git a/devtools/create_wage/create_wage.sh b/devtools/create_classicmacfonts.sh
index 5e8fe352a2..6942d07111 100755
--- a/devtools/create_wage/create_wage.sh
+++ b/devtools/create_classicmacfonts.sh
@@ -106,8 +106,8 @@ echo_n "Converting fonts..."
fondu-060102/fondu -force *.bin
echo done
-zip -9 wage *.bdf
-mv wage.zip wage.dat
+zip -9 classicmacfonts *.bdf
+mv classicmacfonts.zip classicmacfonts.dat
echo_n "Cleaning up..."
rm *.bdf
@@ -116,4 +116,4 @@ rm *.bin
rm *.dmg
echo done
-ls -l wage.dat
+ls -l classicmacfonts.dat
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 235986a878..92754a27b4 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -237,6 +237,7 @@ monkey The Secret of Monkey Island
71523b539491527d9860f4407faf0411 7607 en DOS Demo EGA Demo - Fingolfin
771bc18ec6f93837b839c992b211904b -1 de DOS Demo EGA Demo - khalek
54a936ad06161ff7bfefcb96200f7bff 7617 en Amiga VGA VGA Demo - khalek
+ c0c9de81fb965e6cbe77f6e5631ca705 9135 en DOS SE Talkie Unofficial SE Talkie v1.02 rootfather
pass Passport to Adventure
e6cd81b25ab1453a8a6d3482118c391e 7857 en DOS - - v1.0 9/14/90 Fingolfin
@@ -269,6 +270,7 @@ monkey2 Monkey Island 2: LeChuck's Revenge
430bc518017b6fac046f58bab6baad5d -1 jp FM-TOWNS FM-TOWNS - - Antti Leimi, Andrea Petrucci
387a544b8b10b26912d8413bab63a853 -1 en DOS - Demo non-interactive khalek
+ f4d20ab4ce19743a646cb48bd93aee72 10835 en DOS SE Talkie Unofficial SE Talkie v0.2 rootfather
atlantis Indiana Jones and the Fate of Atlantis
3a03dab514e4038df192d8a8de469788 -1 en Amiga Floppy Floppy - dhewg
diff --git a/doc/de/Neues b/doc/de/Neues
index 106dc6ea88..e3d8f3a607 100644
--- a/doc/de/Neues
+++ b/doc/de/Neues
@@ -15,6 +15,8 @@ Programmcodes finden Sie auf Englisch unter:
Allgemein:
- "TESTING"-Markierung von mehreren unterstützten Spielen entfernt.
- Chinesische Übersetzung (Pinyin) der Benutzeroberfläche hinzugefügt.
+ - Ruckeln des Mauszeigers im ScummVM-Programmfenster behoben, welches auf
+ einigen Systemen auftrat.
BBVS:
- Fehler beim erneuten Starten des Spiels behoben.
@@ -28,10 +30,24 @@ Programmcodes finden Sie auf Englisch unter:
- Laden eines Spielstandes in der "Pendulum"-Szene repariert.
- Falscher Hintergrund für Inventar-Gegenstände im Kapitel 6 in der
spanischen Version korrigiert.
+ - Geschwindigkeit der Animationen korrigiert. Animationen wurden nur halb
+ so schnell wie im originalen Interpreter abgespielt.
+ - Rauschen am Beginn und/oder am Ende der Sprachausgabe behoben.
+ Dieser Fehler trat hauptsächlich in der spanischen Version auf.
+ - Verzögerung während der Interaktion mit dem Verben-Menü und dem Inventar behoben.
+ - Fehler behoben, durch den die Axt im Schloss mehrfach aufgehoben werden konnte.
Gob:
- Aufhängen während Sound-Initialisierung in mehreren Spielen behoben.
+ KYRA:
+ - Potentieller Absturz behoben, der in "Hand of Fate" auftritt, wenn der
+ Sumpfschlangentrank an der Ratte verwendet wird.
+ (HINWEIS: Dieser Fehler wurde bereits in Version 1.8.0 behoben,
+ jedoch nicht in der Neues-Datei erwähnt).
+ - Fehlende Stimm-Reaktionen korrigiert, wenn Gegner in der CD-Version von
+ Lands of Lore getroffen wurden.
+
Lab:
- Aufhängen während der End-Sequenz behoben.
- Interne Spiel-Bedienelemente verbessert.
@@ -74,6 +90,9 @@ Programmcodes finden Sie auf Englisch unter:
wenn ScummVM nicht läuft, und ermöglicht den direkten Start dieser Spiele.
- Sparkle-Updater für vereinfachte Programmaktualisierungen hinzugefügt.
+ GCW0-Portierung:
+ - Verbesserte Unterstützung für die in ScummVM integrierte Dokumentation.
+
1.8.0 (04.03.2016)
Neue Spiele:
- Unterstützung für Rex Nebular and the Cosmic Gender Bender hinzugefügt.
@@ -90,7 +109,7 @@ Programmcodes finden Sie auf Englisch unter:
hinzugefügt.
- Unterstützung für Labyrinth of Time hinzugefügt.
-Neue Portierungen:
+ Neue Portierungen:
- Portierung für den Raspberry Pi hinzugefügt.
- Portierung für den GCW Zero (GCW0) hinzugefügt.
@@ -100,7 +119,7 @@ Neue Portierungen:
SDL:
- Alt+x beendet ScummVM nicht mehr. Verwenden Sie stattdessen
Cmd+q/Strg+q/Strg+z und beachten Sie die Hinweise in der Liesmich-Datei.
- - Auf POSIX-Systemen befolgen wir nun die Spezifikation XDG Base Directory
+ - Auf POSIX-Systemen befolgen wir nun die Spezifikation XDG Base Directory
für die Speicherung von Benutzerdaten. Dies führt zu neuen
Speicherorten für unsere Konfigurationsdatei, unsere Log-Datei sowie für
den standardmäßig voreingestellten Speicherort für Spielstände. Wir
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index e566ad12f6..60c8d1f3ef 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -403,6 +403,11 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_lastSaveTime = 0;
+ _playTimeInSecondsAdjust = 0;
+ _lastUsedPlayTimeInCycles = 0;
+ _lastUsedPlayTimeInSeconds = 0;
+ _passedPlayTimeCycles = 0;
+
memset(_keyQueue, 0, sizeof(_keyQueue));
_console = nullptr;
@@ -418,6 +423,9 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_inventory = nullptr;
_keyHoldMode = false;
+
+ _artificialDelayCurrentRoom = 0;
+ _artificialDelayCurrentPicture = 0;
}
void AgiEngine::initialize() {
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index 793d4081cf..90e5a84829 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -2251,6 +2251,31 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_TALKIE
},
+ // Simon the Sorcerer 2 - Russian DOS CD
+ {
+ {
+ "simon2",
+ "CD",
+
+ {
+ { "gsptr30", GAME_BASEFILE, "e26d162e573587f4601b88701292212c", 58851},
+ { "icon.dat", GAME_ICONFILE, "72096a62d36e6034ea9fecc13b2dbdab", 18089},
+ { "simon2.gme", GAME_GMEFILE, "9c535d403966750ae98bdaf698375a38", 19687892},
+ { "stripped.txt", GAME_STRFILE, "e229f84d46fa83f99b4a7115679f3fb6", 171},
+ { "tbllist", GAME_TBLFILE, "2082f8d02075e590300478853a91ffd9", 513},
+ { NULL, 0, NULL, 0}
+ },
+ Common::RU_RUS,
+ Common::kPlatformDOS,
+ ADGF_CD,
+ GUIO0()
+ },
+
+ GType_SIMON2,
+ GID_SIMON2,
+ GF_TALKIE
+ },
+
// Simon the Sorcerer 2 - Czech Windows CD
{
{
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 54f5c00d93..8b0d8b6c77 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -952,8 +952,9 @@ uint8 Vga::closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 col
}
uint8 Vga::closest(Dac *pal, Dac x) {
- int exp = (sizeof(long) * 8 - 1);
- long D = (1 << exp) - 1; // Maximum value of long.
+ long D = 0;
+ D = ~D;
+ D = (unsigned long)D >> 1; // Maximum value of long.
long R = x._r;
long G = x._g;
long B = x._b;
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
index 7a1258dbde..2eff82bc61 100644
--- a/engines/cruise/dataLoader.cpp
+++ b/engines/cruise/dataLoader.cpp
@@ -249,12 +249,19 @@ int loadFile(const char* name, int idx, int destIdx) {
int numMaxEntriesInSet = getNumMaxEntiresInSet(ptr);
if (destIdx > numMaxEntriesInSet) {
+ MemFree(ptr);
return 0; // exit if limit is reached
}
- return loadSetEntry(name, ptr, destIdx, idx);
+ int res = loadSetEntry(name, ptr, destIdx, idx);
+ MemFree(ptr);
+
+ return res;
}
case type_FNT: {
- return loadFNTSub(ptr, idx);
+ int res = loadFNTSub(ptr, idx);
+ MemFree(ptr);
+
+ return res;
}
case type_SPL: {
// Sound file
diff --git a/engines/drascula/actors.cpp b/engines/drascula/actors.cpp
index a1f2c5386c..b459c4539b 100644
--- a/engines/drascula/actors.cpp
+++ b/engines/drascula/actors.cpp
@@ -196,10 +196,6 @@ void DrasculaEngine::moveCharacters() {
return;
}
}
-
- byte *srcSurface = extraSurface;
- if (currentChapter == 6 && _lang == kSpanish)
- srcSurface = tableSurface;
if (characterMoved == 0) {
curPos[0] = 0;
@@ -218,17 +214,17 @@ void DrasculaEngine::moveCharacters() {
curPos[1] = 0;
if (currentChapter == 2)
copyRect(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- srcSurface, screenSurface);
+ extraSurface, screenSurface);
else
reduce_hare_chico(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- factor_red[curY + curHeight], srcSurface, screenSurface);
+ factor_red[curY + curHeight], extraSurface, screenSurface);
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
copyRect(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- srcSurface, screenSurface);
+ extraSurface, screenSurface);
else
reduce_hare_chico(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- factor_red[curY + curHeight], srcSurface, screenSurface);
+ factor_red[curY + curHeight], extraSurface, screenSurface);
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
copyRect(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
@@ -260,17 +256,17 @@ void DrasculaEngine::moveCharacters() {
curPos[1] = 0;
if (currentChapter == 2)
copyRect(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- srcSurface, screenSurface);
+ extraSurface, screenSurface);
else
reduce_hare_chico(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- factor_red[curY + curHeight], srcSurface, screenSurface);
+ factor_red[curY + curHeight], extraSurface, screenSurface);
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
copyRect(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- srcSurface, screenSurface);
+ extraSurface, screenSurface);
else
reduce_hare_chico(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
- factor_red[curY + curHeight], srcSurface, screenSurface);
+ factor_red[curY + curHeight], extraSurface, screenSurface);
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
copyRect(curPos[0], curPos[1], curPos[2], curPos[3], curPos[4], curPos[5],
diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index 0ed2c61e3f..f672ad3b55 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -1612,7 +1612,7 @@ void DrasculaEngine::animation_6_6() {
removeObject(20);
loadPic(96, frontSurface);
loadPic(97, frontSurface);
- loadPic(97, _lang == kSpanish ? tableSurface : extraSurface);
+ loadPic(97, extraSurface);
loadPic(99, backSurface);
doBreak = 1;
objExit = 104;
@@ -2216,7 +2216,7 @@ void DrasculaEngine::activatePendulum() {
_roomNumber = 102;
loadPic(102, bgSurface, HALF_PAL);
loadPic("an_p1.alg", drawSurface3);
- loadPic("an_p2.alg", _lang == kSpanish ? tableSurface : extraSurface);
+ loadPic("an_p2.alg", extraSurface);
loadPic("an_p3.alg", frontSurface);
copyBackground(0, 171, 0, 0, OBJWIDTH, OBJHEIGHT, backSurface, drawSurface3);
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index 75a81c20b0..ab91056480 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -359,16 +359,13 @@ Common::Error DrasculaEngine::run() {
for (i = 0; i < 25; i++)
memcpy(crosshairCursor + i * 40, tableSurface + 225 + (56 + i) * 320, 40);
- if (_lang == kSpanish)
- loadPic(currentChapter == 6 ? 97 : 974, tableSurface);
+ if (_lang == kSpanish && currentChapter != 6)
+ loadPic(974, tableSurface);
if (currentChapter != 2) {
loadPic(99, cursorSurface);
loadPic(99, backSurface);
- if (currentChapter == 6 && _lang == kSpanish)
- loadPic(95, extraSurface);
- else
- loadPic(97, extraSurface);
+ loadPic(97, extraSurface);
}
memset(iconName, 0, sizeof(iconName));
@@ -598,7 +595,6 @@ bool DrasculaEngine::runCurrentChapter() {
if (_rightMouseButton == 1 && _menuScreen) {
#endif
_rightMouseButton = 0;
- delay(100);
if (currentChapter == 2) {
loadPic(menuBackground, cursorSurface);
loadPic(menuBackground, backSurface);
@@ -627,7 +623,6 @@ bool DrasculaEngine::runCurrentChapter() {
!(currentChapter == 5 && pickedObject == 16)) {
#endif
_rightMouseButton = 0;
- delay(100);
characterMoved = 0;
if (trackProtagonist == 2)
trackProtagonist = 1;
@@ -655,12 +650,11 @@ bool DrasculaEngine::runCurrentChapter() {
#endif
if (_leftMouseButton == 1 && _menuBar) {
- delay(100);
selectVerbFromBar();
} else if (_leftMouseButton == 1 && takeObject == 0) {
- delay(100);
if (verify1())
return true;
+ delay(100);
} else if (_leftMouseButton == 1 && takeObject == 1) {
if (verify2())
return true;
@@ -894,7 +888,7 @@ void DrasculaEngine::pause(int duration) {
}
int DrasculaEngine::getTime() {
- return _system->getMillis() / 20; // originally was 1
+ return _system->getMillis() / 10;
}
void DrasculaEngine::reduce_hare_chico(int xx1, int yy1, int xx2, int yy2, int width, int height, int factor, byte *dir_inicio, byte *dir_fin) {
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 01bd267158..6bfb2e1823 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -217,6 +217,10 @@ void DrasculaEngine::print_abc(const char *said, int screenX, int screenY) {
int letterY = 0, letterX = 0, i;
uint len = strlen(said);
byte c;
+
+ byte *srcSurface = tableSurface;
+ if (_lang == kSpanish && currentChapter == 6)
+ srcSurface = extraSurface;
for (uint h = 0; h < len; h++) {
c = toupper(said[h]);
@@ -241,7 +245,7 @@ void DrasculaEngine::print_abc(const char *said, int screenX, int screenY) {
} // for
copyRect(letterX, letterY, screenX, screenY,
- CHAR_WIDTH, CHAR_HEIGHT, tableSurface, screenSurface);
+ CHAR_WIDTH, CHAR_HEIGHT, srcSurface, screenSurface);
screenX = screenX + CHAR_WIDTH;
if (screenX > 317) {
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index a09b9da07d..07f192cd4c 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -123,15 +123,6 @@ void DrasculaEngine::showMenu() {
int h, n, x;
byte *srcSurface = (currentChapter == 6) ? tableSurface : frontSurface;
x = whichObject();
-
- // The original uses extraSurface to draw text in draw_abc() in the Spanish version
- // while other languages use tableSurface. Here all language use tableSurface for
- // chapter 6. However the code in ScummVM was changed to use tableSurface for all
- // labguage in draw_abc(). So instead here for the Spanish version we use extraSurface.
- // Compared to the original the use of the tableSurface and extraSurface has been swapped
- // for the Spanish language all through chapter 6.
- if (currentChapter == 6 && _lang == kSpanish)
- srcSurface = extraSurface;
for (n = 1; n < ARRAYSIZE(inventoryObjects); n++) {
h = inventoryObjects[n];
diff --git a/engines/drascula/objects.cpp b/engines/drascula/objects.cpp
index 823c073d43..02846abcc9 100644
--- a/engines/drascula/objects.cpp
+++ b/engines/drascula/objects.cpp
@@ -272,6 +272,8 @@ void DrasculaEngine::updateVisible() {
visible[2] = 0;
if (_roomNumber == 26 && flags[12] == 1)
visible[1] = 0;
+ if (_roomNumber == 31 && flags[13] == 1)
+ visible[1] = 0;
if (_roomNumber == 35 && flags[14] == 1)
visible[2] = 0;
if (_roomNumber == 35 && flags[17] == 1)
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index acfc528b0c..57d4517295 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1501,7 +1501,7 @@ void DrasculaEngine::update_102() {
if (actorFrames[kFramePendulum] <= 4)
pendulumSurface = drawSurface3;
else if (actorFrames[kFramePendulum] <= 11)
- pendulumSurface = _lang == kSpanish ? tableSurface : extraSurface;
+ pendulumSurface = extraSurface;
else
pendulumSurface = frontSurface;
diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp
index 6c0c171664..62ec796678 100644
--- a/engines/drascula/sound.cpp
+++ b/engines/drascula/sound.cpp
@@ -44,13 +44,10 @@ void DrasculaEngine::updateVolume(Audio::Mixer::SoundType soundType, int prevVol
}
void DrasculaEngine::volumeControls() {
- byte* srcSurface = tableSurface;
- if (currentChapter == 6 && _lang == kSpanish)
- srcSurface = extraSurface;
- if (_lang == kSpanish)
- loadPic(95, srcSurface);
+ if (_lang == kSpanish && currentChapter != 6)
+ loadPic(95, tableSurface);
- copyRect(1, 56, 73, 63, 177, 97, srcSurface, screenSurface);
+ copyRect(1, 56, 73, 63, 177, 97, tableSurface, screenSurface);
updateScreen(73, 63, 73, 63, 177, 97, screenSurface);
setCursor(kCursorCrosshair);
@@ -67,11 +64,11 @@ void DrasculaEngine::volumeControls() {
updateRoom();
- copyRect(1, 56, 73, 63, 177, 97, srcSurface, screenSurface);
+ copyRect(1, 56, 73, 63, 177, 97, tableSurface, screenSurface);
- copyBackground(183, 56, 82, masterVolumeY, 39, 2 + masterVolume * 4, srcSurface, screenSurface);
- copyBackground(183, 56, 138, voiceVolumeY, 39, 2 + voiceVolume * 4, srcSurface, screenSurface);
- copyBackground(183, 56, 194, musicVolumeY, 39, 2 + musicVolume * 4, srcSurface, screenSurface);
+ copyBackground(183, 56, 82, masterVolumeY, 39, 2 + masterVolume * 4, tableSurface, screenSurface);
+ copyBackground(183, 56, 138, voiceVolumeY, 39, 2 + voiceVolume * 4, tableSurface, screenSurface);
+ copyBackground(183, 56, 194, musicVolumeY, 39, 2 + musicVolume * 4, tableSurface, screenSurface);
updateScreen();
@@ -104,8 +101,8 @@ void DrasculaEngine::volumeControls() {
}
- if (_lang == kSpanish)
- loadPic(currentChapter == 6 ? 95 : 974, srcSurface);
+ if (_lang == kSpanish && currentChapter != 6)
+ loadPic(974, tableSurface);
selectVerb(kVerbNone);
@@ -169,8 +166,8 @@ void DrasculaEngine::MusicFadeout() {
void DrasculaEngine::playFile(const char *fname) {
Common::SeekableReadStream *stream = _archives.open(fname);
if (stream) {
- int startOffset = 0;
- int soundSize = stream->size() - startOffset;
+ int startOffset = 32;
+ int soundSize = stream->size() - 64;
if (!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish) {
// WORKAROUND: File 3.als with English speech files has a big silence at
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index 3176c5e0f3..cc329b206b 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -440,12 +440,9 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else if (notTowers) {
- byte *srcSurface = extraSurface;
- if (currentChapter == 6 && _lang == kSpanish)
- srcSurface = tableSurface;
reduce_hare_chico(x_talk_izq[face], y_mask_talk, curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
- srcSurface, screenSurface);
+ extraSurface, screenSurface);
}
updateRefresh();
} else if (trackProtagonist == 1) {
@@ -453,11 +450,8 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else if (notTowers) {
- byte *srcSurface = extraSurface;
- if (currentChapter == 6 && _lang == kSpanish)
- srcSurface = tableSurface;
reduce_hare_chico(x_talk_dch[face], y_mask_talk, curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)], srcSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
}
updateRefresh();
} else if (trackProtagonist == 2) {
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index ebaff32550..c2aae9ba88 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -24,6 +24,7 @@
#include "common/archive.h"
#include "common/config-manager.h"
+#include "audio/mixer.h"
#include "engines/util.h"
@@ -112,6 +113,8 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
_musicLocal = 0;
_trackStartDelay = 0;
+ _sceneTrackHandle = new Audio::SoundHandle();
+
memset(_sceneTracks, 0, sizeof(_sceneTracks));
memset(_trackName, 0, sizeof(_trackName));
memset(_sceneTracksCurrentTrack, 0, sizeof(_sceneTracksCurrentTrack));
@@ -192,6 +195,7 @@ FullpipeEngine::~FullpipeEngine() {
delete _rnd;
delete _console;
delete _globalMessageQueueList;
+ delete _sceneTrackHandle;
}
void FullpipeEngine::initialize() {
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 7f20a6d6af..fba61aa13b 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -30,8 +30,6 @@
#include "common/savefile.h"
#include "common/system.h"
-#include "audio/mixer.h"
-
#include "graphics/transparent_surface.h"
#include "engines/engine.h"
@@ -41,6 +39,10 @@
struct ADGameDescription;
+namespace Audio {
+class SoundHandle;
+}
+
namespace Fullpipe {
enum FullpipeGameFeatures {
@@ -312,7 +314,7 @@ public:
void lift_openLift();
GameVar *_musicGameVar;
- Audio::SoundHandle _sceneTrackHandle;
+ Audio::SoundHandle *_sceneTrackHandle;
public:
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
index 230d6c39a9..c82c2c414c 100644
--- a/engines/fullpipe/sound.cpp
+++ b/engines/fullpipe/sound.cpp
@@ -30,6 +30,7 @@
#include "fullpipe/statics.h"
#include "common/memstream.h"
+#include "audio/mixer.h"
#include "audio/audiostream.h"
#include "audio/decoders/vorbis.h"
#include "audio/decoders/wave.h"
@@ -96,12 +97,13 @@ Sound::Sound() {
memset(_directSoundBuffers, 0, sizeof(_directSoundBuffers));
_description = 0;
_volume = 100;
+ _handle = new Audio::SoundHandle();
}
Sound::~Sound() {
freeSound();
-
free(_description);
+ delete _handle;
}
bool Sound::load(MfcArchive &file, NGIArchive *archive) {
@@ -206,14 +208,14 @@ void Sound::setPanAndVolumeByStaticAni() {
}
void Sound::setPanAndVolume(int vol, int pan) {
- g_fp->_mixer->setChannelVolume(_handle, vol / 39); // 0..10000
- g_fp->_mixer->setChannelBalance(_handle, pan / 78); // -10000..10000
+ g_fp->_mixer->setChannelVolume(*_handle, vol / 39); // 0..10000
+ g_fp->_mixer->setChannelBalance(*_handle, pan / 78); // -10000..10000
}
void Sound::play(int flag) {
- Audio::SoundHandle handle = getHandle();
+ Audio::SoundHandle *handle = getHandle();
- if (g_fp->_mixer->isSoundHandleActive(handle))
+ if (g_fp->_mixer->isSoundHandleActive(*handle))
return;
byte *soundData = loadData();
@@ -221,7 +223,7 @@ void Sound::play(int flag) {
Audio::RewindableAudioStream *wav = Audio::makeWAVStream(dataStream, DisposeAfterUse::YES);
Audio::AudioStream *audioStream = new Audio::LoopingAudioStream(wav, (flag == 1) ? 0 : 1);
- g_fp->_mixer->playStream(Audio::Mixer::kSFXSoundType, &handle, audioStream);
+ g_fp->_mixer->playStream(Audio::Mixer::kSFXSoundType, handle, audioStream);
}
void Sound::freeSound() {
@@ -231,11 +233,11 @@ void Sound::freeSound() {
}
int Sound::getVolume() {
- return g_fp->_mixer->getChannelVolume(_handle) * 39; // 0..10000
+ return g_fp->_mixer->getChannelVolume(*_handle) * 39; // 0..10000
}
void Sound::stop() {
- g_fp->_mixer->stopHandle(_handle);
+ g_fp->_mixer->stopHandle(*_handle);
}
void FullpipeEngine::setSceneMusicParameters(GameVar *gvar) {
@@ -353,7 +355,7 @@ void FullpipeEngine::startSoundStream1(char *trackName) {
stopAllSoundStreams();
#ifdef USE_VORBIS
- if (_mixer->isSoundHandleActive(_sceneTrackHandle))
+ if (_mixer->isSoundHandleActive(*_sceneTrackHandle))
return;
Common::File *track = new Common::File();
@@ -363,7 +365,7 @@ void FullpipeEngine::startSoundStream1(char *trackName) {
return;
}
Audio::RewindableAudioStream *ogg = Audio::makeVorbisStream(track, DisposeAfterUse::YES);
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_sceneTrackHandle, ogg);
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, _sceneTrackHandle, ogg);
#endif
}
diff --git a/engines/fullpipe/sound.h b/engines/fullpipe/sound.h
index 14e766f5bb..983f28312b 100644
--- a/engines/fullpipe/sound.h
+++ b/engines/fullpipe/sound.h
@@ -23,6 +23,10 @@
#ifndef FULLPIPE_SOUND_H
#define FULLPIPE_SOUND_H
+namespace Audio {
+class SoundHandle;
+}
+
namespace Fullpipe {
class Sound : public MemoryObject {
@@ -31,7 +35,7 @@ class Sound : public MemoryObject {
int _directSoundBuffer;
int _directSoundBuffers[7];
byte *_soundData;
- Audio::SoundHandle _handle;
+ Audio::SoundHandle *_handle;
int _volume;
public:
@@ -45,7 +49,7 @@ public:
virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
void updateVolume();
int getId() const { return _id; }
- Audio::SoundHandle getHandle() const { return _handle; }
+ Audio::SoundHandle *getHandle() const { return _handle; }
void play(int flag);
void freeSound();
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 8ee3b14d0c..36fbb73037 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1576,6 +1576,9 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
_m2x = 0;
_m2y = 0;
+ _counter = 0;
+ _counterMax = 0;
+
_field_78 = 0;
_framePosOffsets = 0;
_field_84 = 0;
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 697e6e1269..7308214551 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -366,7 +366,7 @@ void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
assert(_name1.size() <= 16);
assert(_name2.size() <= 16);
- if (_name2.matchString("NISSND?") && (_status.status & kFlagType9) != kFlag3) {
+ if (_name2.matchString("NISSND?") && ((_status.status & kFlagType9) != kFlag3)) {
s.syncAsUint32LE(_status.status);
s.syncAsUint32LE(_type);
s.syncAsUint32LE(_blockCount); // field_8;
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index 3eab31acc2..0020cb398c 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -40,6 +40,7 @@ namespace Made {
*/
Object::Object() : _objData(NULL), _freeData(false) {
+ _objSize = 0;
}
Object::~Object() {
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index f1539297ee..a29aa2512f 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -58,11 +58,24 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
const GameSettings *g;
+ _eventNum = 0;
+ _eventMouseX = _eventMouseY = 0;
+ _eventKey = 0;
+ _autoStopSound = false;
+ _soundEnergyIndex = 0;
+ _soundEnergyArray = 0;
+ _musicBeatStart = 0;
+ _cdTimeStart = 0;
+
+ _gameId = -1;
+
const char *gameid = ConfMan.get("gameid").c_str();
for (g = madeSettings; g->gameid; ++g)
if (!scumm_stricmp(g->gameid, gameid))
_gameId = g->id;
+ assert(_gameId != -1);
+
_rnd = new Common::RandomSource("made");
_console = new MadeConsole(this);
@@ -85,6 +98,8 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_music = nullptr;
+ _soundRate = 0;
+
// Set default sound frequency
switch (getGameID()) {
case GID_RODNEY:
diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp
index 453e2a4872..0beb132b93 100644
--- a/engines/made/pmvplayer.cpp
+++ b/engines/made/pmvplayer.cpp
@@ -223,7 +223,10 @@ bool PmvPlayer::play(const char *filename) {
//delete _audioStream;
delete _fd;
- _surface->free();
+
+ if(_surface)
+ _surface->free();
+
delete _surface;
return !_aborted;
diff --git a/engines/made/redreader.cpp b/engines/made/redreader.cpp
index f92ffd8dd8..a0aaf7be43 100644
--- a/engines/made/redreader.cpp
+++ b/engines/made/redreader.cpp
@@ -102,7 +102,7 @@ int LzhDecompressor::decompress(Common::SeekableReadStream &source, byte *dest,
int bufsize;
byte* buffer;
- buffer = (byte *) malloc(DICSIZ);
+ buffer = (byte *)calloc(DICSIZ, 1);
_source = &source;
_compSize = sourceLen;
diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp
index f8e763e74e..a9734ed47d 100644
--- a/engines/made/resource.cpp
+++ b/engines/made/resource.cpp
@@ -43,6 +43,7 @@ Resource::~Resource() {
PictureResource::PictureResource() : _picture(NULL), _picturePalette(NULL) {
_hasPalette = false;
+ _paletteColorCount = 0;
}
PictureResource::~PictureResource() {
@@ -182,6 +183,9 @@ void PictureResource::loadChunked(byte *source, int size) {
/* AnimationResource */
AnimationResource::AnimationResource() {
+ _flags = 0;
+ _width = 0;
+ _height = 0;
}
AnimationResource::~AnimationResource() {
diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp
index edccb68953..33edb3834c 100644
--- a/engines/made/screen.cpp
+++ b/engines/made/screen.cpp
@@ -91,6 +91,8 @@ Screen::Screen(MadeEngine *vm) : _vm(vm) {
_currentFontNum = 0;
_fontDrawCtx.clipRect = Common::Rect(320, 200);
_fontDrawCtx.destSurface = _backgroundScreen;
+ _outlineColor = 0;
+ _dropShadowColor = 0;
clearChannels();
}
diff --git a/engines/made/sound.cpp b/engines/made/sound.cpp
index ad49031e7b..62559efa84 100644
--- a/engines/made/sound.cpp
+++ b/engines/made/sound.cpp
@@ -155,6 +155,7 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
};
soundEnergyItem.position = 0;
+ memset(deltaSoundBuffer, 0, 1024);
if (soundEnergyArray)
soundEnergyArray->clear();
@@ -237,6 +238,7 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
break;
default:
+ delete[] soundBuffer;
return;
}
@@ -247,6 +249,9 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
// soundBuffer.
soundBuffer[workChunkSize] = soundBuffer[workChunkSize - 1];
+ for (i = 0; i < chunkSize; i++)
+ soundBuffer[i] = 0;
+
if (deltaType == 1) {
for (i = 0; i < chunkSize - 1; i += 2) {
l = i / 2;
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index 29bcd10094..5776d813cf 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -58,6 +58,7 @@ MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
_resources = nullptr;
_sound = nullptr;
_audio = nullptr;
+ _screen = nullptr;
}
MADSEngine::~MADSEngine() {
diff --git a/engines/mads/menu_views.h b/engines/mads/menu_views.h
index c203248ad9..e22b6223a7 100644
--- a/engines/mads/menu_views.h
+++ b/engines/mads/menu_views.h
@@ -8,20 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-<<<<<<< HEAD
-
-=======
*
->>>>>>> master
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-<<<<<<< HEAD
-
-=======
*
->>>>>>> master
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index e2bc88ebf6..633b67f7e9 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -604,7 +604,8 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
_gfx->runTransition(transition, Common::Rect(544, 333), 10, 0);
} else {
_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
- _needsUpdate = true;
+ _system->updateScreen();
+ _needsUpdate = false;
}
}
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
index 90d366ed7e..81b2edb57d 100644
--- a/engines/mortevielle/mortevielle.cpp
+++ b/engines/mortevielle/mortevielle.cpp
@@ -145,6 +145,7 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescr
_endGame = false;
_loseGame = false;
_txxFileFl = false;
+ _is = 0;
}
MortevielleEngine::~MortevielleEngine() {
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index 50a5b38d8d..8f895f1532 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -163,7 +163,7 @@ int16 Program::findLocal(const char* name) {
int16 Program::addLocal(const char *name, int16 value, int16 min, int16 max) {
assert(_numLocals < NUM_LOCALS);
- strcpy(_localNames[_numLocals], name);
+ Common::strlcpy(_localNames[_numLocals], name, 10);
_locals[_numLocals].setRange(min, max);
_locals[_numLocals].setValue(value);
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 2b75e78582..bbe759dffe 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -60,6 +60,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
DebugMan.addDebugChannel(kDebugMenu, "menu", "Menu debug level");
DebugMan.addDebugChannel(kDebugInventory, "inventory", "Inventory debug level");
+ _screenWidth = 0;
_screenHeight = 0;
_screenSize = 0;
_gameType = 0;
@@ -86,6 +87,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
_inventory = 0;
_currentLocationIndex = 0;
_numLocations = 0;
+ _language = 0;
}
Parallaction::~Parallaction() {
@@ -208,7 +210,7 @@ void Parallaction::allocateLocationSlot(const char *name) {
error("No more location slots available. Please report this immediately to ScummVM team");
if (_currentLocationIndex == -1) {
- strcpy(_locationNames[_numLocations], name);
+ Common::strlcpy(_locationNames[_numLocations], name, 10);
_currentLocationIndex = _numLocations;
_numLocations++;
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index 1e1c0b0a3d..9f045cb397 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -320,7 +320,7 @@ void Parallaction_br::changeLocation() {
freeLocation(false);
// load new location
- strcpy(_location._name, _newLocationName.c_str());
+ Common::strlcpy(_location._name, _newLocationName.c_str(), 100);
parseLocation(_location._name);
if (_location._startPosition.x != -1000) {
diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp
index 77680178c1..e50378b9c0 100644
--- a/engines/saga/isomap.cpp
+++ b/engines/saga/isomap.cpp
@@ -97,6 +97,23 @@ IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) {
_viewScroll.x = (128 - 8) * 16;
_viewScroll.y = (128 - 8) * 16 - 64;
_viewDiff = 1;
+ _platformHeight = 0;
+ _queueCount = _readCount = 0;
+
+ for (int i = 0; i < SAGA_DRAGON_SEARCH_DIAMETER; i++)
+ for (int j = 0; j < SAGA_DRAGON_SEARCH_DIAMETER; j++)
+ _dragonSearchArray.cell[i][j].visited = _dragonSearchArray.cell[i][j].direction = 0;
+
+ for (int i = 0; i < SAGA_SEARCH_DIAMETER; i++)
+ for (int j = 0; j < SAGA_SEARCH_DIAMETER; j++)
+ _searchArray.cell[i][j].visited = _searchArray.cell[i][j].direction = 0;
+
+ for (int i = 0; i < SAGA_SEARCH_QUEUE_SIZE; i++) {
+ memset(&_dragonSearchArray.queue[i], 0, sizeof(DragonTilePoint));
+ memset(&_searchArray.queue[i], 0, sizeof(TilePoint));
+ }
+
+ memset(&_tileMap, 0, sizeof(TileMapData));
}
void IsoMap::loadImages(const ByteArray &resourceData) {
diff --git a/engines/saga/puzzle.cpp b/engines/saga/puzzle.cpp
index 099bf79e6b..2c9a02beec 100644
--- a/engines/saga/puzzle.cpp
+++ b/engines/saga/puzzle.cpp
@@ -86,6 +86,11 @@ Puzzle::Puzzle(SagaEngine *vm) : _vm(vm), _solved(false), _active(false) {
_hintBox.setWidth(240);
_hintBox.setHeight(30);
+ _hintNextRqState = kRQNoHint;
+ _hintGiver = 0;
+ _hintSpeaker = 0;
+ _slidePointX = _slidePointY = 0;
+
initPieceInfo( 0, 268, 18, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3,
Point(0, 1), Point(0, 62), Point(15, 31), Point(0, 0), Point(0, 0), Point(0,0));
initPieceInfo( 1, 270, 52, 0, 0, 0 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4,
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index e659e09ce8..2d798bb0d6 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -56,7 +56,7 @@ SaveFileData *SagaEngine::getSaveFile(uint idx) {
return &_saveFiles[_saveFilesCount - idx - 1];
} else {
if (!emptySlot.name[0])
- strcpy(emptySlot.name, getTextString(kTextNewSave));
+ Common::strlcpy(emptySlot.name, getTextString(kTextNewSave), SAVE_TITLE_SIZE);
return (idx == 0) ? &emptySlot : &_saveFiles[_saveFilesCount - idx];
}
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 2f6ca167a0..c01613268a 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -4356,6 +4356,16 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Torin's Passage - Russian Windows CD (SoftClub official translate)
+ // SCI interpreter version 2.100.002
+ // VERSION file "1.0"
+ { "torin", "",{
+ { "resource.aud", 0, "f66df699be5ed011b16b3f816cee8a04", 210583510 },
+ { "ressci.000", 0, "e672da099fb1663b87c78abc6c8ba2a4", 130622695 },
+ { "resmap.000", 0, "643859f8f2be8e7701611e29b3b65208", 9799 },
+ AD_LISTEND },
+ Common::RU_RUS, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Torin's Passage - English Macintosh
{"torin", "", {
{"Data1", 0, "63887e33cc282c92dc1f916f54aea8eb", 700786},
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 5a994cb699..bb3e7f6ec3 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -245,9 +245,11 @@ static const GameSettings gameVariantsTable[] = {
{"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
{"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
+ {"monkey", "SE Talkie", 0, GID_MONKEY, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_AUDIOTRACKS, UNK, GUIO0()},
{"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
{"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO5(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
+ {"monkey2", "SE Talkie",0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "Steam", "steam", GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index 370f54c1d8..51d9a9045f 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -27,6 +27,8 @@
#ifdef ENABLE_HE
#include "scumm/he/floodfill_he.h"
#include "scumm/he/wiz_he.h"
+
+#include "scumm/he/moonbase/moonbase.h"
#endif
#include "scumm/actor_he.h" // For AuxBlock & AuxEntry
@@ -186,6 +188,7 @@ protected:
#ifdef ENABLE_HE
class ScummEngine_v71he : public ScummEngine_v70he {
friend class Wiz;
+ friend class Moonbase;
protected:
bool _skipProcessActors;
@@ -244,6 +247,10 @@ public:
void queueAuxEntry(int actorNum, int subIndex);
void remapHEPalette(const uint8 *src, uint8 *dst);
+
+public:
+ /* Moonbase stuff */
+ Moonbase *_moonbase;
};
class ScummEngine_v72he : public ScummEngine_v71he {
diff --git a/engines/scumm/he/logic/moonbase.cpp b/engines/scumm/he/logic/moonbase.cpp
deleted file mode 100644
index 29a0dde7a2..0000000000
--- a/engines/scumm/he/logic/moonbase.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "scumm/he/intern_he.h"
-#include "scumm/he/logic_he.h"
-
-namespace Scumm {
-
-/**
- * Logic code for:
- * Moonbase Commander
- */
-class LogicHEmoonbase : public LogicHE {
-public:
- LogicHEmoonbase(ScummEngine_v90he *vm) : LogicHE(vm) {}
-
- int versionID();
-};
-
-int LogicHEmoonbase::versionID() {
- if (_vm->_game.features & GF_DEMO)
- return -100;
- else if (strcmp(_vm->_game.variant, "1.1") == 0)
- return 110;
- else
- return 100;
-}
-
-LogicHE *makeLogicHEmoonbase(ScummEngine_v90he *vm) {
- return new LogicHEmoonbase(vm);
-}
-
-} // End of namespace Scumm
diff --git a/engines/scumm/he/logic/moonbase_logic.cpp b/engines/scumm/he/logic/moonbase_logic.cpp
new file mode 100644
index 0000000000..5f02fa9cd4
--- /dev/null
+++ b/engines/scumm/he/logic/moonbase_logic.cpp
@@ -0,0 +1,231 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "scumm/he/intern_he.h"
+#include "scumm/he/logic_he.h"
+
+namespace Scumm {
+
+/**
+ * Logic code for:
+ * Moonbase Commander
+ */
+class LogicHEmoonbase : public LogicHE {
+public:
+ LogicHEmoonbase(ScummEngine_v90he *vm) : LogicHE(vm) {}
+
+ int versionID();
+
+ int32 dispatch(int op, int numArgs, int32 *args);
+
+private:
+ void op_create_multi_state_wiz(int op, int numArgs, int32 *args);
+ void op_load_multi_channel_wiz(int op, int numArgs, int32 *args);
+ void op_wiz_from_multi_channel_wiz(int op, int numArgs, int32 *args);
+ void op_dos_command(int op, int numArgs, int32 *args);
+ void op_set_fow_sentinel(int32 *args);
+ void op_set_fow_information(int op, int numArgs, int32 *args);
+ void op_set_fow_image(int op, int numArgs, int32 *args);
+
+ void op_ai_test_kludge(int op, int numArgs, int32 *args);
+ void op_ai_master_control_program(int op, int numArgs, int32 *args);
+ void op_ai_reset(int op, int numArgs, int32 *args);
+ void op_ai_set_type(int op, int numArgs, int32 *args);
+ void op_ai_clean_up(int op, int numArgs, int32 *args);
+};
+
+int LogicHEmoonbase::versionID() {
+ if (_vm->_game.features & GF_DEMO)
+ return -100;
+ else if (strcmp(_vm->_game.variant, "1.1") == 0)
+ return 110;
+ else
+ return 100;
+}
+
+#define OP_CREATE_MULTI_STATE_WIZ 100
+#define OP_LOAD_MULTI_CHANNEL_WIZ 101
+#define OP_WIZ_FROM_MULTI_CHANNEL_WIZ 102
+#define OP_DOS_COMMAND 103
+#define OP_SET_FOW_SENTINEL 104
+#define OP_SET_FOW_INFORMATION 105
+#define OP_SET_FOW_IMAGE 106
+
+#define OP_AI_TEST_KLUDGE 10000
+#define OP_AI_MASTER_CONTROL_PROGRAM 10001
+#define OP_AI_RESET 10002
+#define OP_AI_SET_TYPE 10003
+#define OP_AI_CLEAN_UP 10004
+
+#define OP_NET_REMOTE_START_SCRIPT 1492
+#define OP_NET_DO_INIT_ALL 1493
+#define OP_NET_DO_INIT_PROVIDER 1494
+#define OP_NET_DO_INIT_SESSION 1495
+#define OP_NET_DO_INIT_USER 1496
+#define OP_NET_QUERY_PROVIDERS 1497
+#define OP_NET_GET_PROVIDER_NAME 1498
+#define OP_NET_SET_PROVIDER 1499
+#define OP_NET_CLOSE_PROVIDER 1500
+#define OP_NET_QUERY_SESSIONS 1501
+#define OP_NET_GET_SESSION_NAME 1502
+#define OP_NET_CREATE_SESSION 1503
+#define OP_NET_JOIN_SESSION 1504
+#define OP_NET_END_SESSION 1505
+#define OP_NET_ADD_USER 1506
+#define OP_NET_REMOVE_USER 1507
+#define OP_NET_WHO_SENT_THIS 1508
+#define OP_NET_REMOTE_SEND_ARRAY 1509
+#define OP_NET_WHO_AM_I 1510
+#define OP_NET_REMOTE_START_FUNCTION 1511
+#define OP_NET_GET_PLAYER_LONG_NAME 1512
+#define OP_NET_GET_PLAYER_SHORT_NAME 1513
+#define OP_NET_SET_PROVIDER_BY_NAME 1516
+#define OP_NET_HOST_TCPIP_GAME 1517
+#define OP_NET_JOIN_TCPIP_GAME 1518
+#define OP_NET_SET_FAKE_LAG 1555
+#define OP_NET_GET_HOST_NAME 1556
+#define OP_NET_GET_IP_FROM_NAME 1557
+#define OP_NET_GET_SESSION_PLAYER_COUNT 1558
+#define OP_NET_DISABLE_SESSION_PLAYER_JOIN 1559
+#define OP_NET_START_QUERY_SESSIONS 1560
+#define OP_NET_UPDATE_QUERY_SESSIONS 1561
+#define OP_NET_STOP_QUERY_SESSIONS 1562
+#define OP_NET_DESTROY_PLAYER 1563
+#define OP_NET_ENABLE_SESSION_PLAYER_JOIN 1564
+#define OP_NET_SET_AI_PLAYER_COUNT 1565
+
+
+int32 LogicHEmoonbase::dispatch(int op, int numArgs, int32 *args) {
+ switch (op) {
+ case OP_CREATE_MULTI_STATE_WIZ:
+ op_create_multi_state_wiz(op, numArgs, args);
+ break;
+ case OP_LOAD_MULTI_CHANNEL_WIZ:
+ op_load_multi_channel_wiz(op, numArgs, args);
+ break;
+ case OP_WIZ_FROM_MULTI_CHANNEL_WIZ:
+ op_wiz_from_multi_channel_wiz(op, numArgs, args);
+ break;
+ case OP_DOS_COMMAND:
+ op_dos_command(op, numArgs, args);
+ break;
+ case OP_SET_FOW_SENTINEL:
+ op_set_fow_sentinel(args);
+ break;
+ case OP_SET_FOW_INFORMATION:
+ op_set_fow_information(op, numArgs, args);
+ break;
+ case OP_SET_FOW_IMAGE:
+ op_set_fow_image(op, numArgs, args);
+ break;
+
+ case OP_AI_TEST_KLUDGE:
+ op_ai_test_kludge(op, numArgs, args);
+ break;
+ case OP_AI_MASTER_CONTROL_PROGRAM:
+ op_ai_master_control_program(op, numArgs, args);
+ break;
+ case OP_AI_RESET:
+ op_ai_reset(op, numArgs, args);
+ break;
+ case OP_AI_SET_TYPE:
+ op_ai_set_type(op, numArgs, args);
+ break;
+ case OP_AI_CLEAN_UP:
+ op_ai_clean_up(op, numArgs, args);
+ break;
+
+ default:
+ LogicHE::dispatch(op, numArgs, args);
+ }
+
+ return 0;
+}
+
+void LogicHEmoonbase::op_create_multi_state_wiz(int op, int numArgs, int32 *args) {
+ warning("STUB: op_create_multi_state_wiz()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_load_multi_channel_wiz(int op, int numArgs, int32 *args) {
+ warning("STUB: op_load_multi_channel_wiz()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_wiz_from_multi_channel_wiz(int op, int numArgs, int32 *args) {
+ warning("STUB: op_wiz_from_multi_channel_wiz()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_dos_command(int op, int numArgs, int32 *args) {
+ warning("STUB: op_dos_command()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_set_fow_sentinel(int32 *args) {
+ debug(2, "op_set_fow_sentinel(%d, %d, %d)", args[0], args[1], args[2]);
+
+ _vm->_moonbase->_fowSentinelImage = args[0];
+ _vm->_moonbase->_fowSentinelState = args[1];
+ _vm->_moonbase->_fowSentinelConditionBits = args[2];
+}
+
+void LogicHEmoonbase::op_set_fow_information(int op, int numArgs, int32 *args) {
+ warning("STUB: op_set_fow_information()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_set_fow_image(int op, int numArgs, int32 *args) {
+ warning("STUB: op_set_fow_image()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_ai_test_kludge(int op, int numArgs, int32 *args) {
+ warning("STUB: op_ai_test_kludge()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_ai_master_control_program(int op, int numArgs, int32 *args) {
+ warning("STUB: op_ai_master_control_program()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_ai_reset(int op, int numArgs, int32 *args) {
+ warning("STUB: op_ai_reset)");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_ai_set_type(int op, int numArgs, int32 *args) {
+ warning("STUB: op_ai_set_type()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+void LogicHEmoonbase::op_ai_clean_up(int op, int numArgs, int32 *args) {
+ warning("STUB: op_ai_clean_up()");
+ LogicHE::dispatch(op, numArgs, args);
+}
+
+LogicHE *makeLogicHEmoonbase(ScummEngine_v90he *vm) {
+ return new LogicHEmoonbase(vm);
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/he/moonbase/moonbase.cpp b/engines/scumm/he/moonbase/moonbase.cpp
new file mode 100644
index 0000000000..a07a874b48
--- /dev/null
+++ b/engines/scumm/he/moonbase/moonbase.cpp
@@ -0,0 +1,154 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "scumm/he/intern_he.h"
+
+namespace Scumm {
+
+Moonbase::Moonbase(ScummEngine_v71he *vm) : _vm(vm) {
+ initFOW();
+}
+
+Moonbase::~Moonbase() {
+}
+
+void Moonbase::blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox,
+ uint8 *wizd, int x, int y, int rawROP, int paramROP) {
+
+ Common::Rect clippedDstRect(dstw, dsth);
+ if (clipBox) {
+ Common::Rect clip(clipBox->left, clipBox->top, clipBox->right, clipBox->bottom);
+ if (clippedDstRect.intersects(clip)) {
+ clippedDstRect.clip(clip);
+ } else {
+ return;
+ }
+ }
+
+ int width = READ_LE_UINT16(wizd + 0x8 + 0);
+ int height = READ_LE_UINT16(wizd + 0x8 + 2);
+
+ Common::Rect srcLimitsRect(width, height);
+ Common::Rect dstOperation(x, y, x + width, y + height);
+ if (!clippedDstRect.intersects(dstOperation))
+ return;
+ Common::Rect clippedRect = clippedDstRect.findIntersectingRect(dstOperation);
+
+ int cx = clippedRect.right - clippedRect.left;
+ int cy = clippedRect.bottom - clippedRect.top;
+
+ int sx = ((clippedRect.left - x) + srcLimitsRect.left);
+ int sy = ((clippedRect.top - y) + srcLimitsRect.top);
+
+ dst += clippedRect.top * dstPitch + clippedRect.left * 2;
+
+ int headerSize = READ_LE_UINT32(wizd + 0x4);
+ uint8 *dataPointer = wizd + 0x8 + headerSize;
+
+ for (int i = 0; i < sy; i++) {
+ uint16 lineSize = READ_LE_UINT16(dataPointer + 0);
+
+ dataPointer += lineSize;
+ }
+
+ for (int i = 0; i < cy; i++) {
+ uint16 lineSize = READ_LE_UINT16(dataPointer + 0);
+ uint8 *singlesOffset = READ_LE_UINT16(dataPointer + 2) + dataPointer;
+ uint8 *quadsOffset = READ_LE_UINT16(dataPointer + 4) + dataPointer;
+
+ int pixels = 0;
+ byte *dst1 = dst;
+ byte *codes = dataPointer + 6;
+
+ while (1) {
+ int code = *codes - 2;
+ codes++;
+
+ if (code == 0) { // quad
+ for (int c = 0; c < 4; c++) {
+ if (pixels >= sx) {
+ WRITE_LE_UINT16(dst1, READ_LE_UINT16(quadsOffset));
+ dst1 += 2;
+ }
+ quadsOffset += 2;
+ pixels++;
+ }
+ } else if (code < 0) { // single
+ if (pixels >= sx) {
+ WRITE_LE_UINT16(dst1, READ_LE_UINT16(singlesOffset));
+ dst1 += 2;
+ }
+ singlesOffset += 2;
+ pixels++;
+ } else { // skip
+ if ((code & 1) == 0) {
+ code >>= 1;
+
+ for (int j = 0; j < code; j++) {
+ if (pixels >= sx)
+ dst1 += 2;
+ pixels++;
+ }
+ } else { // special case
+ if (pixels >= sx) {
+ int alpha = code >> 1;
+ uint16 color = READ_LE_UINT16(singlesOffset);
+ uint32 orig = READ_LE_UINT16(dst1);
+
+ //WRITE_LE_UINT16(dst1, color); // ENABLE_PREMUL_ALPHA = 0
+ // ENABLE_PREMUL_ALPHA = 2
+ if (alpha > 32) {
+ alpha -= 32;
+
+ uint32 oR = orig & 0x7c00;
+ uint32 oG = orig & 0x03e0;
+ uint32 oB = orig & 0x1f;
+ uint32 dR = ((((color & 0x7c00) - oR) * alpha) >> 5) + oR;
+ uint32 dG = ((((color & 0x3e0) - oG) * alpha) >> 5) + oG;
+ uint32 dB = ((((color & 0x1f) - oB) * alpha) >> 5) + oB;
+
+ WRITE_LE_UINT16(dst1, (dR & 0x7c00) | (dG & 0x3e0) | (dB & 0x1f));
+ } else {
+ uint32 pix = ((orig << 16) | orig) & 0x3e07c1f;
+ pix = (((pix * alpha) & 0xffffffff) >> 5) & 0x3e07c1f;
+ pix = ((pix << 16) + pix + color) & 0xffff;
+
+ WRITE_LE_UINT16(dst1, pix);
+ }
+
+ dst1 += 2;
+ }
+ singlesOffset += 2;
+ pixels++;
+ }
+ }
+
+ if (pixels >= cx + sx)
+ break;
+ }
+
+ dataPointer += lineSize;
+ dst += dstPitch;
+ }
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/he/moonbase/moonbase.h b/engines/scumm/he/moonbase/moonbase.h
new file mode 100644
index 0000000000..e50337ddeb
--- /dev/null
+++ b/engines/scumm/he/moonbase/moonbase.h
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCUMM_HE_MOONBASE_H
+#define SCUMM_HE_MOONBASE_H
+
+#ifdef ENABLE_HE
+
+namespace Scumm {
+
+class Moonbase {
+public:
+ Moonbase(ScummEngine_v71he *vm);
+ ~Moonbase();
+
+ void blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox,
+ uint8 *wizd, int srcx, int srcy, int rawROP, int paramROP);
+
+ // FOW Stuff
+ void initFOW();
+ void releaseFOWResources();
+
+ bool setFOWImage(int id);
+
+ void setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int viewX, int viewY, int clipX1,
+ int clipY1, int clipX2, int clipY2, int technique, int nFrame);
+
+
+ void renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int flags);
+
+private:
+ bool captureFOWImageFromLocation(void *src);
+ int readFOWVisibilityArray(int array, int y, int x);
+ void renderFOWState(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int x, int y, int srcw, int srch, int state, int flags);
+
+public:
+ int _fowSentinelImage;
+ int _fowSentinelState;
+ uint16 _fowSentinelConditionBits;
+
+private:
+ ScummEngine_v71he *_vm;
+
+ int _fowFrameBaseNumber;
+ int _fowAnimationFrames;
+ int _fowCurrentFOWFrame;
+
+ int _fowTileW;
+ int _fowTileH;
+
+ byte *_fowImage;
+ int _fowClipX1;
+ int _fowClipY1;
+ int _fowClipX2;
+ int _fowClipY2;
+
+ int _fowDrawX;
+ int _fowDrawY;
+
+ int _fowVtx1;
+ int _fowVty1;
+ int _fowMvx;
+ int _fowMvy;
+ int _fowVw;
+ int _fowVh;
+
+ bool _fowBlackMode;
+
+ int _fowRenderTable[32768];
+};
+
+#endif
+
+} // End of namespace Scumm
+
+#endif
diff --git a/engines/scumm/he/moonbase/moonbase_fow.cpp b/engines/scumm/he/moonbase/moonbase_fow.cpp
new file mode 100644
index 0000000000..f76bebf89e
--- /dev/null
+++ b/engines/scumm/he/moonbase/moonbase_fow.cpp
@@ -0,0 +1,435 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "scumm/he/intern_he.h"
+
+namespace Scumm {
+
+#define FOW_ANIM_FRAME_COUNT 38
+
+void Moonbase::initFOW() {
+ _fowSentinelImage = -1;
+ _fowSentinelState = -1;
+ _fowSentinelConditionBits = 0;
+
+ _fowFrameBaseNumber = 0;
+ _fowAnimationFrames = 1;
+ _fowCurrentFOWFrame = 0;
+
+ _fowTileW = 0;
+ _fowTileH = 0;
+
+ _fowImage = nullptr;
+ _fowClipX1 = 0;
+ _fowClipY1 = 0;
+ _fowClipX2 = 0;
+ _fowClipY2 = 0;
+
+ _fowDrawX = 0;
+ _fowDrawY = 0;
+
+ _fowVtx1 = 0;
+ _fowVty1 = 0;
+ _fowMvx = 0;
+ _fowMvy = 0;
+ _fowVw = 0;
+ _fowVh = 0;
+
+ _fowBlackMode = true;
+
+ memset(_fowRenderTable, 0, 32768);
+}
+
+void Moonbase::releaseFOWResources() {
+ if (_fowImage) {
+ free(_fowImage);
+ _fowImage = 0;
+ }
+}
+
+bool Moonbase::captureFOWImageFromLocation(void *src) {
+ if (!src)
+ return false;
+
+ int imageDataSize = 0; //getMemoryBlockSize(src); // TODO
+
+ if (imageDataSize <= 0)
+ return false;
+
+ _fowImage = (byte *)malloc(imageDataSize);
+
+ if (!_fowImage)
+ return false;
+
+ memcpy(_fowImage, src, imageDataSize);
+
+ return true;
+}
+
+bool Moonbase::setFOWImage(int image) {
+ releaseFOWResources();
+
+ if (!_fowImage) {
+ Common::String fowImageFilename(ConfMan.get("MOONX_FOWImageFilename").c_str());
+
+#if 0 // TODO
+ if (!fowImageFilename.empty()) {
+ void *wiz = loadWizFromFilename(fowImageFilename);
+
+ if (wiz) {
+ captureFOWImageFromLocation(wiz);
+ free(wiz);
+ }
+ }
+#endif
+
+ if (!_fowImage && image < 0) {
+ int resType;
+
+ // PIECES BUBBLES CIRCLES SIMPLE* WEDGEY BUBBLE2
+ // WEDGE2 SPIKEY ANGLES SMOOTHED WUZZY SYS7-BEVELED
+ if (image >= -1 && image <= 12)
+ resType = 210 - image; // 211-222 range
+ else
+ resType = 214; // default, SIMPLE
+#if 0 // TODO
+ HRSRC hResource = FindResource(g_hInst, resType, 10);
+ if (hResource) {
+ byte res = LoadResource(g_hInst, hResource);
+
+ if (res) {
+ uint16 nDataSize = SizeofResource(g_hInst, hResource);
+
+ if (nDataSize)
+ captureFOWImageFromLocation(res);
+ }
+ }
+#endif
+ }
+
+ if (!_fowImage && image > 0) {
+ void *glob = _vm->getResourceAddress(rtImage, image);
+
+ if (glob)
+ captureFOWImageFromLocation(glob);
+ }
+
+ if (!_fowImage)
+ return false;
+ }
+
+ int nStates = _vm->_wiz->getWizImageStates(_fowImage);
+
+ if (nStates > FOW_ANIM_FRAME_COUNT) {
+ releaseFOWResources();
+ return false;
+ }
+
+ _fowAnimationFrames = (nStates + FOW_ANIM_FRAME_COUNT - 1) / FOW_ANIM_FRAME_COUNT;
+
+ Common::Point fowTileSize(0, 0); //getWizStateSize(_fowImage, (nStates - 1)); // TODO
+
+ _fowTileW = fowTileSize.x;
+ _fowTileH = fowTileSize.y;
+
+ int hitTestValue = 0;
+ uint pixelValue = 0;
+
+ //LayeredWizHitTest(&hitTestValue, &pixelValue, _fowImage, (nStates - 1), 0, 0, 0, 0); // TODO
+ _fowBlackMode = (pixelValue == 0) ? 1 : 0;
+
+ if (ConfMan.hasKey("EnableFOWRects"))
+ _fowBlackMode = (ConfMan.getInt("EnableFOWRects") == 1);
+
+ return true;
+}
+
+enum FOWElement {
+ FOW_EMPTY = 0,
+ FOW_SOLID = 1,
+
+ FF_L = 0x01,
+ FF_R = 0x02,
+ FF_T = 0x04,
+ FF_B = 0x08,
+ FF_T_L = 0x10,
+ FF_T_R = 0x20,
+ FF_B_L = 0x40,
+ FF_B_R = 0x80,
+ FF_Q_A = (FF_L | FF_T | FF_T_L),
+ FF_Q_B = (FF_R | FF_T | FF_T_R),
+ FF_Q_C = (FF_L | FF_B | FF_B_L),
+ FF_Q_D = (FF_R | FF_B | FF_B_R)
+};
+
+int Moonbase::readFOWVisibilityArray(int array, int y, int x) {
+ //_vm->VAR(_vm->VAR_U32_ARRAY_UNK) = array; // TODO
+
+ if (_vm->readArray(116, y, x) > 0)
+ return FOW_EMPTY;
+
+ return FOW_SOLID;
+}
+
+void Moonbase::setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int viewX, int viewY, int clipX1,
+ int clipY1, int clipX2, int clipY2, int technique, int nFrame) {
+ if (!_fowImage)
+ return;
+
+ _fowDrawX = clipX1;
+ _fowDrawY = clipY1;
+
+ _fowClipX1 = clipX1;
+ _fowClipY1 = clipY1;
+ _fowClipX2 = clipX2;
+ _fowClipY2 = clipY2;
+
+ // Figure out the number of tiles are involved
+ int view_W = (clipX2 - clipX1) + 1;
+ int view_H = (clipY2 - clipY1) + 1;
+
+ int tw = _fowTileW;
+ int th = _fowTileH;
+
+ int dw = acrossDim;
+ int dh = downDim;
+
+ int dlw = dw * tw;
+ int dlh = dh * th;
+
+ _fowMvx = (0 <= viewX) ? (viewX % dlw) : (dlw - (-viewX % dlw));
+ _fowMvy = (0 <= viewY) ? (viewY % dlh) : (dlh - (-viewY % dlh));
+
+ _fowVtx1 = _fowMvx / tw;
+ _fowVty1 = _fowMvy / th;
+
+ _fowVw = (((_fowMvx + view_W + tw - 1) / tw) - _fowVtx1) + 1;
+ _fowVh = (((_fowMvy + view_H + th - 1) / th) - _fowVty1) + 1;
+
+ // Build the connectivity table
+ int t = (_fowVty1 - 1); if (t >= dh) { t = 0; } else if (t < 0) { t = (dh - 1); }
+ int m = (_fowVty1 + 0); if (m >= dh) { m = 0; } else if (m < 0) { m = (dh - 1); }
+ int b = (_fowVty1 + 1); if (b >= dh) { b = 0; } else if (b < 0) { b = (dh - 1); }
+
+ int il = (_fowVtx1 - 1); if (il >= dh) { il = 0; } else if (il < 0) { il = (dw - 1); }
+ int ic = (_fowVtx1 + 0); if (ic >= dh) { ic = 0; } else if (ic < 0) { ic = (dw - 1); }
+ int ir = (_fowVtx1 + 1); if (ir >= dh) { ir = 0; } else if (ir < 0) { ir = (dw - 1); }
+
+ int dataOffset = (_fowVw * 3);
+ int dataOffset2 = (dataOffset * 2);
+ int *pOutterRenderTableA = _fowRenderTable;
+ int *pOutterRenderTableB = pOutterRenderTableA + dataOffset;
+
+ for (int ay = 0; ay < _fowVh; ay++) {
+ int l = il;
+ int c = ic;
+ int r = ir;
+
+ int *pRenderTableA = pOutterRenderTableA;
+ int *pRenderTableB = pOutterRenderTableB;
+
+ pOutterRenderTableA += dataOffset2;
+ pOutterRenderTableB += dataOffset2;
+
+ for (int ax = 0; ax < _fowVw; ax++) {
+ int visibility = readFOWVisibilityArray(fowInfoArray, m, c);
+
+ if (visibility == FOW_EMPTY) {
+ int bits = 0;
+
+ if (readFOWVisibilityArray(fowInfoArray, t, l) != 0) bits |= FF_T_L;
+ if (readFOWVisibilityArray(fowInfoArray, t, c) != 0) bits |= FF_T;
+ if (readFOWVisibilityArray(fowInfoArray, t, r) != 0) bits |= FF_T_R;
+ if (readFOWVisibilityArray(fowInfoArray, m, l) != 0) bits |= FF_L;
+ if (readFOWVisibilityArray(fowInfoArray, m, r) != 0) bits |= FF_R;
+ if (readFOWVisibilityArray(fowInfoArray, b, l) != 0) bits |= FF_B_L;
+ if (readFOWVisibilityArray(fowInfoArray, b, c) != 0) bits |= FF_B;
+ if (readFOWVisibilityArray(fowInfoArray, b, r) != 0) bits |= FF_B_R;
+
+ if (bits) {
+ *pRenderTableA++ = 1;
+ *pRenderTableB++ = 1;
+
+ // Quadrant (A)
+ if (bits & FF_Q_A) {
+ *pRenderTableA++ = (
+ ((FF_L & bits) ? 1 : 0) |
+ ((FF_T & bits) ? 2 : 0) |
+ ((FF_T_L & bits) ? 4 : 0)
+ ) + 0;
+ } else {
+ *pRenderTableA++ = 0;
+ }
+
+ // Quadrant (B)
+ if (bits & FF_Q_B) {
+ *pRenderTableA++ = (
+ ((FF_R & bits) ? 1 : 0) |
+ ((FF_T & bits) ? 2 : 0) |
+ ((FF_T_R & bits) ? 4 : 0)
+ ) + 8;
+ } else {
+ *pRenderTableA++ = 0;
+ }
+
+ // Quadrant (C)
+ if (bits & FF_Q_C) {
+ *pRenderTableB++ = (
+ ((FF_L & bits) ? 1 : 0) |
+ ((FF_B & bits) ? 2 : 0) |
+ ((FF_B_L & bits) ? 4 : 0)
+ ) + 16;
+ } else {
+ *pRenderTableB++ = 0;
+ }
+
+ // Quadrant (D)
+ if (bits & FF_Q_D) {
+ *pRenderTableB++ = (
+ ((FF_R & bits) ? 1 : 0) |
+ ((FF_B & bits) ? 2 : 0) |
+ ((FF_B_R & bits) ? 4 : 0)
+ ) + 24;
+ } else {
+ *pRenderTableB++ = 0;
+ }
+ } else {
+ *pRenderTableA++ = 0;
+ *pRenderTableB++ = 0;
+ }
+ } else {
+ if (_fowBlackMode) {
+ *pRenderTableA++ = 2;
+ *pRenderTableB++ = 2;
+ } else {
+ *pRenderTableA++ = 1;
+ *pRenderTableA++ = 33;
+ *pRenderTableA++ = 34;
+
+ *pRenderTableB++ = 1;
+ *pRenderTableB++ = 35;
+ *pRenderTableB++ = 36;
+ }
+ }
+
+ if (++l >= dw) { l = 0; }
+ if (++c >= dw) { c = 0; }
+ if (++r >= dw) { r = 0; }
+ }
+
+ if (++t >= dh) { t = 0; }
+ if (++m >= dh) { m = 0; }
+ if (++b >= dh) { b = 0; }
+ }
+
+ _fowCurrentFOWFrame = (nFrame >= 0) ? (nFrame % _fowAnimationFrames) : ((-nFrame) % _fowAnimationFrames);
+ _fowFrameBaseNumber = (_fowCurrentFOWFrame * FOW_ANIM_FRAME_COUNT);
+}
+
+void Moonbase::renderFOWState(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int x, int y, int srcw, int srch, int state, int flags) {
+ int spotx, spoty;
+
+ _vm->_wiz->getWizStateSpot(_fowImage, state, &spotx, &spoty);
+ Common::Rect r(_fowClipX1, _fowClipY1, _fowClipX2, _fowClipY2);
+
+ _vm->_wiz->drawWizImageEx(destSurface, _fowImage, 0, dstPitch, dstType, dstw, dsth, x - spotx, y - spoty, srcw, srch, state, &r, flags, 0, 0, 16, 0, 0);
+}
+
+static void blackRect_16bpp(uint8 *destSurface, int x1, int y1, int x2, int y2) {
+ // TODO
+}
+
+void Moonbase::renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int flags) {
+ if (!_fowImage)
+ return;
+
+ const int *pOutterRenderTable = _fowRenderTable;
+ int ixPos = ((_fowVtx1 * _fowTileW) - _fowMvx) + _fowDrawX;
+ int yPos = ((_fowVty1 * _fowTileH) - _fowMvy) + _fowDrawY;
+ int dataOffset = _fowVw * 3;
+ int halfTileHeight = _fowTileH / 2;
+ int cx2 = MIN(_fowClipX2, (dstw - 1));
+ int cy2 = MIN(_fowClipY2, (dsth - 1));
+
+ for (int ry = 0; ry < _fowVh; ry++) {
+ int real_yPos = yPos;
+
+ for (int i = 0; i < 2; i++) {
+ const int *pRenderTable = pOutterRenderTable;
+ pOutterRenderTable += dataOffset;
+
+ int xPos = ixPos;
+
+ for (int rx = 0; rx < _fowVw; rx++) {
+ int nState = *pRenderTable++;
+
+ if (nState != 0) {
+ if (nState == 2) {
+ int countLeft = (_fowVw - rx);
+ int count = 0;
+
+ for (; count < countLeft; count++) {
+ if (*(pRenderTable + count) != 2)
+ break;
+
+ pRenderTable++;
+ rx++;
+ }
+ count++;
+
+ int x1 = xPos;
+ int y1 = real_yPos;
+
+ xPos += _fowTileW * count;
+ int x2 = (xPos - 1);
+ int y2 = ((y1 + halfTileHeight) - 1);
+
+ x1 = MAX(0, x1);
+ y1 = MAX(0, y1);
+ x2 = MIN(x2, cx2);
+ y2 = MIN(y2, cy2);
+
+ if ((x2 >= x1) && (y2 >= y1) && (x1 <= _fowClipX2) && (y1 <= _fowClipY2))
+ blackRect_16bpp(destSurface, x1, y1, x2, y2);
+ } else {
+ int subState;
+
+ if ((subState = *pRenderTable++) != 0)
+ renderFOWState(destSurface, dstPitch, dstType, dstw, dsth, xPos, yPos, _fowTileW, _fowTileH, (subState + _fowFrameBaseNumber), flags);
+
+ if ((subState = *pRenderTable++) != 0)
+ renderFOWState(destSurface, dstPitch, dstType, dstw, dsth, xPos, yPos, _fowTileW, _fowTileH, (subState + _fowFrameBaseNumber), flags);
+
+ xPos += _fowTileW;
+ }
+ } else {
+ xPos += _fowTileW;
+ }
+ }
+ real_yPos += halfTileHeight;
+ }
+ yPos += _fowTileH;
+ }
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index afc6633ef6..7d56138247 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -1310,36 +1310,36 @@ void ScummEngine_v100he::o100_wizImageOps() {
if (_wizParams.img.resNum)
_wiz->processWizImage(&_wizParams);
break;
- case 128:
- _wizParams.field_239D = pop();
- _wizParams.field_2399 = pop();
- _wizParams.field_23A5 = pop();
- _wizParams.field_23A1 = pop();
- copyScriptString(_wizParams.string2, sizeof(_wizParams.string2));
+ case 128: // Font create
_wizParams.processMode = 15;
+ _wizParams.fontProperties.bgColor = pop();
+ _wizParams.fontProperties.fgColor = pop();
+ _wizParams.fontProperties.size = pop();
+ _wizParams.fontProperties.style = pop();
+ copyScriptString(_wizParams.fontProperties.fontName, sizeof(_wizParams.fontProperties.fontName));
break;
case 129:
_wizParams.processMode = 14;
break;
- case 130:
+ case 130: // Font render
_wizParams.processMode = 16;
- _wizParams.field_23AD = pop();
- _wizParams.field_23A9 = pop();
- copyScriptString(_wizParams.string1, sizeof(_wizParams.string1));
+ _wizParams.fontProperties.yPos = pop();
+ _wizParams.fontProperties.xPos = pop();
+ copyScriptString(_wizParams.fontProperties.string, sizeof(_wizParams.fontProperties.string));
break;
case 131:
_wizParams.processMode = 13;
break;
- case 133:
+ case 133: // Render ellipse
_wizParams.processMode = 17;
- _wizParams.field_23CD = pop();
- _wizParams.field_23C9 = pop();
- _wizParams.field_23C5 = pop();
- _wizParams.field_23C1 = pop();
- _wizParams.field_23BD = pop();
- _wizParams.field_23B9 = pop();
- _wizParams.field_23B5 = pop();
- _wizParams.field_23B1 = pop();
+ _wizParams.ellipseProperties.color = pop();
+ _wizParams.ellipseProperties.lod = pop();
+ _wizParams.ellipseProperties.ky = pop();
+ _wizParams.ellipseProperties.kx = pop();
+ _wizParams.ellipseProperties.qy = pop();
+ _wizParams.ellipseProperties.qx = pop();
+ _wizParams.ellipseProperties.py = pop();
+ _wizParams.ellipseProperties.px = pop();
break;
case 134:
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
@@ -1997,6 +1997,7 @@ void ScummEngine_v100he::o100_setSpriteInfo() {
_sprite->setSpriteFlagRemapPalette(spriteId, args[0]);
break;
default:
+ warning("Unknown sprite property %d for sprite %d", args[0], spriteId);
break;
}
break;
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index f65d2f6077..f2d92bc2ca 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -285,29 +285,29 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.processMode = 13;
break;
case 142: // HE99+
- _wizParams.field_239D = pop();
- _wizParams.field_2399 = pop();
- _wizParams.field_23A5 = pop();
- _wizParams.field_23A1 = pop();
- copyScriptString(_wizParams.string2, sizeof(_wizParams.string2));
_wizParams.processMode = 15;
+ _wizParams.fontProperties.bgColor = pop();
+ _wizParams.fontProperties.fgColor = pop();
+ _wizParams.fontProperties.size = pop();
+ _wizParams.fontProperties.style = pop();
+ copyScriptString(_wizParams.fontProperties.fontName, sizeof(_wizParams.fontProperties.fontName));
break;
case 143: // HE99+
_wizParams.processMode = 16;
- _wizParams.field_23AD = pop();
- _wizParams.field_23A9 = pop();
- copyScriptString(_wizParams.string1, sizeof(_wizParams.string1));
+ _wizParams.fontProperties.yPos = pop();
+ _wizParams.fontProperties.xPos = pop();
+ copyScriptString(_wizParams.fontProperties.string, sizeof(_wizParams.fontProperties.string));
break;
case 189: // HE99+
_wizParams.processMode = 17;
- _wizParams.field_23CD = pop();
- _wizParams.field_23C9 = pop();
- _wizParams.field_23C5 = pop();
- _wizParams.field_23C1 = pop();
- _wizParams.field_23BD = pop();
- _wizParams.field_23B9 = pop();
- _wizParams.field_23B5 = pop();
- _wizParams.field_23B1 = pop();
+ _wizParams.ellipseProperties.color = pop();
+ _wizParams.ellipseProperties.lod = pop();
+ _wizParams.ellipseProperties.ky = pop();
+ _wizParams.ellipseProperties.kx = pop();
+ _wizParams.ellipseProperties.qy = pop();
+ _wizParams.ellipseProperties.qx = pop();
+ _wizParams.ellipseProperties.py = pop();
+ _wizParams.ellipseProperties.px = pop();
break;
case 196: // HE99+
_wizParams.processMode = 14;
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index 9a456b86c0..2e0a03af7f 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -470,6 +470,10 @@ void SoundHE::processSoundOpcodes(int sound, byte *codePtr, int *soundVars) {
if (arg == 2) {
val = getSoundVar(sound, val);
}
+ if (!val) {
+ val = 1; // Safeguard for division by zero
+ warning("Incorrect value 0 for processSoundOpcodes() kludge DIV");
+ }
val = getSoundVar(sound, var) / val;
setSoundVar(sound, var, val);
break;
diff --git a/engines/scumm/he/sprite_he.cpp b/engines/scumm/he/sprite_he.cpp
index 245a986531..b192fab233 100644
--- a/engines/scumm/he/sprite_he.cpp
+++ b/engines/scumm/he/sprite_he.cpp
@@ -386,7 +386,7 @@ int Sprite::getSpriteGeneralProperty(int spriteId, int type) {
case 0x7B:
return _spriteTable[spriteId].imgFlags;
case 0x7D:
- return _spriteTable[spriteId].field_90;
+ return _spriteTable[spriteId].conditionBits;
case 0x7E:
return _spriteTable[spriteId].animProgress;
default:
@@ -746,7 +746,7 @@ void Sprite::setSpriteField84(int spriteId, int value) {
}
void Sprite::setSpriteGeneralProperty(int spriteId, int type, int value) {
- debug(0, "setSpriteGeneralProperty: spriteId %d type 0x%x", spriteId, type);
+ debug(0, "setSpriteGeneralProperty: spriteId %d type 0x%x value 0x%x", spriteId, type, value);
assertRange(1, spriteId, _varNumSprites, "sprite");
int32 delay;
@@ -758,7 +758,7 @@ void Sprite::setSpriteGeneralProperty(int spriteId, int type, int value) {
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
break;
case 0x7D:
- _spriteTable[spriteId].field_90 = value;
+ _spriteTable[spriteId].conditionBits = value;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
break;
case 0x7E:
@@ -799,7 +799,7 @@ void Sprite::resetSprite(int spriteId) {
_spriteTable[spriteId].priority = 0;
_spriteTable[spriteId].field_84 = 0;
_spriteTable[spriteId].imgFlags = 0;
- _spriteTable[spriteId].field_90 = 0;
+ _spriteTable[spriteId].conditionBits = 0;
if (_vm->_game.heversion >= 100) {
_spriteTable[spriteId].flags &= ~kSFMarkDirty;
@@ -1292,7 +1292,7 @@ void Sprite::processImages(bool arg) {
wiz.spriteId = spi->id;
wiz.spriteGroup = spi->group;
- wiz.field_23EA = spi->field_90;
+ wiz.conditionBits = spi->conditionBits;
spi->curImageState = wiz.img.state = imageState;
spi->curImage = wiz.img.resNum = image;
wiz.processFlags = kWPFNewState | kWPFSetPos;
@@ -1341,7 +1341,7 @@ void Sprite::processImages(bool arg) {
wiz.img.flags |= kWIFRemapPalette;
if (spi->field_84) {
wiz.processFlags |= 0x200000;
- wiz.img.field_390 = spi->field_84;
+ wiz.img.zbuffer = spi->field_84;
wiz.img.zorder = spi->priority;
}
if (spi->sourceImage) {
@@ -1426,7 +1426,7 @@ void Sprite::saveOrLoadSpriteData(Serializer *s) {
MKLINE(SpriteInfo, field_84, sleInt32, VER(48)),
MKLINE(SpriteInfo, classFlags, sleInt32, VER(48)),
MKLINE(SpriteInfo, imgFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, field_90, sleInt32, VER(48)),
+ MKLINE(SpriteInfo, conditionBits, sleInt32, VER(48)),
MKEND()
};
diff --git a/engines/scumm/he/sprite_he.h b/engines/scumm/he/sprite_he.h
index e31ccbf790..b1a7641fcc 100644
--- a/engines/scumm/he/sprite_he.h
+++ b/engines/scumm/he/sprite_he.h
@@ -79,7 +79,7 @@ struct SpriteInfo {
int32 field_84;
int32 classFlags;
int32 imgFlags;
- int32 field_90;
+ int32 conditionBits;
};
struct SpriteGroup {
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index 9a59609651..9a5be1cc5f 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -1422,19 +1422,19 @@ void Wiz::displayWizImage(WizImage *pwi) {
wi->state = pwi->state;
wi->flags = pwi->flags;
wi->shadow = 0;
- wi->field_390 = 0;
+ wi->zbuffer = 0;
wi->palette = 0;
++_imagesNum;
} else if (pwi->flags & kWIFIsPolygon) {
drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, 0, 0, 0);
} else {
const Common::Rect *r = NULL;
- drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, _vm->getHEPaletteSlot(0));
+ drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, _vm->getHEPaletteSlot(0), 0);
}
}
-uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr) {
- debug(3, "drawWizImage(resNum %d, state %d maskNum %d maskState %d x1 %d y1 %d flags 0x%X zorder %d shadow %d field_390 %d dstResNum %d)", resNum, state, maskNum, maskState, x1, y1, flags, zorder, shadow, field_390, dstResNum);
+uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int zbuffer, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr, uint32 conditionBits) {
+ debug(3, "drawWizImage(resNum %d, state %d maskNum %d maskState %d x1 %d y1 %d flags 0x%X zorder %d shadow %d zbuffer %d dstResNum %d conditionBits: 0x%x)", resNum, state, maskNum, maskState, x1, y1, flags, zorder, shadow, zbuffer, dstResNum, conditionBits);
uint8 *dataPtr;
uint8 *dst = NULL;
@@ -1456,9 +1456,6 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
uint32 height = READ_LE_UINT32(wizh + 0x8);
debug(3, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d", comp, width, height);
- uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
- assert(wizd);
-
uint8 *mask = NULL;
if (maskNum) {
uint8 *maskPtr = _vm->getResourceAddress(rtImage, maskNum);
@@ -1574,58 +1571,251 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
transColor = (trns == NULL) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : -1;
}
+ drawWizImageEx(dst, dataPtr, mask, dstPitch, dstType, cw, ch, x1, y1, width, height,
+ state, &rScreen, flags, palPtr, transColor, _vm->_bytesPerPixel, xmapPtr, conditionBits);
+
+ if (!(flags & kWIFBlitToMemBuffer) && dstResNum == 0) {
+ Common::Rect rImage(x1, y1, x1 + width, y1 + height);
+ if (rImage.intersects(rScreen)) {
+ rImage.clip(rScreen);
+ if (!(flags & kWIFBlitToFrontVideoBuffer) && (flags & (kWIFBlitToFrontVideoBuffer | kWIFMarkBufferDirty))) {
+ ++rImage.bottom;
+ _vm->markRectAsDirty(kMainVirtScreen, rImage);
+ } else {
+ _vm->restoreBackgroundHE(rImage);
+ }
+ }
+ }
+
+ return dst;
+}
+
+void Wiz::drawWizImageEx(uint8 *dst, uint8 *dataPtr, uint8 *maskPtr, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *rect,
+ int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits) {
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
+ assert(wizh);
+ uint32 comp = READ_LE_UINT32(wizh + 0x0);
+ uint32 width = READ_LE_UINT32(wizh + 0x4);
+ uint32 height = READ_LE_UINT32(wizh + 0x8);
+ debug(3, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d", comp, width, height);
+
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
+ assert(wizd);
+
switch (comp) {
case 0:
- copyRawWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor, _vm->_bytesPerPixel);
+ copyRawWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, palPtr, transColor, bitDepth);
break;
case 1:
- if (flags & 0x80) {
+ if (flags & kWIFZPlaneOn) {
dst = _vm->getMaskBuffer(0, 0, 1);
dstPitch /= _vm->_bytesPerPixel;
- copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 2);
- } else if (flags & 0x100) {
+ copyWizImageWithMask(dst, wizd, dstPitch, dstw, dsth, srcx, srcy, srcw, srch, rect, 0, 2);
+ } else if (flags & kWIFZPlaneOff) {
dst = _vm->getMaskBuffer(0, 0, 1);
dstPitch /= _vm->_bytesPerPixel;
- copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 1);
+ copyWizImageWithMask(dst, wizd, dstPitch, dstw, dsth, srcx, srcy, srcw, srch, rect, 0, 1);
} else {
- copyWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr, _vm->_bytesPerPixel);
+ copyWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, palPtr, xmapPtr, bitDepth);
}
break;
#ifdef USE_RGB_COLOR
case 2:
- if (maskNum) {
- copyMaskWizImage(dst, wizd, mask, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr);
+ if (maskPtr) {
+ copyMaskWizImage(dst, wizd, maskPtr, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, palPtr);
} else {
- copyRaw16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, transColor);
+ copyRaw16BitWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, transColor);
}
break;
case 4:
- // TODO: Unknown image type
+ copyCompositeWizImage(dst, dataPtr, wizd, maskPtr, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, state, rect, flags, palPtr, transColor, bitDepth, xmapPtr, conditionBits);
break;
case 5:
- copy16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, xmapPtr);
+ copy16BitWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, xmapPtr);
+ break;
+ case 9:
+ copy555WizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, rect, conditionBits);
break;
#endif
default:
- error("drawWizImage: Unhandled wiz compression type %d", comp);
+ error("drawWizImageEx: Unhandled wiz compression type %d", comp);
}
+}
- if (!(flags & kWIFBlitToMemBuffer) && dstResNum == 0) {
- Common::Rect rImage(x1, y1, x1 + width, y1 + height);
- if (rImage.intersects(rScreen)) {
- rImage.clip(rScreen);
- if (!(flags & kWIFBlitToFrontVideoBuffer) && (flags & (kWIFBlitToFrontVideoBuffer | kWIFMarkBufferDirty))) {
- ++rImage.bottom;
- _vm->markRectAsDirty(kMainVirtScreen, rImage);
- } else {
- _vm->restoreBackgroundHE(rImage);
+#ifdef USE_RGB_COLOR
+
+void Wiz::copyCompositeWizImage(uint8 *dst, uint8 *wizPtr, uint8 *compositeInfoBlockPtr, uint8 *maskPtr, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *clipBox,
+ int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits) {
+
+ uint8 *nestedBlockHeader = _vm->heFindResource(MKTAG('N','E','S','T'), wizPtr);
+ assert(nestedBlockHeader);
+
+ uint8 *nestedWizHeader = _vm->heFindResource(MKTAG('M','U','L','T'), nestedBlockHeader);
+ assert(nestedWizHeader);
+
+ uint16 layerCount = READ_LE_UINT16(compositeInfoBlockPtr);
+ compositeInfoBlockPtr += 2;
+
+ uint16 defaultSubConditionBits = (conditionBits & kWMSBReservedBits);
+
+ conditionBits &= ~kWMSBReservedBits;
+
+ for (uint layerCounter = 0; layerCounter < layerCount; layerCounter++) {
+ int cmdSize = READ_LE_UINT16(compositeInfoBlockPtr);
+ uint8 *cmdPtr = compositeInfoBlockPtr + 2;
+
+ compositeInfoBlockPtr += (cmdSize + 2);
+ uint32 layerCmdDataBits = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+
+ uint32 subConditionBits;
+
+ if (layerCmdDataBits & kWCFConditionBits) {
+ uint32 layerConditionBits = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+
+ subConditionBits = (layerConditionBits & kWMSBReservedBits);
+ layerConditionBits &= ~kWMSBReservedBits;
+
+ if (subConditionBits == 0)
+ subConditionBits = defaultSubConditionBits;
+
+ uint32 conditionType = (layerConditionBits & kWSPCCTBits);
+ layerConditionBits &= ~kWSPCCTBits;
+
+ switch (conditionType) {
+ case kWSPCCTAnd:
+ if (layerConditionBits != (layerConditionBits & conditionBits))
+ continue;
+ break;
+
+ case kWSPCCTNot:
+ if (layerConditionBits & conditionBits)
+ continue;
+ break;
+
+ case kWSPCCTOr:
+ default:
+ if (!(layerConditionBits & conditionBits))
+ continue;
+ break;
}
+ } else {
+ subConditionBits = defaultSubConditionBits;
+ }
+
+ uint16 subState;
+ if (layerCmdDataBits & kWCFSubState) {
+ subState = READ_LE_UINT16(cmdPtr);
+ cmdPtr += 2;
+ } else {
+ subState = 0;
+ }
+
+ int16 xPos;
+ if (layerCmdDataBits & kWCFXDelta) {
+ xPos = (int16)READ_LE_UINT16(cmdPtr);
+ cmdPtr += 2;
+ } else {
+ xPos = 0;
}
+
+ int16 yPos;
+ if (layerCmdDataBits & kWCFYDelta) {
+ yPos = (int16)READ_LE_UINT16(cmdPtr);
+ cmdPtr += 2;
+ } else {
+ yPos = 0;
+ }
+
+ uint32 drawFlags;
+ if (layerCmdDataBits & kWCFDrawFlags) {
+ drawFlags = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+ } else {
+ drawFlags = flags;
+ }
+
+ uint srcw1, srch1;
+ if (drawFlags & (kWIFFlipX | kWIFFlipY)) {
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), wizPtr, subState, 0);
+ assert(wizh);
+ srcw1 = READ_LE_UINT32(wizh + 0x4);
+ srch1 = READ_LE_UINT32(wizh + 0x8);
+ }
+
+ if (drawFlags & kWIFFlipX)
+ xPos = (srcw - (xPos + srcw1));
+
+ if (drawFlags & kWIFFlipY)
+ yPos = (srch - (yPos + srch1));
+
+ if (layerCmdDataBits & kWCFSubConditionBits) {
+ subConditionBits = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+ } else {
+ subConditionBits = 0;
+ }
+
+ drawWizImageEx(dst, nestedWizHeader, maskPtr, dstPitch, dstType, dstw, dsth, srcx + xPos, srcy + yPos, srcw, srch,
+ subState, clipBox, drawFlags, palPtr, transColor, bitDepth, xmapPtr, subConditionBits);
+ }
+}
+
+void Wiz::copy555WizImage(uint8 *dst, uint8 *wizd, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, const Common::Rect *clipBox, uint32 conditionBits) {
+
+ int rawROP = conditionBits & kWMSBRopMask;
+ int paramROP = (conditionBits & kWMSBReservedBits) >> kWMSBRopParamRShift;
+
+ switch (rawROP) {
+ default:
+ case 1:
+ // MMX_PREMUL_ALPHA_COPY
+ break;
+
+ case 2:
+ warning("T14: MMX_ADDITIVE");
+ break;
+
+ case 3:
+ warning("T14: MMX_SUBTRACTIVE");
+ break;
+
+ case 4:
+ warning("T14: MMX_CONSTANT_ALPHA");
+ break;
+
+ case 5:
+ warning("T14: MMX_CHEAP_50_50");
+ break;
+
+ case 6:
+ warning("T14: COPY");
+ break;
+
+ case 7:
+ warning("T14: CHEAP_50_50");
+ break;
+ }
+
+
+ uint32 compID = READ_LE_UINT32(wizd);
+
+ if (compID == 0x12340102) {
+ _vm->_moonbase->blitT14WizImage(dst, dstw, dsth, dstPitch, clipBox, wizd, srcx, srcy, rawROP, paramROP);
+ } else if (compID == 0x12340802) {
+ warning("Distorion codec");
+ } else if (compID == 0x12340902) {
+ error("Unsupported Distortion");
}
- return dst;
}
+#endif
+
struct PolygonDrawData {
struct PolygonArea {
int32 xmin;
@@ -1747,7 +1937,7 @@ void Wiz::captureWizPolygon(int resNum, int maskNum, int maskState, int id1, int
assert(maskNum);
const Common::Rect *r = NULL;
- const uint8 *src = drawWizImage(maskNum, maskState, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0);
+ const uint8 *src = drawWizImage(maskNum, maskState, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0, 0);
getWizImageDim(maskNum, maskState, srcw, srch);
dstw = wp->bound.width();
@@ -1815,7 +2005,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
debug(0, "drawWizPolygonTransform() unhandled flag 0x800000");
}
- srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, flags, 0, _vm->getHEPaletteSlot(palette));
+ srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, flags, 0, _vm->getHEPaletteSlot(palette), 0);
} else {
assert(_vm->_bytesPerPixel == 1);
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
@@ -1826,7 +2016,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
}
} else {
if (getWizImageData(resNum, state, 0) != 0) {
- srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette));
+ srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette), 0);
} else {
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
@@ -2001,7 +2191,7 @@ void Wiz::flushWizBuffer() {
drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, pwi->shadow, 0, pwi->palette);
} else {
const Common::Rect *r = NULL;
- drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->field_390, r, pwi->flags, 0, _vm->getHEPaletteSlot(pwi->palette));
+ drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->zbuffer, r, pwi->flags, 0, _vm->getHEPaletteSlot(pwi->palette), 0);
}
}
_imagesNum = 0;
@@ -2023,7 +2213,7 @@ void Wiz::loadWizCursor(int resId, int palette) {
const Common::Rect *r = NULL;
_cursorImage = true;
- uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette));
+ uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette), 0);
_cursorImage = false;
int32 cw, ch;
@@ -2073,10 +2263,10 @@ void Wiz::displayWizComplexImage(const WizParameters *params) {
if (params->processFlags & kWPFShadow) {
shadow = params->img.shadow;
}
- int field_390 = 0;
- if (params->processFlags & 0x200000) {
- field_390 = params->img.field_390;
- debug(0, "displayWizComplexImage() unhandled flag 0x200000");
+ int zbuffer = 0;
+ if (params->processFlags & kWPFZBuffer) {
+ zbuffer = params->img.zbuffer;
+ debug(0, "displayWizComplexImage() unhandled flag kWPFZBuffer");
}
const Common::Rect *r = NULL;
if (params->processFlags & kWPFClipBox) {
@@ -2104,19 +2294,26 @@ void Wiz::displayWizComplexImage(const WizParameters *params) {
pwi->state = state;
pwi->flags = flags;
pwi->shadow = shadow;
- pwi->field_390 = field_390;
+ pwi->zbuffer = zbuffer;
pwi->palette = palette;
++_imagesNum;
} else {
if (sourceImage != 0) {
- drawWizImage(params->sourceImage, 0, params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette));
+ drawWizImage(params->sourceImage, 0, params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, zbuffer, r, flags, dstResNum, _vm->getHEPaletteSlot(palette), 0);
} else if (params->processFlags & (kWPFScaled | kWPFRotate)) {
drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, shadow, rotationAngle, scale, r, flags, dstResNum, palette);
} else {
if (flags & kWIFIsPolygon) {
drawWizPolygon(params->img.resNum, state, po_x, flags, shadow, dstResNum, palette);
} else {
- drawWizImage(params->img.resNum, state, 0, 0, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette));
+ if (_vm->_game.id == GID_MOONBASE) {
+ if (params->img.resNum == _vm->_moonbase->_fowSentinelImage &&
+ state == _vm->_moonbase->_fowSentinelState &&
+ params->conditionBits == _vm->_moonbase->_fowSentinelConditionBits)
+ _vm->_moonbase->renderFOW(0, 0, 0, 0, 0, flags);
+ }
+
+ drawWizImage(params->img.resNum, state, 0, 0, po_x, po_y, params->img.zorder, shadow, zbuffer, r, flags, dstResNum, _vm->getHEPaletteSlot(palette), params->conditionBits);
}
}
}
@@ -2547,6 +2744,11 @@ int Wiz::getWizImageData(int resNum, int state, int type) {
int Wiz::getWizImageStates(int resNum) {
const uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
+
+ return getWizImageStates(dataPtr);
+}
+
+int Wiz::getWizImageStates(const uint8 *dataPtr) {
if (READ_BE_UINT32(dataPtr) == MKTAG('M','U','L','T')) {
const byte *offs, *wrap;
@@ -2564,6 +2766,18 @@ int Wiz::getWizImageStates(int resNum) {
}
}
+void Wiz::getWizStateSpot(byte *data, int state, int *x, int *y) {
+ byte *spot = _vm->findWrappedBlock(MKTAG('S','P','O','T'), data, state, 0);
+
+ if (!spot) {
+ *x = *y = 0;
+ return;
+ }
+
+ *x = READ_LE_UINT32(spot + 0x0);
+ *y = READ_LE_UINT32(spot + 0x4);
+}
+
int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags) {
int ret = 0;
uint8 *data = _vm->getResourceAddress(rtImage, resNum);
@@ -2597,11 +2811,12 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags
case 2:
ret = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
break;
- case 4:
- // TODO: Unknown image type
- ret = 1;
- debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
+ case 4: {
+ uint16 color = 0xffff;
+ copyCompositeWizImage((byte *)&color, data, wizd, 0, 2, kDstMemory, 1, 1, -x, -y, w, h, state, 0, 0, 0, 0, 2, 0, 0);
+ ret = color != 0xffff;
break;
+ }
case 5:
ret = isWizPixelNonTransparent(wizd, x, y, w, h, 2);
break;
@@ -2641,8 +2856,7 @@ uint16 Wiz::getWizPixelColor(int resNum, int state, int x, int y) {
color = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
break;
case 4:
- // TODO: Unknown image type
- debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c);
+ copyCompositeWizImage((byte *)&color, data, wizd, 0, 2, kDstMemory, 1, 1, -x, -y, w, h, state, 0, 0, 0, 0, 2, 0, 0);
break;
case 5:
color = getWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
diff --git a/engines/scumm/he/wiz_he.h b/engines/scumm/he/wiz_he.h
index 8db438a074..ff5169f7e8 100644
--- a/engines/scumm/he/wiz_he.h
+++ b/engines/scumm/he/wiz_he.h
@@ -43,10 +43,32 @@ struct WizImage {
int state;
int flags;
int shadow;
- int field_390;
+ int zbuffer;
int palette;
};
+struct FontProperties {
+ byte string[4096];
+ byte fontName[4096];
+ int fgColor;
+ int bgColor;
+ int style;
+ int size;
+ int xPos;
+ int yPos;
+};
+
+struct EllipseProperties {
+ int px;
+ int py;
+ int qx;
+ int qy;
+ int kx;
+ int ky;
+ int lod;
+ int color;
+};
+
struct WizParameters {
int field_0;
byte filename[260];
@@ -77,27 +99,13 @@ struct WizParameters {
int remapNum;
int dstResNum;
uint16 fillColor;
- byte string1[4096];
- byte string2[4096];
- int field_2399;
- int field_239D;
- int field_23A1;
- int field_23A5;
- int field_23A9;
- int field_23AD;
- int field_23B1;
- int field_23B5;
- int field_23B9;
- int field_23BD;
- int field_23C1;
- int field_23C5;
- int field_23C9;
- int field_23CD;
+ FontProperties fontProperties;
+ EllipseProperties ellipseProperties;
Common::Rect box2;
- int field_23DE;
+ int blendFlags;
int spriteId;
int spriteGroup;
- int field_23EA;
+ int conditionBits;
WizImage img;
};
@@ -109,6 +117,9 @@ enum WizImageFlags {
kWIFMarkBufferDirty = 0x10,
kWIFBlitToMemBuffer = 0x20,
kWIFIsPolygon = 0x40,
+ kWIFZPlaneOn = 0x80,
+ kWIFZPlaneOff = 0x100,
+ kWIFUseShadow = 0x200,
kWIFFlipX = 0x400,
kWIFFlipY = 0x800
};
@@ -130,7 +141,31 @@ enum WizProcessFlags {
kWPFFillColor = 0x20000,
kWPFClipBox2 = 0x40000,
kWPFMaskImg = 0x80000,
- kWPFParams = 0x100000
+ kWPFParams = 0x100000,
+ kWPFZBuffer = 0x200000
+};
+
+enum WizCompositeFlags {
+ kWCFConditionBits = 0x01,
+ kWCFSubState = 0x02,
+ kWCFXDelta = 0x04,
+ kWCFYDelta = 0x08,
+ kWCFDrawFlags = 0x10,
+ kWCFSubConditionBits = 0x20
+};
+
+enum WizSpcConditionTypes {
+ kWSPCCTBits = 0xc0000000,
+ kWSPCCTOr = 0x00000000,
+ kWSPCCTAnd = 0x40000000,
+ kWSPCCTNot = 0x80000000
+};
+
+enum WizMoonSystemBits {
+ kWMSBRopMask = 0xff,
+ kWMSBRopParamMask = 0xff00,
+ kWMSBReservedBits = (kWMSBRopMask | kWMSBRopParamMask),
+ kWMSBRopParamRShift = 8
};
enum {
@@ -186,6 +221,8 @@ public:
void getWizImageDim(int resNum, int state, int32 &w, int32 &h);
int getWizImageStates(int resnum);
+ int getWizImageStates(const uint8 *ptr);
+ void getWizStateSpot(byte *data, int state, int *x, int *y);
int isWizPixelNonTransparent(int resnum, int state, int x, int y, int flags);
uint16 getWizPixelColor(int resnum, int state, int x, int y);
int getWizImageData(int resNum, int state, int type);
@@ -202,7 +239,8 @@ public:
void displayWizImage(WizImage *pwi);
void processWizImage(const WizParameters *params);
- uint8 *drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr);
+ uint8 *drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int zbuffer, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr, uint32 conditionBits);
+ void drawWizImageEx(uint8 *dst, uint8 *src, uint8 *mask, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits);
void drawWizPolygon(int resNum, int state, int id, int flags, int shadow, int dstResNum, int palette);
void drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int zoom, const Common::Rect *r, int flags, int dstResNum, int palette);
void drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette);
@@ -210,6 +248,12 @@ public:
#ifdef USE_RGB_COLOR
static void copyMaskWizImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr);
+
+ void copyCompositeWizImage(uint8 *dst, uint8 *wizPtr, uint8 *wizd, uint8 *maskPtr, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *clipBox,
+ int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits);
+ void copy555WizImage(uint8 *dst, uint8 *wizd, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, const Common::Rect *clipBox, uint32 conditionBits);
#endif
static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, uint8 bitdepth);
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 416a8f7ef9..c56ef7e5f4 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -136,9 +136,11 @@ MODULE_OBJS += \
he/logic/basketball.o \
he/logic/football.o \
he/logic/funshop.o \
- he/logic/moonbase.o \
+ he/logic/moonbase_logic.o \
he/logic/puttrace.o \
- he/logic/soccer.o
+ he/logic/soccer.o \
+ he/moonbase/moonbase.o \
+ he/moonbase/moonbase_fow.o
endif
# This module can be built as a plugin
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index e986ae4b47..68e4887b00 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 Mon Mar 28 09:52:54 2016
+ This file was generated by the md5table tool on Sat Apr 30 14:24:41 2016
DO NOT EDIT MANUALLY!
*/
@@ -532,6 +532,7 @@ static const MD5Table md5table[] = {
{ "bf8b52fdd9a69c67f34e8e9fec72661c", "farm", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "bfdf584b01503f0762baded581f6a0a2", "SoccerMLS", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", 26159, Common::NL_NLD, Common::kPlatformWindows },
+ { "c0c9de81fb965e6cbe77f6e5631ca705", "monkey", "SE Talkie", "Unofficial SE Talkie v1.02", 9135, Common::EN_ANY, Common::kPlatformDOS },
{ "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD },
{ "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii },
@@ -672,6 +673,7 @@ static const MD5Table md5table[] = {
{ "f3c5d9bf3f091bd1f18dc1013fba5396", "atlantis", "Steam", "Steam", 638976, Common::EN_ANY, Common::kPlatformWindows },
{ "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", "", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows },
{ "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "HE 60", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "f4d20ab4ce19743a646cb48bd93aee72", "monkey2", "SE Talkie", "Unofficial SE Talkie v0.2", 10835, Common::EN_ANY, Common::kPlatformDOS },
{ "f5228b0cc1c19e6ea8268ba2eeb61f60", "freddi", "HE 73", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "f73883f13b5a302749a5bad31d909780", "tentacle", "", "CD", -1, Common::DE_DEU, Common::kPlatformMacintosh },
{ "f7635a0e2ab82c9a0f9ace5f232a488f", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index e7118616ba..ff25dc9201 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -733,7 +733,7 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
VAR_ACTIVE_VERB = 0xFF;
if (strcmp(dr.fp.pattern, "maniacdemo.d64") == 0 )
- _game.features |= GF_DEMO;
+ _game.features |= GF_DEMO;
}
ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr)
@@ -832,9 +832,16 @@ ScummEngine_v71he::ScummEngine_v71he(OSystem *syst, const DetectorResult &dr)
_skipProcessActors = 0;
VAR_WIZ_TCOLOR = 0xFF;
+
+ /* Moonbase stuff */
+ _moonbase = 0;
+
+ if (_game.id == GID_MOONBASE)
+ _moonbase = new Moonbase(this);
}
ScummEngine_v71he::~ScummEngine_v71he() {
+ delete _moonbase;
delete _wiz;
}
diff --git a/engines/sherlock/tattoo/tattoo_fixed_text.h b/engines/sherlock/tattoo/tattoo_fixed_text.h
index 7dbe13bbb3..eb636cdada 100644
--- a/engines/sherlock/tattoo/tattoo_fixed_text.h
+++ b/engines/sherlock/tattoo/tattoo_fixed_text.h
@@ -233,7 +233,7 @@ public:
virtual const Common::String getActionMessage(FixedTextActionId actionId, int messageIndex);
};
-} // End of namespace Scalpel
+} // End of namespace Tattoo
} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_journal.cpp b/engines/sherlock/tattoo/tattoo_journal.cpp
index 8e1a61d36e..4d4f37f8d5 100644
--- a/engines/sherlock/tattoo/tattoo_journal.cpp
+++ b/engines/sherlock/tattoo/tattoo_journal.cpp
@@ -50,7 +50,7 @@ void TattooJournal::show() {
Screen &screen = *_vm->_screen;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
byte palette[PALETTE_SIZE];
-
+
Common::Point oldScroll = screen._currentScroll;
screen._currentScroll = Common::Point(0, 0);
@@ -66,7 +66,7 @@ void TattooJournal::show() {
// Set screen to black, and set background
screen._backBuffer1.SHblitFrom((*_journalImages)[0], Common::Point(0, 0));
- screen.empty();
+ screen.clear();
screen.setPalette(palette);
if (_journal.empty()) {
@@ -87,12 +87,12 @@ void TattooJournal::show() {
handleKeyboardEvents();
highlightJournalControls(true);
-
+
handleButtons();
if (_wait)
events.wait(2);
-
+
} while (!_vm->shouldQuit() && !_exitJournal);
// Clear events
@@ -275,7 +275,7 @@ void TattooJournal::handleButtons() {
if (frameCounter >= _scrollingTimer) {
// Set next scrolling time
_scrollingTimer = frameCounter + 6;
-
+
// Handle different scrolling actions
switch (_selector) {
case JH_SCROLL_LEFT:
@@ -355,13 +355,13 @@ void TattooJournal::handleButtons() {
_savedIndex = _index;
_savedSub = _sub;
_savedPage = _page;
-
+
bool drawResult = drawJournal(dir + 2, 1000 * LINES_PER_PAGE);
if (!drawResult) {
_index = _savedIndex;
_sub = _savedSub;
_page = _savedPage;
-
+
drawFrame();
drawJournal(0, 0);
notFound = true;
@@ -539,7 +539,7 @@ void TattooJournal::drawControls(int mode) {
_oldSelector = 100;
switch (mode) {
- case 0:
+ case 0:
highlightJournalControls(false);
break;
case 1:
@@ -548,7 +548,7 @@ void TattooJournal::drawControls(int mode) {
default:
break;
}
-
+
_oldSelector = savedSelector;
}
@@ -558,7 +558,7 @@ void TattooJournal::highlightJournalControls(bool slamIt) {
Common::Point mousePos = events.mousePos();
Common::Rect r(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, SHERLOCK_SCREEN_HEIGHT - r.height());
-
+
if ((events._pressed || events._released) && _selector == JH_THUMBNAIL) {
if (events._released)
_selector = JH_NONE;
@@ -576,7 +576,7 @@ void TattooJournal::highlightJournalControls(bool slamIt) {
_selector = JH_NONE;
if (bounds.contains(mousePos))
_selector = (mousePos.x - r.left) / (r.width() / 3);
-
+
else if (events._pressed && mousePos.y >= (r.top + screen.fontHeight() + 10)
&& mousePos.y < (r.top + screen.fontHeight() + 10 + BUTTON_SIZE)) {
if (mousePos.x >= r.left && mousePos.x < (r.left + BUTTON_SIZE))
@@ -628,7 +628,7 @@ void TattooJournal::highlightJournalControls(bool slamIt) {
color = (_selector == JH_SAVE) ? COMMAND_HIGHLIGHTED : INFO_TOP;
else
color = INFO_BOTTOM;
- screen.gPrint(Common::Point(xp - screen.stringWidth(FIXED(SaveJournal)) / 2, r.top + 5),
+ screen.gPrint(Common::Point(xp - screen.stringWidth(FIXED(SaveJournal)) / 2, r.top + 5),
color, "%s", FIXED(SaveJournal));
// Draw the horizontal scrollbar
@@ -701,7 +701,7 @@ void TattooJournal::drawScrollBar() {
raised = _selector != JH_SCROLL_LEFT;
screen._backBuffer1.fillRect(Common::Rect(r.left, r.top + screen.fontHeight() + 12, r.left + BUTTON_SIZE,
r.top + screen.fontHeight() + BUTTON_SIZE + 9), INFO_MIDDLE);
- ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.left + 3, r.top + screen.fontHeight() + 10, r.left + 3 + BUTTON_SIZE,
+ ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.left + 3, r.top + screen.fontHeight() + 10, r.left + 3 + BUTTON_SIZE,
r.top + screen.fontHeight() + 10 + BUTTON_SIZE), raised);
color = (_page > 1) ? INFO_BOTTOM + 2 : INFO_BOTTOM;
@@ -716,15 +716,15 @@ void TattooJournal::drawScrollBar() {
// Draw the Scroll Right button
raised = _selector != JH_SCROLL_RIGHT;
- screen._backBuffer1.fillRect(Common::Rect(r.right - BUTTON_SIZE - 1, r.top + screen.fontHeight() + 12,
+ screen._backBuffer1.fillRect(Common::Rect(r.right - BUTTON_SIZE - 1, r.top + screen.fontHeight() + 12,
r.right - 5, r.top + screen.fontHeight() + BUTTON_SIZE + 9), INFO_MIDDLE);
ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.right - BUTTON_SIZE - 3, r.top + screen.fontHeight() + 10, r.right - 3,
r.top + screen.fontHeight() + BUTTON_SIZE + 9), raised);
color = _down ? INFO_BOTTOM + 2 : INFO_BOTTOM;
- screen._backBuffer1.vLine(r.right - 1 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2,
+ screen._backBuffer1.vLine(r.right - 1 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2,
r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2, color);
- screen._backBuffer1.vLine(r.right - 2 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 9 + BUTTON_SIZE / 2,
+ screen._backBuffer1.vLine(r.right - 2 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 9 + BUTTON_SIZE / 2,
r.top + screen.fontHeight() + 11 + BUTTON_SIZE / 2, color);
screen._backBuffer1.vLine(r.right - 3 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 8 + BUTTON_SIZE / 2,
r.top + screen.fontHeight() + 12 + BUTTON_SIZE / 2, color);
@@ -776,14 +776,14 @@ int TattooJournal::getFindName(bool printError) {
drawControls(1);
disableControls();
-
+
// Backup the area under the text entry
Surface bgSurface(r.width() - 6, screen.fontHeight());
- bgSurface.SHblitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(r.left + 3, cursorY,
+ bgSurface.SHblitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(r.left + 3, cursorY,
r.right - 3, cursorY + screen.fontHeight()));
if (printError) {
- screen.gPrint(Common::Point(r.left + (r.width() - screen.stringWidth(FIXED(TextNotFound))) / 2, cursorY),
+ screen.gPrint(Common::Point(r.left + (r.width() - screen.stringWidth(FIXED(TextNotFound))) / 2, cursorY),
INFO_TOP, "%s", FIXED(TextNotFound));
} else {
// If there was a name already entered, copy it to name and display it
@@ -977,7 +977,7 @@ void TattooJournal::saveJournal() {
int line = 0;
// Copy all of the talk files entries into one big string
- do {
+ do {
if (_lines[line].hasPrefix("@")) {
text += Common::String(_lines[line].c_str() + 1);
if ((line + 1) < (int)_lines.size() && _lines[line + 1].hasPrefix("@"))
@@ -992,7 +992,7 @@ void TattooJournal::saveJournal() {
// which show up as a blank line with the next line starting
// with a '@'. We have to add a line break here because the '@' handler
// previously assumes that they're always following a blank line
-
+
if ((_lines[line].empty() || _lines[line] == " ")
&& (line + 1) < (int)_lines.size() && _lines[line + 1].hasPrefix("@"))
text += "\n";
@@ -1005,7 +1005,7 @@ void TattooJournal::saveJournal() {
do {
if (text.size() > 80) {
const char *msgP = text.c_str() + 80;
-
+
if (Common::String(text.c_str(), msgP).contains("\n")) {
// The 80 characters contain a carriage return,
// so we can print out that line
@@ -1013,7 +1013,7 @@ void TattooJournal::saveJournal() {
file->writeString(Common::String(text.c_str(), cr));
text = Common::String(cr + 1);
} else {
- // Move backwards to find a word break
+ // Move backwards to find a word break
while (*msgP != ' ')
--msgP;
diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h
index e0d53c67dd..c844d86e19 100644
--- a/engines/sherlock/tattoo/tattoo_people.h
+++ b/engines/sherlock/tattoo/tattoo_people.h
@@ -273,9 +273,8 @@ public:
virtual void setListenSequence(int speaker, int sequenceNum = 1);
};
-} // End of namespace Scalpel
+} // End of namespace Tattoo
} // End of namespace Sherlock
-
#endif
diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index dfdd765120..9f78234aba 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -324,7 +324,11 @@ void Control::initPanel() {
}
void Control::buttonControl(ConResource *pButton) {
- char autoSave[] = "Restore Autosave";
+ char autoSave[50] = "Restore Autosave";
+
+ if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS)
+ strncpy(autoSave, "Zarpyzit/ abtocoxpahehie", 50);
+
if (pButton == NULL) {
free(_textSprite);
_textSprite = NULL;
@@ -525,8 +529,13 @@ void Control::doControlPanel() {
}
uint16 Control::handleClick(ConResource *pButton) {
- char quitDos[] = "Quit to DOS?";
- char restart[] = "Restart?";
+ char quitDos[50] = "Quit to DOS?";
+ char restart[50] = "Restart?";
+
+ if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) {
+ strncpy(quitDos, "B[uti b DOC?", 50);
+ strncpy(restart, "Hobaq irpa?", 50);
+ }
switch (pButton->_onClick) {
case DO_NOTHING:
@@ -1562,8 +1571,13 @@ void Control::showGameQuitMsg() {
screenData = _skyScreen->giveCurrent();
- _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 0], textBuf1, true, 320, 255);
- _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 1], textBuf2, true, 320, 255);
+ if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) {
+ _skyText->displayText(_quitTexts[8 * 2 + 0], textBuf1, true, 320, 255);
+ _skyText->displayText(_quitTexts[8 * 2 + 1], textBuf2, true, 320, 255);
+ } else {
+ _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 0], textBuf1, true, 320, 255);
+ _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 1], textBuf2, true, 320, 255);
+ }
uint8 *curLine1 = textBuf1 + sizeof(DataFileHeader);
uint8 *curLine2 = textBuf2 + sizeof(DataFileHeader);
uint8 *targetLine = screenData + GAME_SCREEN_WIDTH * 80;
@@ -1584,7 +1598,7 @@ void Control::showGameQuitMsg() {
free(textBuf2);
}
-char Control::_quitTexts[16][35] = {
+char Control::_quitTexts[18][35] = {
"Game over player one",
"BE VIGILANT",
"Das Spiel ist aus.",
@@ -1600,7 +1614,9 @@ char Control::_quitTexts[16][35] = {
"Fim de jogo para o jogador um",
"BE VIGILANT",
"Game over player one",
- "BE VIGILANT"
+ "BE VIGILANT",
+ "Irpa okohseha, irpok 1",
+ "JYD\x96 JDITELEH"
};
uint8 Control::_crossImg[594] = {
diff --git a/engines/sky/control.h b/engines/sky/control.h
index 44591f299d..2089c74363 100644
--- a/engines/sky/control.h
+++ b/engines/sky/control.h
@@ -292,7 +292,7 @@ private:
ControlStatus *_statusBar;
- static char _quitTexts[16][35];
+ static char _quitTexts[18][35];
static uint8 _crossImg[594];
};
diff --git a/engines/sky/skydefs.h b/engines/sky/skydefs.h
index 167b7dade2..ed07a5e2cd 100644
--- a/engines/sky/skydefs.h
+++ b/engines/sky/skydefs.h
@@ -45,6 +45,7 @@ namespace Sky {
#define SKY_ITALIAN 5
#define SKY_PORTUGUESE 6
#define SKY_SPANISH 7
+#define SKY_RUSSIAN 8
#define ST_COLLISION_BIT 5
diff --git a/engines/sword2/screen.cpp b/engines/sword2/screen.cpp
index 0cb951fdfc..40baf67e46 100644
--- a/engines/sword2/screen.cpp
+++ b/engines/sword2/screen.cpp
@@ -1296,7 +1296,7 @@ void Screen::setPsxScrCache(byte *psxScrCache, uint8 level) {
}
byte *Screen::getPsxScrCache(uint8 level) {
- if (level > 3) {
+ if (level > 2) {
level = 0;
}
@@ -1307,7 +1307,7 @@ byte *Screen::getPsxScrCache(uint8 level) {
}
bool Screen::getPsxScrCacheStatus(uint8 level) {
- if (level > 3) {
+ if (level > 2) {
level = 0;
}
diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp
index a678fdccad..5d35a4f47e 100644
--- a/engines/sword25/gfx/image/vectorimage.cpp
+++ b/engines/sword25/gfx/image/vectorimage.cpp
@@ -217,6 +217,7 @@ Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement)
VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, const Common::String &fname) : _pixelData(0), _fname(fname) {
success = false;
+ _bgColor = 0;
// Create bitstream object
// In the following the file data will be readout of the bitstream object.
diff --git a/engines/sword25/gfx/renderobject.cpp b/engines/sword25/gfx/renderobject.cpp
index c109e49aa8..92d39c252d 100644
--- a/engines/sword25/gfx/renderobject.cpp
+++ b/engines/sword25/gfx/renderobject.cpp
@@ -71,19 +71,18 @@ RenderObject::RenderObject(RenderObjectPtr<RenderObject> parentPtr, TYPES type,
_version(++_nextGlobalVersion),
_isSolid(false) {
- // Renderobject registrieren, abhängig vom Handle-Parameter entweder mit beliebigem oder vorgegebenen Handle.
if (handle == 0)
_handle = RenderObjectRegistry::instance().registerObject(this);
else
_handle = RenderObjectRegistry::instance().registerObject(this, handle);
if (_handle == 0)
- return;
+ error("Failed to initialize RenderObject()");
updateAbsolutePos();
- // Dieses Objekt zu den Kindern der Elternobjektes hinzufügen, falls nicht Wurzel (ParentPtr ungültig) und dem
- // selben RenderObjektManager zuweisen.
+ // Add this item to the children of the parent object, if not root (ParentPtr is invalid),
+ // assign to the same RenderObjectManager.
if (_parentPtr.isValid()) {
_managerPtr = _parentPtr->getManager();
_parentPtr->addObject(this->getHandle());
@@ -100,24 +99,22 @@ RenderObject::RenderObject(RenderObjectPtr<RenderObject> parentPtr, TYPES type,
}
RenderObject::~RenderObject() {
- // Objekt aus dem Elternobjekt entfernen.
+ // Remove object from its parent.
if (_parentPtr.isValid())
_parentPtr->detatchChildren(this->getHandle());
deleteAllChildren();
- // Objekt deregistrieren.
RenderObjectRegistry::instance().deregisterObject(this);
}
void RenderObject::preRender(RenderObjectQueue *renderQueue) {
- // Objektänderungen validieren
validateObject();
if (!_visible)
return;
- // Falls notwendig, wird die Renderreihenfolge der Kinderobjekte aktualisiert.
+ // If necessary, update the children rendering order of the updated objects.
if (_childChanged) {
sortRenderObjects();
_childChanged = false;
@@ -149,7 +146,7 @@ bool RenderObject::render(RectangleList *updateRects, const Common::Array<int> &
if (needRender)
doRender(updateRects);
- // Dann müssen die Kinder gezeichnet werden
+ // Draw all children
RENDEROBJECT_ITER it = _children.begin();
for (; it != _children.end(); ++it)
if (!(*it)->render(updateRects, updateRectsMinZ))
@@ -159,7 +156,6 @@ bool RenderObject::render(RectangleList *updateRects, const Common::Array<int> &
}
void RenderObject::validateObject() {
- // Die Veränderungen in den Objektvariablen aufheben
_oldBbox = _bbox;
_oldVisible = _visible;
_oldX = _x;
@@ -169,15 +165,14 @@ void RenderObject::validateObject() {
}
bool RenderObject::updateObjectState() {
- // Falls sich das Objekt verändert hat, muss der interne Zustand neu berechnet werden und evtl. Update-Regions für den nächsten Frame
- // registriert werden.
+ // If the object has changed, the internal state must be recalculated and possibly
+ // update Regions be registered for the next frame.
if ((calcBoundingBox() != _oldBbox) ||
(_visible != _oldVisible) ||
(_x != _oldX) ||
(_y != _oldY) ||
(_z != _oldZ) ||
_refreshForced) {
- // Renderrang des Objektes neu bestimmen, da sich dieser verändert haben könnte
if (_parentPtr.isValid())
_parentPtr->signalChildChange();
@@ -200,12 +195,10 @@ bool RenderObject::updateObjectState() {
}
void RenderObject::updateBoxes() {
- // Bounding-Box aktualisieren
_bbox = calcBoundingBox();
}
Common::Rect RenderObject::calcBoundingBox() const {
- // Die Bounding-Box mit der Objektgröße initialisieren.
Common::Rect bbox(0, 0, _width, _height);
// Die absolute Position der Bounding-Box berechnen.
@@ -247,8 +240,6 @@ int32 RenderObject::calcAbsoluteZ() const {
}
void RenderObject::deleteAllChildren() {
- // Es ist nicht notwendig die Liste zu iterieren, da jedes Kind für sich DetatchChildren an diesem Objekt aufruft und sich somit
- // selber entfernt. Daher muss immer nur ein beliebiges Element (hier das letzte) gelöscht werden, bis die Liste leer ist.
while (!_children.empty()) {
RenderObjectPtr<RenderObject> curPtr = _children.back();
curPtr.erase();
@@ -261,10 +252,10 @@ bool RenderObject::addObject(RenderObjectPtr<RenderObject> pObject) {
return false;
}
- // Objekt in die Kinderliste einfügen.
+ // Insert Object in the children list.
_children.push_back(pObject);
- // Sicherstellen, dass vor dem nächsten Rendern die Renderreihenfolge aktualisiert wird.
+ // Make sure that before the next render the channel order is updated.
if (_parentPtr.isValid())
_parentPtr->signalChildChange();
diff --git a/engines/teenagent/music.cpp b/engines/teenagent/music.cpp
index 5d66c3c90c..795b8f7312 100644
--- a/engines/teenagent/music.cpp
+++ b/engines/teenagent/music.cpp
@@ -36,7 +36,7 @@ static const uint32 noteToPeriod[3][12] = {
{214, 201, 189, 179, 170, 160, 151, 143, 135, 127, 120, 113}
};
-MusicPlayer::MusicPlayer(TeenAgentEngine *vm) : Paula(false, 44100, 5000), _vm(vm), _id(0) {
+MusicPlayer::MusicPlayer(TeenAgentEngine *vm) : Paula(false, 44100, 5000), _vm(vm), _id(0), _currRow(0) {
}
MusicPlayer::~MusicPlayer() {
@@ -55,7 +55,7 @@ bool MusicPlayer::load(int id) {
Common::StackLock lock(_mutex);
// Load the samples
- sampleCount = stream->readByte();
+ byte sampleCount = stream->readByte();
debugC(0, kDebugMusic, "sampleCount = %d", sampleCount);
diff --git a/engines/teenagent/music.h b/engines/teenagent/music.h
index e1630cc845..4b1b683a30 100644
--- a/engines/teenagent/music.h
+++ b/engines/teenagent/music.h
@@ -74,7 +74,6 @@ private:
size = 0;
}
} _samples[256];
- byte sampleCount;
Common::Array<Row> _rows;
uint _currRow;
diff --git a/engines/teenagent/objects.h b/engines/teenagent/objects.h
index f923ae52ab..1f8a82a66e 100644
--- a/engines/teenagent/objects.h
+++ b/engines/teenagent/objects.h
@@ -165,7 +165,7 @@ struct Object {
//19
Common::String name, description;
- Object(): _base(NULL) {}
+ Object(): _base(NULL) { id = 0; actorOrientation = 0; enabled = 0; }
void dump(int level = 0) const;
void setName(const Common::String &newName);
void load(byte *addr);
@@ -205,7 +205,7 @@ struct Walkbox {
Rect rect;
byte sideHint[4];
- Walkbox() : _base(NULL) {}
+ Walkbox() : _base(NULL) { memset(this, 0, sizeof(Walkbox)); }
void dump(int level = 0) const;
void load(byte *src);
void save() const;
diff --git a/engines/teenagent/scene.cpp b/engines/teenagent/scene.cpp
index 6e1cef31bc..c250269844 100644
--- a/engines/teenagent/scene.cpp
+++ b/engines/teenagent/scene.cpp
@@ -71,6 +71,9 @@ Scene::Scene(TeenAgentEngine *vm) : _vm(vm), intro(false), _id(0), ons(0),
varia.close();
loadObjectData();
+
+ _onsCount = 0;
+ _messageColor = 0;
}
Scene::~Scene() {
@@ -314,7 +317,7 @@ void Scene::loadOns() {
uint16 addr = _vm->res->dseg.get_word(dsAddr_onsAnimationTablePtr + (_id - 1) * 2);
debugC(0, kDebugScene, "ons index: %04x", addr);
- onsCount = 0;
+ _onsCount = 0;
byte b;
byte onId[16];
while ((b = _vm->res->dseg.get_byte(addr)) != 0xff) {
@@ -323,15 +326,15 @@ void Scene::loadOns() {
if (b == 0)
continue;
- onId[onsCount++] = b;
+ onId[_onsCount++] = b;
}
delete[] ons;
ons = NULL;
- if (onsCount > 0) {
- ons = new Surface[onsCount];
- for (uint32 i = 0; i < onsCount; ++i) {
+ if (_onsCount > 0) {
+ ons = new Surface[_onsCount];
+ for (uint32 i = 0; i < _onsCount; ++i) {
Common::ScopedPtr<Common::SeekableReadStream> s(_vm->res->ons.getStream(onId[i]));
if (s) {
ons[i].load(*s, Surface::kTypeOns);
@@ -498,7 +501,7 @@ bool Scene::processEvent(const Common::Event &event) {
events.clear();
sounds.clear();
currentEvent.clear();
- messageColor = textColorMark;
+ _messageColor = textColorMark;
for (int i = 0; i < 4; ++i)
customAnimation[i].free();
_vm->playMusic(4);
@@ -651,7 +654,7 @@ bool Scene::render(bool tickGame, bool tickMark, uint32 messageDelta) {
bool gotAnyAnimation = false;
if (ons != NULL && debugFeatures.feature[DebugFeatures::kShowOns]) {
- for (uint32 i = 0; i < onsCount; ++i) {
+ for (uint32 i = 0; i < _onsCount; ++i) {
Surface *s = ons + i;
if (s != NULL)
s->render(surface);
@@ -821,7 +824,7 @@ bool Scene::render(bool tickGame, bool tickMark, uint32 messageDelta) {
}
if (visible) {
- _vm->res->font7.render(surface, messagePos.x, messagePos.y, message, messageColor);
+ _vm->res->font7.render(surface, messagePos.x, messagePos.y, message, _messageColor);
busy = true;
}
}
@@ -1005,7 +1008,7 @@ bool Scene::processEventQueue() {
warning("no animation in slot %u", messageSlot);
}
messagePos = messagePosition(message, p);
- messageColor = currentEvent.color;
+ _messageColor = currentEvent.color;
if (messageFirstFrame)
currentEvent.clear(); // async message, clearing event
@@ -1153,7 +1156,7 @@ bool Scene::processEventQueue() {
}
if (events.empty()) {
- messageColor = textColorMark;
+ _messageColor = textColorMark;
hideActor = false;
}
@@ -1232,7 +1235,7 @@ void Scene::displayMessage(const Common::String &str, byte color, const Common::
debugC(0, kDebugScene, "displayMessage: %s", str.c_str());
message = str;
messagePos = (pos.x | pos.y) ? pos : messagePosition(str, position);
- messageColor = color;
+ _messageColor = color;
messageTimer = messageDuration(message);
}
@@ -1251,7 +1254,7 @@ void Scene::clear() {
void Scene::clearMessage() {
message.clear();
messageTimer = 0;
- messageColor = textColorMark;
+ _messageColor = textColorMark;
messageFirstFrame = 0;
messageLastFrame = 0;
messageAnimation = NULL;
diff --git a/engines/teenagent/scene.h b/engines/teenagent/scene.h
index 07b304ed97..40f910a3aa 100644
--- a/engines/teenagent/scene.h
+++ b/engines/teenagent/scene.h
@@ -194,7 +194,7 @@ private:
SurfaceList on;
bool onEnabled;
Surface *ons;
- uint32 onsCount;
+ uint32 _onsCount;
Animation actorAnimation, animation[4], customAnimation[4];
Common::Rect actorAnimationPosition, animationPosition[4];
@@ -214,7 +214,7 @@ private:
Common::String message;
Common::Point messagePos;
- byte messageColor;
+ byte _messageColor;
uint messageTimer;
byte messageFirstFrame;
byte messageLastFrame;
diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp
index 4dc785754c..2d10b82f51 100644
--- a/engines/teenagent/teenagent.cpp
+++ b/engines/teenagent/teenagent.cpp
@@ -71,6 +71,13 @@ TeenAgentEngine::TeenAgentEngine(OSystem *system, const ADGameDescription *gd)
res = new Resources();
console = 0;
+ scene = 0;
+ inventory = 0;
+ _sceneBusy = false;
+ _dstObject = 0;
+ _musicStream = 0;
+ _markDelay = 0;
+ _gameDelay = 0;
}
TeenAgentEngine::~TeenAgentEngine() {
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index a84dad942c..4bc28ffb53 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -3676,13 +3676,13 @@ extern void HideConversation(bool bHide) {
ConstructInventory(FULL);
else {
// Move it all back on-screen
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiAdjustXY(g_objArray[i], -2 * SCREEN_WIDTH, 0);
}
// Don't flash if items changed. If they have, will be redrawn anyway.
if (TinselV2 || !g_ItemsChanged) {
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiAdjustXY(g_iconArray[i], -2*SCREEN_WIDTH, 0);
}
}
@@ -3739,10 +3739,10 @@ extern void HideConversation(bool bHide) {
deltay = g_InvD[INV_CONV].inventoryY - deltay;
// Move it all
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiMoveRelXY(g_objArray[i], x - center, deltay);
}
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiMoveRelXY(g_iconArray[i], x - center, deltay);
}
g_InvD[INV_CONV].inventoryX += x - center;
@@ -3771,10 +3771,10 @@ extern void HideConversation(bool bHide) {
y = 0;
if (x || y) {
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiMoveRelXY(g_objArray[i], x, y);
}
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiMoveRelXY(g_iconArray[i], x, y);
}
g_InvD[INV_CONV].inventoryX += x;
@@ -3786,10 +3786,10 @@ extern void HideConversation(bool bHide) {
*/
if (MultiLowest(g_RectObject) > SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) {
y = (SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) - MultiLowest(g_RectObject);
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiMoveRelXY(g_objArray[i], 0, y);
}
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiMoveRelXY(g_iconArray[i], 0, y);
}
g_InvD[INV_CONV].inventoryY += y;
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index b64903ec6d..b26408fadc 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -45,7 +45,7 @@ enum ChunkTypes {
kChunkStopSubtitles = 8
};
-MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm), _isPlaying(false), _lastPrefetchOfs(0), _framesPerSoundChunk(0), _endPos(0) {
+MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm), _isPlaying(false), _lastPrefetchOfs(0), _framesPerSoundChunk(0), _endPos(0), _audioStream(0) {
}
MoviePlayer::~MoviePlayer() {
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index 468ae0272f..6dbb9c2843 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -31,6 +31,7 @@ namespace Toltecs {
/* ArchiveReader */
ArchiveReader::ArchiveReader() {
+ _offsets = 0;
}
ArchiveReader::~ArchiveReader() {
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index f29f64dcfe..be4be5d9e3 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -84,6 +84,7 @@ public:
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
_scalerStatus = 0;
+ _xerror = 0;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
SpriteReaderStatus status = kSrsPixelsLeft;
@@ -135,6 +136,8 @@ public:
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
_scalerStatus = 0;
+ _sourcep = 0;
+ _xerror = 0;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
SpriteReaderStatus status;
diff --git a/engines/tony/gfxcore.cpp b/engines/tony/gfxcore.cpp
index 2a32926c53..27145d7c4b 100644
--- a/engines/tony/gfxcore.cpp
+++ b/engines/tony/gfxcore.cpp
@@ -1733,13 +1733,6 @@ void RMGfxSourceBuffer8AA::drawAA(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *pri
g /= 5;
b /= 5;
- if (r > 0x1f)
- r = 0x1f;
- if (g > 0x3f)
- g = 0x3f;
- if (b > 0x1f)
- b = 0x1f;
-
mybuf[0] = (r << 11) | (g << 5) | b;
}
}
@@ -1774,13 +1767,6 @@ void RMGfxSourceBuffer8AA::drawAA(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *pri
g /= 6;
b /= 6;
- if (r > 0x1f)
- r = 0x1f;
- if (g > 0x3f)
- g = 0x3f;
- if (b > 0x1f)
- b = 0x1f;
-
mybuf[0] = (r << 11) | (g << 5) | b;
}
}
diff --git a/engines/tony/mpal/loadmpc.cpp b/engines/tony/mpal/loadmpc.cpp
index 8d030f1e52..01892a40e6 100644
--- a/engines/tony/mpal/loadmpc.cpp
+++ b/engines/tony/mpal/loadmpc.cpp
@@ -331,7 +331,7 @@ static const byte *parseItem(const byte *lpBuf, LpMpalItem lpmiItem) {
byte len = *lpBuf;
lpBuf++;
- memcpy(lpmiItem->_lpszDescribe, lpBuf, MIN((byte)127, len));
+ memcpy(lpmiItem->_lpszDescribe, lpBuf, MIN((byte)MAX_DESCRIBE_SIZE, len));
lpBuf += len;
if (len >= MAX_DESCRIBE_SIZE)
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 89cc28130d..9172843781 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -367,12 +367,18 @@ MpalHandle resLoad(uint32 dwId) {
temp = (byte *)globalAlloc(GMEM_FIXED | GMEM_ZEROINIT, nSizeComp);
nBytesRead = GLOBALS._hMpr.read(temp, nSizeComp);
- if (nBytesRead != nSizeComp)
+ if (nBytesRead != nSizeComp) {
+ globalDestroy(temp);
+ globalDestroy(h);
return NULL;
+ }
lzo1x_decompress(temp, nSizeComp, buf, &nBytesRead);
- if (nBytesRead != nSizeDecomp)
+ if (nBytesRead != nSizeDecomp) {
+ globalDestroy(temp);
+ globalDestroy(h);
return NULL;
+ }
globalDestroy(temp);
globalUnlock(h);
@@ -526,8 +532,10 @@ static LpItem getItemData(uint32 nOrdItem) {
globalFree(hDat);
// Check if we've got to the end of the file
- if (i != 0xABCD)
+ if (i != 0xABCD) {
+ globalDestroy(ret);
return NULL;
+ }
return ret;
}
@@ -1413,36 +1421,51 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
if (bCompress) {
// Get the compressed size and read the data in
uint32 dwSizeComp = hMpc.readUint32LE();
- if (hMpc.err())
+ if (hMpc.err()) {
+ globalDestroy(lpMpcImage);
return false;
+ }
cmpbuf = (byte *)globalAlloc(GMEM_FIXED, dwSizeComp);
- if (cmpbuf == NULL)
+ if (cmpbuf == NULL) {
+ globalDestroy(lpMpcImage);
return false;
+ }
nBytesRead = hMpc.read(cmpbuf, dwSizeComp);
- if (nBytesRead != dwSizeComp)
+ if (nBytesRead != dwSizeComp) {
+ globalDestroy(cmpbuf);
+ globalDestroy(lpMpcImage);
return false;
+ }
// Decompress the data
lzo1x_decompress(cmpbuf, dwSizeComp, lpMpcImage, &nBytesRead);
- if (nBytesRead != dwSizeDecomp)
+ if (nBytesRead != dwSizeDecomp) {
+ globalDestroy(cmpbuf);
+ globalDestroy(lpMpcImage);
return false;
+ }
globalDestroy(cmpbuf);
} else {
// If the file is not compressed, we directly read in the data
nBytesRead = hMpc.read(lpMpcImage, dwSizeDecomp);
- if (nBytesRead != dwSizeDecomp)
+ if (nBytesRead != dwSizeDecomp) {
+ globalDestroy(lpMpcImage);
return false;
+ }
}
// Close the file
hMpc.close();
// Process the data
- if (parseMpc(lpMpcImage) == false)
+ if (parseMpc(lpMpcImage) == false) {
+ globalDestroy(lpMpcImage);
+
return false;
+ }
globalDestroy(lpMpcImage);
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
index bd8a0cdd0d..6b44ecc514 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -1440,7 +1440,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
case 2425:
_sceneMode = 10;
R2_GLOBALS._player.setPosition(Common::Point(280, 150));
- _action->signal();
+ signal();
break;
case 2455:
_sceneMode = 2428;
diff --git a/engines/wage/debugger.cpp b/engines/wage/debugger.cpp
index 7d01b0b85e..d34aca7d49 100644
--- a/engines/wage/debugger.cpp
+++ b/engines/wage/debugger.cpp
@@ -56,7 +56,7 @@ static int strToInt(const char *s) {
}
bool Debugger::Cmd_ListScenes(int argc, const char **argv) {
- int currentScene;
+ int currentScene = 0;
for (uint i = 1; i < _engine->_world->_orderedScenes.size(); i++) { // #0 is STORAGE@
if (_engine->_world->_player->_currentScene == _engine->_world->_orderedScenes[i])
diff --git a/engines/wage/design.cpp b/engines/wage/design.cpp
index 185c051eb6..eda28df159 100644
--- a/engines/wage/design.cpp
+++ b/engines/wage/design.cpp
@@ -45,8 +45,10 @@
*
*/
+#include "graphics/managed_surface.h"
#include "graphics/primitives.h"
-#include "wage/wage.h"
+
+#include "wage/macwindowmanager.h"
#include "wage/design.h"
namespace Wage {
@@ -208,9 +210,9 @@ void drawPixel(int x, int y, int color, void *data) {
if (p->thickness == 1) {
p->design->adjustBounds(x, y);
} else {
- int x1 = x - p->thickness / 2;
+ int x1 = x;
int x2 = x1 + p->thickness;
- int y1 = y - p->thickness / 2;
+ int y1 = y;
int y2 = y1 + p->thickness;
for (y = y1; y < y2; y++)
@@ -233,9 +235,9 @@ void drawPixel(int x, int y, int color, void *data) {
color : kColorWhite;
}
} else {
- int x1 = x - p->thickness / 2;
+ int x1 = x;
int x2 = x1 + p->thickness;
- int y1 = y - p->thickness / 2;
+ int y1 = y;
int y2 = y1 + p->thickness;
for (y = y1; y < y2; y++)
diff --git a/engines/wage/design.h b/engines/wage/design.h
index a6e0df4c40..9b0231ca96 100644
--- a/engines/wage/design.h
+++ b/engines/wage/design.h
@@ -48,10 +48,11 @@
#ifndef WAGE_DESIGN_H
#define WAGE_DESIGN_H
-#include "graphics/managed_surface.h"
#include "common/memstream.h"
#include "common/rect.h"
+#include "wage/macwindowmanager.h"
+
namespace Wage {
class Design {
diff --git a/engines/wage/dialog.cpp b/engines/wage/dialog.cpp
index 263570bddc..d9bb3e6a61 100644
--- a/engines/wage/dialog.cpp
+++ b/engines/wage/dialog.cpp
@@ -49,6 +49,7 @@
#include "common/events.h"
#include "wage/wage.h"
+#include "wage/macwindowmanager.h"
#include "wage/design.h"
#include "wage/gui.h"
#include "wage/dialog.h"
@@ -88,11 +89,11 @@ Dialog::~Dialog() {
}
const Graphics::Font *Dialog::getDialogFont() {
- return _gui->getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
+ return _gui->_wm.getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
}
void Dialog::paint() {
- Design::drawFilledRect(&_gui->_screen, _bbox, kColorWhite, _gui->_patterns, kPatternSolid);
+ Design::drawFilledRect(&_gui->_screen, _bbox, kColorWhite, _gui->_wm.getPatterns(), kPatternSolid);
_font->drawString(&_gui->_screen, _text, _bbox.left + 24, _bbox.top + 16, _bbox.width(), kColorBlack);
static int boxOutline[] = { 1, 0, 0, 1, 1 };
@@ -114,7 +115,7 @@ void Dialog::paint() {
Common::Rect bb(button->bounds.left + 5, button->bounds.top + 5,
button->bounds.right - 5, button->bounds.bottom - 5);
- Design::drawFilledRect(&_gui->_screen, bb, kColorBlack, _gui->_patterns, kPatternSolid);
+ Design::drawFilledRect(&_gui->_screen, bb, kColorBlack, _gui->_wm.getPatterns(), kPatternSolid);
color = kColorWhite;
}
@@ -137,7 +138,7 @@ void Dialog::drawOutline(Common::Rect &bounds, int *spec, int speclen) {
for (int i = 0; i < speclen; i++)
if (spec[i] != 0)
Design::drawRect(&_gui->_screen, bounds.left + i, bounds.top + i, bounds.right - i, bounds.bottom - i,
- 1, kColorBlack, _gui->_patterns, kPatternSolid);
+ 1, kColorBlack, _gui->_wm.getPatterns(), kPatternSolid);
}
int Dialog::run() {
@@ -145,7 +146,7 @@ int Dialog::run() {
Common::Rect r(_bbox);
_tempSurface.copyRectToSurface(_gui->_screen.getBasePtr(_bbox.left, _bbox.top), _gui->_screen.pitch, 0, 0, _bbox.width() + 1, _bbox.height() + 1);
- _gui->pushArrowCursor();
+ _gui->_wm.pushArrowCursor();
while (!shouldQuit) {
Common::Event event;
@@ -189,7 +190,7 @@ int Dialog::run() {
_gui->_screen.copyRectToSurface(_tempSurface.getBasePtr(0, 0), _tempSurface.pitch, _bbox.left, _bbox.top, _bbox.width() + 1, _bbox.height() + 1);
g_system->copyRectToScreen(_gui->_screen.getBasePtr(r.left, r.top), _gui->_screen.pitch, r.left, r.top, r.width() + 1, r.height() + 1);
- _gui->popCursor();
+ _gui->_wm.popCursor();
return _pressedButton;
}
diff --git a/engines/wage/entities.cpp b/engines/wage/entities.cpp
index 49e2592949..43ac6c8cc7 100644
--- a/engines/wage/entities.cpp
+++ b/engines/wage/entities.cpp
@@ -52,6 +52,7 @@
#include "wage/world.h"
#include "common/memstream.h"
+#include "graphics/managed_surface.h"
namespace Wage {
@@ -138,16 +139,16 @@ void Scene::paint(Graphics::ManagedSurface *surface, int x, int y) {
Common::Rect r(x + 5, y + 5, _design->getBounds()->width() + x - 10, _design->getBounds()->height() + y - 10);
surface->fillRect(r, kColorWhite);
- _design->paint(surface, ((WageEngine *)g_engine)->_world->_patterns, x, y);
+ _design->paint(surface, *((WageEngine *)g_engine)->_world->_patterns, x, y);
for (ObjList::const_iterator it = _objs.begin(); it != _objs.end(); ++it) {
debug(2, "paining Obj: %s, index: %d, type: %d", (*it)->_name.c_str(), (*it)->_index, (*it)->_type);
- (*it)->_design->paint(surface, ((WageEngine *)g_engine)->_world->_patterns, x, y);
+ (*it)->_design->paint(surface, *((WageEngine *)g_engine)->_world->_patterns, x, y);
}
for (ChrList::const_iterator it = _chrs.begin(); it != _chrs.end(); ++it) {
debug(2, "paining Chr: %s", (*it)->_name.c_str());
- (*it)->_design->paint(surface, ((WageEngine *)g_engine)->_world->_patterns, x, y);
+ (*it)->_design->paint(surface, *((WageEngine *)g_engine)->_world->_patterns, x, y);
}
}
@@ -202,6 +203,22 @@ const char *Scene::getFontName() {
return "Unknown";
}
+Designed *Scene::lookUpEntity(int x, int y) {
+ for (ObjList::const_iterator it = _objs.end(); it != _objs.begin(); ) {
+ it--;
+ if ((*it)->_design->isPointOpaque(x, y))
+ return *it;
+ }
+
+ for (ChrList::const_iterator it = _chrs.end(); it != _chrs.begin(); ) {
+ it--;
+ if ((*it)->_design->isPointOpaque(x, y))
+ return *it;
+ }
+
+ return nullptr;
+}
+
Obj::Obj() : _currentOwner(NULL), _currentScene(NULL) {
_index = 0;
_namePlural = false;
diff --git a/engines/wage/entities.h b/engines/wage/entities.h
index c393f15f01..9e706f0d58 100644
--- a/engines/wage/entities.h
+++ b/engines/wage/entities.h
@@ -322,6 +322,8 @@ public:
Scene(Common::String name, Common::SeekableReadStream *data);
~Scene();
+ Designed *lookUpEntity(int x, int y);
+
Common::Rect *getTextBounds() {
return _textBounds == NULL ? NULL : new Common::Rect(*_textBounds);
}
diff --git a/engines/wage/gui-console.cpp b/engines/wage/gui-console.cpp
index 840b8e3ced..8b6fe43a17 100644
--- a/engines/wage/gui-console.cpp
+++ b/engines/wage/gui-console.cpp
@@ -45,6 +45,7 @@
*
*/
+#include "common/events.h"
#include "common/timer.h"
#include "common/unzip.h"
#include "graphics/cursorman.h"
@@ -54,7 +55,8 @@
#include "wage/wage.h"
#include "wage/design.h"
#include "wage/entities.h"
-#include "wage/menu.h"
+#include "wage/macwindow.h"
+#include "wage/macmenu.h"
#include "wage/gui.h"
#include "wage/world.h"
@@ -66,7 +68,7 @@ const Graphics::Font *Gui::getConsoleFont() {
snprintf(fontName, 128, "%s-%d", scene->getFontName(), scene->_fontSize);
- return getFont(fontName, Graphics::FontManager::kConsoleFont);
+ return _wm.getFont(fontName, Graphics::FontManager::kConsoleFont);
}
void Gui::clearOutput() {
@@ -114,7 +116,7 @@ enum {
void Gui::flowText(Common::String &str) {
Common::StringArray wrappedLines;
- int textW = _consoleTextArea.width() - kConWPadding * 2;
+ int textW = _consoleWindow->getInnerDimensions().width() - kConWPadding * 2;
const Graphics::Font *font = getConsoleFont();
font->wordWrapText(str, textW, wrappedLines);
@@ -196,7 +198,7 @@ void Gui::renderConsole(Graphics::ManagedSurface *g, const Common::Rect &r) {
color = kColorWhite;
Common::Rect trect(0, y1, _console.w, y1 + _consoleLineHeight);
- Design::drawFilledRect(&_console, trect, kColorBlack, _patterns, kPatternSolid);
+ Design::drawFilledRect(&_console, trect, kColorBlack, _wm.getPatterns(), kPatternSolid);
}
if (line == _selectionStartY || line == _selectionEndY) {
@@ -223,7 +225,7 @@ void Gui::renderConsole(Graphics::ManagedSurface *g, const Common::Rect &r) {
else
trect.left = rectW;
- Design::drawFilledRect(&_console, trect, kColorBlack, _patterns, kPatternSolid);
+ Design::drawFilledRect(&_console, trect, kColorBlack, _wm.getPatterns(), kPatternSolid);
font->drawString(&_console, beg, x1, y1, textW, color1);
font->drawString(&_console, end, x1 + rectW - kConWPadding - kConWOverlap, y1, textW, color2);
@@ -242,7 +244,7 @@ void Gui::renderConsole(Graphics::ManagedSurface *g, const Common::Rect &r) {
int rectW2 = rectW1 + font->getStringWidth(mid);
Common::Rect trect(rectW1, y1, rectW2, y1 + _consoleLineHeight);
- Design::drawFilledRect(&_console, trect, kColorBlack, _patterns, kPatternSolid);
+ Design::drawFilledRect(&_console, trect, kColorBlack, _wm.getPatterns(), kPatternSolid);
font->drawString(&_console, beg, x1, y1, textW, kColorBlack);
font->drawString(&_console, mid, x1 + rectW1 - kConWPadding - kConWOverlap, y1, textW, kColorWhite);
@@ -285,10 +287,7 @@ void Gui::drawInput() {
if (!_screen.getPixels())
return;
- if (_sceneIsActive) {
- _sceneIsActive = false;
- _bordersDirty = true;
- }
+ _wm.setActive(_consoleWindow->getId());
_out.pop_back();
_lines.pop_back();
@@ -300,17 +299,17 @@ void Gui::drawInput() {
if (_engine->_inputText.contains('\n')) {
_consoleDirty = true;
} else {
- int x = kConWPadding + _consoleTextArea.left;
- int y = _cursorY + _consoleTextArea.top;
+ int x = kConWPadding + _consoleWindow->getInnerDimensions().left;
+ int y = _cursorY + _consoleWindow->getInnerDimensions().top;
- Common::Rect r(x, y, x + _consoleTextArea.width() - kConWPadding, y + font->getFontHeight());
+ Common::Rect r(x, y, x + _consoleWindow->getInnerDimensions().width() - kConWPadding, y + font->getFontHeight());
_screen.fillRect(r, kColorWhite);
undrawCursor();
font->drawString(&_screen, _out[_inputTextLineNum], x, y, _screen.w, kColorBlack);
- g_system->copyRectToScreen(_screen.getBasePtr(x, y), _screen.pitch, x, y, _consoleTextArea.width(), font->getFontHeight());
+ g_system->copyRectToScreen(_screen.getBasePtr(x, y), _screen.pitch, x, y, _consoleWindow->getInnerDimensions().width(), font->getFontHeight());
}
_cursorX = font->getStringWidth(_out[_inputTextLineNum]) + kConHPadding;
@@ -425,4 +424,140 @@ void Gui::enableNewGameMenus() {
_menu->enableCommand(kMenuFile, kMenuActionQuit, true);
}
+bool Gui::processConsoleEvents(WindowClick click, Common::Event &event) {
+ if (click == kBorderScrollUp || click == kBorderScrollDown) {
+ if (event.type == Common::EVENT_LBUTTONDOWN) {
+ int consoleHeight = _consoleWindow->getInnerDimensions().height();
+ int textFullSize = _lines.size() * _consoleLineHeight + consoleHeight;
+ float scrollPos = (float)_scrollPos / textFullSize;
+ float scrollSize = (float)consoleHeight / textFullSize;
+
+ _consoleWindow->setScroll(scrollPos, scrollSize);
+
+ return true;
+ } else if (event.type == Common::EVENT_LBUTTONUP) {
+ int oldScrollPos = _scrollPos;
+
+ switch (click) {
+ case kBorderScrollUp:
+ _scrollPos = MAX<int>(0, _scrollPos - _consoleLineHeight);
+ undrawCursor();
+ _cursorY -= (_scrollPos - oldScrollPos);
+ _consoleDirty = true;
+ _consoleFullRedraw = true;
+ break;
+ case kBorderScrollDown:
+ _scrollPos = MIN<int>((_lines.size() - 2) * _consoleLineHeight, _scrollPos + _consoleLineHeight);
+ undrawCursor();
+ _cursorY -= (_scrollPos - oldScrollPos);
+ _consoleDirty = true;
+ _consoleFullRedraw = true;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ if (click == kBorderResizeButton) {
+ _consoleDirty = true;
+ _consoleFullRedraw = true;
+
+ return true;
+ }
+
+ if (click == kBorderInner) {
+ if (event.type == Common::EVENT_LBUTTONDOWN) {
+ startMarking(event.mouse.x, event.mouse.y);
+
+ return true;
+ } else if (event.type == Common::EVENT_LBUTTONUP) {
+ if (_inTextSelection) {
+ _inTextSelection = false;
+
+ if (_selectionEndY == -1 ||
+ (_selectionEndX == _selectionStartX && _selectionEndY == _selectionStartY)) {
+ _selectionStartY = _selectionEndY = -1;
+ _consoleFullRedraw = true;
+ _menu->enableCommand(kMenuEdit, kMenuActionCopy, false);
+ } else {
+ _menu->enableCommand(kMenuEdit, kMenuActionCopy, true);
+
+ bool cutAllowed = false;
+
+ if (_selectionStartY == _selectionEndY && _selectionStartY == (int)_lines.size() - 1)
+ cutAllowed = true;
+
+ _menu->enableCommand(kMenuEdit, kMenuActionCut, cutAllowed);
+ _menu->enableCommand(kMenuEdit, kMenuActionClear, cutAllowed);
+ }
+ }
+
+ return true;
+ } else if (event.type == Common::EVENT_MOUSEMOVE) {
+ if (_inTextSelection) {
+ updateTextSelection(event.mouse.x, event.mouse.y);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return false;
+}
+
+int Gui::calcTextX(int x, int textLine) {
+ const Graphics::Font *font = getConsoleFont();
+
+ if ((uint)textLine >= _lines.size())
+ return 0;
+
+ Common::String str = _lines[textLine];
+
+ x -= _consoleWindow->getInnerDimensions().left;
+
+ for (int i = str.size(); i >= 0; i--) {
+ if (font->getStringWidth(str) < x) {
+ return i;
+ }
+
+ str.deleteLastChar();
+ }
+
+ return 0;
+}
+
+int Gui::calcTextY(int y) {
+ y -= _consoleWindow->getInnerDimensions().top;
+
+ if (y < 0)
+ y = 0;
+
+ const int firstLine = _scrollPos / _consoleLineHeight;
+ int textLine = (y - _scrollPos % _consoleLineHeight) / _consoleLineHeight + firstLine;
+
+ return textLine;
+}
+
+void Gui::startMarking(int x, int y) {
+ _selectionStartY = calcTextY(y);
+ _selectionStartX = calcTextX(x, _selectionStartY);
+
+ _selectionEndY = -1;
+
+ _inTextSelection = true;
+}
+
+void Gui::updateTextSelection(int x, int y) {
+ _selectionEndY = calcTextY(y);
+ _selectionEndX = calcTextX(x, _selectionEndY);
+
+ _consoleFullRedraw = true;
+}
+
} // End of namespace Wage
diff --git a/engines/wage/gui.cpp b/engines/wage/gui.cpp
index 436d17c56f..310e5734b7 100644
--- a/engines/wage/gui.cpp
+++ b/engines/wage/gui.cpp
@@ -46,73 +46,40 @@
*/
#include "common/timer.h"
-#include "common/unzip.h"
+#include "common/system.h"
#include "graphics/cursorman.h"
-#include "graphics/fonts/bdf.h"
-#include "graphics/palette.h"
#include "graphics/primitives.h"
#include "wage/wage.h"
#include "wage/design.h"
#include "wage/entities.h"
+#include "wage/gui.h"
#include "wage/macwindow.h"
#include "wage/macwindowmanager.h"
-#include "wage/menu.h"
-#include "wage/gui.h"
+#include "wage/macmenu.h"
#include "wage/world.h"
namespace Wage {
-static const byte palette[] = {
- 0, 0, 0, // Black
- 0x80, 0x80, 0x80, // Gray
- 0xff, 0xff, 0xff, // White
- 0x00, 0xff, 0x00, // Green
- 0x00, 0xcf, 0x00 // Green2
-};
-
-static byte fillPatterns[][8] = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, // kPatternSolid
- { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, // kPatternStripes
- { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }, // kPatternCheckers
- { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa } // kPatternCheckers2
-};
-
-static const byte macCursorArrow[] = {
- 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 0, 0, 2, 3, 3, 3, 3, 3, 3, 3,
- 2, 0, 0, 0, 2, 3, 3, 3, 3, 3, 3,
- 2, 0, 0, 0, 0, 2, 3, 3, 3, 3, 3,
- 2, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3,
- 2, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3,
- 2, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3,
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3,
- 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
- 2, 0, 0, 2, 0, 0, 2, 3, 3, 3, 3,
- 2, 0, 2, 3, 2, 0, 0, 2, 3, 3, 3,
- 2, 2, 3, 3, 2, 0, 0, 2, 3, 3, 3,
- 2, 3, 3, 3, 3, 2, 0, 0, 2, 3, 3,
- 3, 3, 3, 3, 3, 2, 0, 0, 2, 3, 3,
- 3, 3, 3, 3, 3, 3, 2, 2, 2, 3, 3
-};
-
-static const byte macCursorBeam[] = {
- 0, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3,
- 3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3,
- 0, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3,
+static const MenuData menuSubItems[] = {
+ { kMenuHighLevel, "File", 0, 0, false },
+ { kMenuHighLevel, "Edit", 0, 0, false },
+ { kMenuFile, "New", kMenuActionNew, 0, false },
+ { kMenuFile, "Open...", kMenuActionOpen, 0, false },
+ { kMenuFile, "Close", kMenuActionClose, 0, true },
+ { kMenuFile, "Save", kMenuActionSave, 0, false },
+ { kMenuFile, "Save as...", kMenuActionSaveAs, 0, true },
+ { kMenuFile, "Revert", kMenuActionRevert, 0, false },
+ { kMenuFile, "Quit", kMenuActionQuit, 0, true },
+
+ { kMenuEdit, "Undo", kMenuActionUndo, 'Z', false },
+ { kMenuEdit, NULL, 0, 0, false },
+ { kMenuEdit, "Cut", kMenuActionCut, 'K', false },
+ { kMenuEdit, "Copy", kMenuActionCopy, 'C', false },
+ { kMenuEdit, "Paste", kMenuActionPaste, 'V', false },
+ { kMenuEdit, "Clear", kMenuActionClear, 'B', false },
+
+ { 0, NULL, 0, 0, false }
};
static void cursorTimerHandler(void *refCon) {
@@ -127,8 +94,8 @@ static void cursorTimerHandler(void *refCon) {
if (!gui->_screen.getPixels())
return;
- x += gui->_consoleTextArea.left;
- y += gui->_consoleTextArea.top;
+ x += gui->_consoleWindow->getInnerDimensions().left;
+ y += gui->_consoleWindow->getInnerDimensions().top;
gui->_screen.vLine(x, y, y + kCursorHeight, gui->_cursorState ? kColorBlack : kColorWhite);
@@ -143,22 +110,25 @@ static void cursorTimerHandler(void *refCon) {
gui->_cursorDirty = true;
}
+static bool sceneWindowCallback(WindowClick click, Common::Event &event, void *gui);
+static bool consoleWindowCallback(WindowClick click, Common::Event &event, void *gui);
+static void menuCommandsCallback(int action, Common::String &text, void *data);
+
+
Gui::Gui(WageEngine *engine) {
_engine = engine;
_scene = NULL;
_sceneDirty = true;
_consoleDirty = true;
- _bordersDirty = true;
- _menuDirty = true;
_cursorDirty = false;
_consoleFullRedraw = true;
_screen.create(g_system->getWidth(), g_system->getHeight(), Graphics::PixelFormat::createFormatCLUT8());
+ _wm.setScreen(&_screen);
+
_scrollPos = 0;
_consoleLineHeight = 8; // Dummy value which makes sense
_consoleNumLines = 24; // Dummy value
- _builtInFonts = false;
- _sceneIsActive = false;
_cursorX = 0;
_cursorY = 0;
@@ -171,31 +141,39 @@ Gui::Gui(WageEngine *engine) {
_inputTextLineNum = 0;
- g_system->getPaletteManager()->setPalette(palette, 0, ARRAYSIZE(palette) / 3);
+ g_system->getTimerManager()->installTimerProc(&cursorTimerHandler, 200000, this, "wageCursor");
- CursorMan.replaceCursorPalette(palette, 0, 4);
- CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3);
- _cursorIsArrow = true;
- CursorMan.showMouse(true);
+ _menu = _wm.addMenu();
- for (int i = 0; i < ARRAYSIZE(fillPatterns); i++)
- _patterns.push_back(fillPatterns[i]);
+ _menu->setCommandsCallback(menuCommandsCallback, this);
- loadFonts();
+ _menu->addStaticMenus(menuSubItems);
+ _menu->addMenuSubItem(kMenuAbout, _engine->_world->getAboutMenuItemName(), kMenuActionAbout);
- g_system->getTimerManager()->installTimerProc(&cursorTimerHandler, 200000, this, "wageCursor");
+ _commandsMenuId = _menu->addMenuItem(_engine->_world->_commandsMenuName.c_str());
+ regenCommandsMenu();
+
+ if (!_engine->_world->_weaponMenuDisabled) {
+ _weaponsMenuId = _menu->addMenuItem(_engine->_world->_weaponsMenuName.c_str());
+
+ regenWeaponsMenu();
+ } else {
+ _weaponsMenuId = -1;
+ }
+
+ _menu->calcDimensions();
- _menu = new Menu(this);
+ _sceneWindow = _wm.addWindow(false, false, false);
+ _sceneWindow->setCallback(sceneWindowCallback, this);
- _sceneWindowId = _wm.add(false);
- _consoleWindowId = _wm.add(true);
+ _consoleWindow = _wm.addWindow(true, true, true);
+ _consoleWindow->setCallback(consoleWindowCallback, this);
}
Gui::~Gui() {
_screen.free();
_console.free();
g_system->getTimerManager()->removeTimerProc(&cursorTimerHandler);
- delete _menu;
}
void Gui::undrawCursor() {
@@ -205,63 +183,34 @@ void Gui::undrawCursor() {
_cursorOff = false;
}
-const Graphics::Font *Gui::getFont(const char *name, Graphics::FontManager::FontUsage fallback) {
- const Graphics::Font *font = 0;
-
- if (!_builtInFonts) {
- font = FontMan.getFontByName(name);
-
- if (!font)
- warning("Cannot load font %s", name);
- }
-
- if (_builtInFonts || !font)
- font = FontMan.getFontByUsage(fallback);
-
- return font;
-}
-
-const Graphics::Font *Gui::getTitleFont() {
- return getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
-}
-
-void Gui::drawDesktop() {
- // Draw desktop
- Common::Rect r(0, 0, _screen.w - 1, _screen.h - 1);
- Design::drawFilledRoundRect(&_screen, r, kDesktopArc, kColorBlack, _patterns, kPatternCheckers);
- g_system->copyRectToScreen(_screen.getPixels(), _screen.pitch, 0, 0, _screen.w, _screen.h);
-}
-
void Gui::draw() {
if (_engine->_isGameOver) {
- if (_menuDirty) {
- drawDesktop();
- _menu->render();
- }
-
- _menuDirty = false;
+ _wm.draw();
return;
}
- if (_scene != _engine->_world->_player->_currentScene)
+ if (!_engine->_world->_player->_currentScene)
+ return;
+
+ if (_scene != _engine->_world->_player->_currentScene) {
_sceneDirty = true;
- if (_sceneDirty || _bordersDirty)
- drawDesktop();
+ _scene = _engine->_world->_player->_currentScene;
- if (_sceneIsActive) {
- drawConsole();
- drawScene();
- } else {
- drawScene();
- drawConsole();
+ _sceneWindow->setDimensions(*_scene->_designBounds);
+ _sceneWindow->setTitle(_scene->_name);
+ _consoleWindow->setDimensions(*_scene->_textBounds);
+
+ _wm.setFullRefresh(true);
}
- if (_menuDirty)
- _menu->render();
+ drawScene();
+ drawConsole();
+
+ _wm.draw();
- if (_cursorDirty) {
+ if (_cursorDirty && _cursorRect.left < _screen.w && _cursorRect.bottom < _screen.h) {
g_system->copyRectToScreen(_screen.getBasePtr(_cursorRect.left, _cursorRect.top), _screen.pitch,
_cursorRect.left, _cursorRect.top, _cursorRect.width(), _cursorRect.height());
@@ -270,446 +219,141 @@ void Gui::draw() {
_sceneDirty = false;
_consoleDirty = false;
- _bordersDirty = false;
- _menuDirty = false;
_consoleFullRedraw = false;
}
void Gui::drawScene() {
- if (!_sceneDirty && !_bordersDirty)
+ if (!_sceneDirty)
return;
- _scene = _engine->_world->_player->_currentScene;
-
- MacWindow *w = _wm.getWindow(_sceneWindowId);
-
- w->setDimensions(*_scene->_designBounds);
- w->setTitle(_scene->_name);
- _scene->paint(w->getSurface(), 0, 0);
- w->draw(&_screen);
- g_system->copyRectToScreen(_screen.getBasePtr(_scene->_designBounds->left - 2, _scene->_designBounds->top - 2),
- _screen.pitch, _scene->_designBounds->left - 2, _scene->_designBounds->top - 2,
- _scene->_designBounds->width(), _scene->_designBounds->height());
+ _scene->paint(_sceneWindow->getSurface(), 0, 0);
+ _sceneWindow->setDirty(true);
_sceneDirty = true;
_consoleDirty = true;
- _menuDirty = true;
+ _menu->setDirty(true);
_consoleFullRedraw = true;
-
- _sceneArea.left = _scene->_designBounds->left + kBorderWidth - 2;
- _sceneArea.top = _scene->_designBounds->top + kBorderWidth - 2;
- _sceneArea.setWidth(_scene->_designBounds->width() - 2 * kBorderWidth);
- _sceneArea.setHeight(_scene->_designBounds->height() - 2 * kBorderWidth);
-
- _consoleTextArea.left = _scene->_textBounds->left + kBorderWidth - 2;
- _consoleTextArea.top = _scene->_textBounds->top + kBorderWidth - 2;
- _consoleTextArea.setWidth(_scene->_textBounds->width() - 2 * kBorderWidth);
- _consoleTextArea.setHeight(_scene->_textBounds->height() - 2 * kBorderWidth);
-}
-
-// Render console
-void Gui::drawConsole() {
- if (!_consoleDirty && !_consoleFullRedraw && !_bordersDirty && !_sceneDirty)
- return;
-
- MacWindow *w = _wm.getWindow(_consoleWindowId);
- w->setDimensions(*_scene->_textBounds);
- renderConsole(w->getSurface(), Common::Rect(kBorderWidth - 2, kBorderWidth - 2,
- _scene->_textBounds->width() - kBorderWidth, _scene->_textBounds->height() - kBorderWidth));
- w->draw(&_screen);
- g_system->copyRectToScreen(_screen.getBasePtr(_scene->_textBounds->left - 2, _scene->_textBounds->top - 2),
- _screen.pitch, _scene->_textBounds->left - 2, _scene->_textBounds->top - 2,
- _scene->_textBounds->width(), _scene->_textBounds->height());
}
-void Gui::drawBox(Graphics::ManagedSurface *g, int x, int y, int w, int h) {
- Common::Rect r(x, y, x + w + 1, y + h + 1);
-
- g->fillRect(r, kColorWhite);
- g->frameRect(r, kColorBlack);
-}
-
-void Gui::fillRect(Graphics::ManagedSurface *g, int x, int y, int w, int h, int color) {
- Common::Rect r(x, y, x + w, y + h);
-
- g->fillRect(r, color);
-}
-
-#define ARROW_W 12
-#define ARROW_H 6
-const int arrowPixels[ARROW_H][ARROW_W] = {
- {0,0,0,0,0,1,1,0,0,0,0,0},
- {0,0,0,0,1,1,1,1,0,0,0,0},
- {0,0,0,1,1,1,1,1,1,0,0,0},
- {0,0,1,1,1,1,1,1,1,1,0,0},
- {0,1,1,1,1,1,1,1,1,1,1,0},
- {1,1,1,1,1,1,1,1,1,1,1,1}};
-
-static void drawPixelInverted(int x, int y, int color, void *data) {
- Graphics::ManagedSurface *surface = (Graphics::ManagedSurface *)data;
-
- if (x >= 0 && x < surface->w && y >= 0 && y < surface->h) {
- byte *p = (byte *)surface->getBasePtr(x, y);
+static bool sceneWindowCallback(WindowClick click, Common::Event &event, void *g) {
+ Gui *gui = (Gui *)g;
- *p = *p == kColorWhite ? kColorBlack : kColorWhite;
- }
+ return gui->processSceneEvents(click, event);
}
-void Gui::paintBorder(Graphics::ManagedSurface *g, Common::Rect &r, WindowType windowType, int highlightedPart, float scrollPos, float scrollSize) {
- bool active = false, scrollable = false, closeable = false, drawTitle = false;
- const int size = kBorderWidth;
- int x = r.left - size;
- int y = r.top - size;
- int width = r.width() + 2 * size;
- int height = r.height() + 2 * size;
-
- switch (windowType) {
- case kWindowScene:
- active = _sceneIsActive;
- scrollable = false;
- closeable = _sceneIsActive;
- drawTitle = true;
- break;
- case kWindowConsole:
- active = !_sceneIsActive;
- scrollable = true;
- closeable = !_sceneIsActive;
- drawTitle = false;
- break;
- }
-
- drawBox(g, x, y, size, size);
- drawBox(g, x + width - size - 1, y, size, size);
- drawBox(g, x + width - size - 1, y + height - size - 1, size, size);
- drawBox(g, x, y + height - size - 1, size, size);
- drawBox(g, x + size, y + 2, width - 2 * size - 1, size - 4);
- drawBox(g, x + size, y + height - size + 1, width - 2 * size - 1, size - 4);
- drawBox(g, x + 2, y + size, size - 4, height - 2 * size - 1);
- drawBox(g, x + width - size + 1, y + size, size - 4, height - 2 * size - 1);
-
- if (active) {
- fillRect(g, x + size, y + 5, width - 2 * size - 1, 8);
- fillRect(g, x + size, y + height - 13, width - 2 * size - 1, 8);
- fillRect(g, x + 5, y + size, 8, height - 2 * size - 1);
- if (!scrollable) {
- fillRect(g, x + width - 13, y + size, 8, height - 2 * size - 1);
- } else {
- int x1 = x + width - 15;
- int y1 = y + size + 1;
-
- for (int yy = 0; yy < ARROW_H; yy++) {
- for (int xx = 0; xx < ARROW_W; xx++)
- g->hLine(x1 + xx, y1 + yy, x1 + xx, (arrowPixels[yy][xx] != 0 ? kColorBlack : kColorWhite));
- }
-
- fillRect(g, x + width - 13, y + size + ARROW_H, 8, height - 2 * size - 1 - ARROW_H * 2);
-
- y1 += height - 2 * size - ARROW_H - 2;
- for (int yy = 0; yy < ARROW_H; yy++) {
- for (int xx = 0; xx < ARROW_W; xx++)
- g->hLine(x1 + xx, y1 + yy, x1 + xx, (arrowPixels[ARROW_H - yy - 1][xx] != 0 ? kColorBlack : kColorWhite));
- }
-
- if (highlightedPart == kBorderScrollUp || highlightedPart == kBorderScrollDown) {
- int rx1 = x + width - kBorderWidth + 2;
- int ry1 = y + size + r.height() * scrollPos;
- int rx2 = rx1 + size - 4;
- int ry2 = ry1 + r.height() * scrollSize;
- Common::Rect rr(rx1, ry1, rx2, ry2);
-
- Graphics::drawFilledRect(rr, kColorBlack, drawPixelInverted, g);
- }
- }
- if (closeable) {
- if (highlightedPart == kBorderCloseButton) {
- fillRect(g, x + 6, y + 6, 6, 6);
- } else {
- drawBox(g, x + 5, y + 5, 7, 7);
- }
- }
- }
-
- if (drawTitle) {
- const Graphics::Font *font = getTitleFont();
- int yOff = _builtInFonts ? 3 : 1;
+bool Gui::processSceneEvents(WindowClick click, Common::Event &event) {
+ if (click == kBorderInner && event.type == Common::EVENT_LBUTTONUP) {
+ Designed *obj = _scene->lookUpEntity(event.mouse.x - _sceneWindow->getDimensions().left,
+ event.mouse.y - _sceneWindow->getDimensions().top);
- int w = font->getStringWidth(_scene->_name) + 10;
- int maxWidth = width - size * 2 - 7;
- if (w > maxWidth)
- w = maxWidth;
- drawBox(g, x + (width - w) / 2, y, w, size);
- font->drawString(g, _scene->_name, x + (width - w) / 2 + 5, y + yOff, w, kColorBlack);
- }
+ if (obj != nullptr)
+ _engine->processTurn(NULL, obj);
- if (x < 0) {
- width += x;
- x = 0;
- }
- if (y < 0) {
- height += y;
- y = 0;
+ return true;
}
- if (x + width > _screen.w)
- width = _screen.w - x;
- if (y + height > _screen.h)
- height = _screen.h - y;
- g_system->copyRectToScreen(g->getBasePtr(x, y), g->pitch, x, y, width, height);
+ return false;
}
-void Gui::loadFonts() {
- Common::Archive *dat;
-
- dat = Common::makeZipArchive("wage.dat");
-
- if (!dat) {
- warning("Could not find wage.dat. Falling back to built-in fonts");
- _builtInFonts = true;
-
+// Render console
+void Gui::drawConsole() {
+ if (!_consoleDirty && !_consoleFullRedraw && !_sceneDirty)
return;
- }
-
- Common::ArchiveMemberList list;
- dat->listMembers(list);
- for (Common::ArchiveMemberList::iterator it = list.begin(); it != list.end(); ++it) {
- Common::SeekableReadStream *stream = dat->createReadStreamForMember((*it)->getName());
-
- Graphics::BdfFont *font = Graphics::BdfFont::loadFont(*stream);
-
- delete stream;
-
- Common::String fontName = (*it)->getName();
-
- // Trim the .bdf extension
- for (int i = fontName.size() - 1; i >= 0; --i) {
- if (fontName[i] == '.') {
- while ((uint)i < fontName.size()) {
- fontName.deleteLastChar();
- }
- break;
- }
- }
-
- FontMan.assignFontToName(fontName, font);
-
- debug(2, " %s", fontName.c_str());
- }
+ renderConsole(_consoleWindow->getSurface(), Common::Rect(kBorderWidth - 2, kBorderWidth - 2,
+ _consoleWindow->getDimensions().width(), _consoleWindow->getDimensions().height()));
+ _consoleWindow->setDirty(true);
+}
- _builtInFonts = false;
+static bool consoleWindowCallback(WindowClick click, Common::Event &event, void *g) {
+ Gui *gui = (Gui *)g;
- delete dat;
+ return gui->processConsoleEvents(click, event);
}
+////////////////
+// Menu stuff
+////////////////
void Gui::regenCommandsMenu() {
- _menu->regenCommandsMenu();
+ _menu->createSubMenuFromString(_commandsMenuId, _engine->_world->_commandsMenu.c_str());
}
void Gui::regenWeaponsMenu() {
- _menu->regenWeaponsMenu();
-}
-
-void Gui::processMenuShortCut(byte flags, uint16 ascii) {
- _menu->processMenuShortCut(flags, ascii);
-}
-
-void Gui::mouseMove(int x, int y) {
- if (_menu->_menuActivated) {
- if (_menu->mouseMove(x, y))
- _menuDirty = true;
-
+ if (_engine->_world->_weaponMenuDisabled)
return;
- }
-
- if (_inTextSelection) {
- updateTextSelection(x, y);
- return;
- }
-
- if (_consoleTextArea.contains(x, y)) {
- if (_cursorIsArrow) {
- CursorMan.replaceCursor(macCursorBeam, 11, 16, 3, 8, 3);
- _cursorIsArrow = false;
- }
- } else if (_cursorIsArrow == false) {
- CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3);
- _cursorIsArrow = true;
- }
-}
-
-void Gui::pushArrowCursor() {
- CursorMan.pushCursor(macCursorArrow, 11, 16, 1, 1, 3);
-}
-
-void Gui::popCursor() {
- CursorMan.popCursor();
-}
-
-static int isInBorder(Common::Rect &rect, int x, int y) {
- if (x >= rect.left - kBorderWidth && x < rect.left && y >= rect.top - kBorderWidth && y < rect.top)
- return kBorderCloseButton;
-
- if (x >= rect.right && x < rect.right + kBorderWidth) {
- if (y < rect.top - kBorderWidth)
- return kBorderNone;
-
- if (y >= rect.bottom + kBorderWidth)
- return kBorderNone;
-
- if (y >= rect.top + rect.height() / 2)
- return kBorderScrollDown;
-
- return kBorderScrollUp;
- }
-
- return kBorderNone;
-}
-
-Designed *Gui::mouseUp(int x, int y) {
- if (_menu->_menuActivated) {
- if (_menu->mouseRelease(x, y)) {
- _sceneDirty = true;
- _consoleDirty = true;
- _bordersDirty = true;
- _menuDirty = true;
- }
- return NULL;
- }
-
- if (_inTextSelection) {
- _inTextSelection = false;
-
- if (_selectionEndY == -1 ||
- (_selectionEndX == _selectionStartX && _selectionEndY == _selectionStartY)) {
- _selectionStartY = _selectionEndY = -1;
- _consoleFullRedraw = true;
- _menu->enableCommand(kMenuEdit, kMenuActionCopy, false);
- } else {
- _menu->enableCommand(kMenuEdit, kMenuActionCopy, true);
+ _menu->clearSubMenu(_weaponsMenuId);
- bool cutAllowed = false;
+ Chr *player = _engine->_world->_player;
+ ObjArray *weapons = player->getWeapons(true);
- if (_selectionStartY == _selectionEndY && _selectionStartY == (int)_lines.size() - 1)
- cutAllowed = true;
+ bool empty = true;
- _menu->enableCommand(kMenuEdit, kMenuActionCut, cutAllowed);
- _menu->enableCommand(kMenuEdit, kMenuActionClear, cutAllowed);
- }
- }
+ for (uint i = 0; i < weapons->size(); i++) {
+ Obj *obj = (*weapons)[i];
+ if (obj->_type == Obj::REGULAR_WEAPON ||
+ obj->_type == Obj::THROW_WEAPON ||
+ obj->_type == Obj::MAGICAL_OBJECT) {
+ Common::String command(obj->_operativeVerb);
+ command += " ";
+ command += obj->_name;
- int borderClick;
-
- if (_sceneArea.contains(x, y)) {
- if (!_sceneIsActive) {
- _sceneIsActive = true;
- _bordersDirty = true;
- }
-
- for (ObjList::const_iterator it = _scene->_objs.end(); it != _scene->_objs.begin(); ) {
- it--;
- if ((*it)->_design->isPointOpaque(x - _sceneArea.left + kBorderWidth, y - _sceneArea.top + kBorderWidth))
- return *it;
- }
+ _menu->addMenuSubItem(_weaponsMenuId, command.c_str(), kMenuActionCommand, 0, 0, true);
- for (ChrList::const_iterator it = _scene->_chrs.end(); it != _scene->_chrs.begin(); ) {
- it--;
- if ((*it)->_design->isPointOpaque(x - _sceneArea.left + kBorderWidth, y - _sceneArea.top + kBorderWidth))
- return *it;
- }
- } else if (_consoleTextArea.contains(x, y)) {
- if (_sceneIsActive) {
- _sceneIsActive = false;
- _bordersDirty = true;
- }
- } else if ((borderClick = isInBorder(_consoleTextArea, x, y)) != kBorderNone) {
- _bordersDirty = true;
- int _oldScrollPos = _scrollPos;
-
- switch (borderClick) {
- case kBorderScrollUp:
- _scrollPos = MAX<int>(0, _scrollPos - _consoleLineHeight);
- undrawCursor();
- _cursorY -= (_scrollPos - _oldScrollPos);
- _consoleDirty = true;
- _consoleFullRedraw = true;
- break;
- case kBorderScrollDown:
- _scrollPos = MIN<int>((_lines.size() - 2) * _consoleLineHeight, _scrollPos + _consoleLineHeight);
- undrawCursor();
- _cursorY -= (_scrollPos - _oldScrollPos);
- _consoleDirty = true;
- _consoleFullRedraw = true;
- break;
+ empty = false;
}
}
+ delete weapons;
- return NULL;
+ if (empty)
+ _menu->addMenuSubItem(_weaponsMenuId, "You have no weapons", 0, 0, 0, false);
}
-void Gui::mouseDown(int x, int y) {
- int borderClick;
-
- if (_menu->mouseClick(x, y)) {
- _menuDirty = true;
- } else if (_consoleTextArea.contains(x, y)) {
- startMarking(x, y);
- } else if ((borderClick = isInBorder(_consoleTextArea, x, y)) != kBorderNone) {
- int textFullSize = _lines.size() * _consoleLineHeight + _consoleTextArea.height();
- float scrollPos = (float)_scrollPos / textFullSize;
- float scrollSize = (float)_consoleTextArea.height() / textFullSize;
-
- paintBorder(&_screen, _consoleTextArea, kWindowConsole, borderClick, scrollPos, scrollSize);
- }
-}
-
-int Gui::calcTextX(int x, int textLine) {
- const Graphics::Font *font = getConsoleFont();
-
- if ((uint)textLine >= _lines.size())
- return 0;
-
- Common::String str = _lines[textLine];
-
- x -= _consoleTextArea.left;
-
- for (int i = str.size(); i >= 0; i--) {
- if (font->getStringWidth(str) < x) {
- return i;
- }
-
- str.deleteLastChar();
- }
-
- return 0;
+bool Gui::processEvent(Common::Event &event) {
+ return _wm.processEvent(event);
}
-int Gui::calcTextY(int y) {
- y -= _consoleTextArea.top;
-
- if (y < 0)
- y = 0;
+void menuCommandsCallback(int action, Common::String &text, void *data) {
+ Gui *g = (Gui *)data;
- const int firstLine = _scrollPos / _consoleLineHeight;
- int textLine = (y - _scrollPos % _consoleLineHeight) / _consoleLineHeight + firstLine;
-
- return textLine;
+ g->executeMenuCommand(action, text);
}
-void Gui::startMarking(int x, int y) {
- _selectionStartY = calcTextY(y);
- _selectionStartX = calcTextX(x, _selectionStartY);
-
- _selectionEndY = -1;
+void Gui::executeMenuCommand(int action, Common::String &text) {
+ switch(action) {
+ case kMenuActionAbout:
+ case kMenuActionNew:
+ case kMenuActionOpen:
+ case kMenuActionClose:
+ case kMenuActionSave:
+ case kMenuActionSaveAs:
+ case kMenuActionRevert:
+ case kMenuActionQuit:
+
+ case kMenuActionUndo:
+ actionUndo();
+ break;
+ case kMenuActionCut:
+ actionCut();
+ break;
+ case kMenuActionCopy:
+ actionCopy();
+ break;
+ case kMenuActionPaste:
+ actionPaste();
+ break;
+ case kMenuActionClear:
+ actionClear();
+ break;
- _inTextSelection = true;
-}
+ case kMenuActionCommand:
+ _engine->processTurn(&text, NULL);
+ break;
-void Gui::updateTextSelection(int x, int y) {
- _selectionEndY = calcTextY(y);
- _selectionEndX = calcTextX(x, _selectionEndY);
+ default:
+ warning("Unknown action: %d", action);
- _consoleFullRedraw = true;
+ }
}
} // End of namespace Wage
diff --git a/engines/wage/gui.h b/engines/wage/gui.h
index dc3a593bda..ba1bb5ef3b 100644
--- a/engines/wage/gui.h
+++ b/engines/wage/gui.h
@@ -50,8 +50,8 @@
#include "common/str-array.h"
#include "graphics/font.h"
-#include "graphics/fontman.h"
#include "graphics/managed_surface.h"
+#include "common/events.h"
#include "common/rect.h"
#include "wage/macwindow.h"
@@ -60,27 +60,13 @@
namespace Wage {
class Menu;
+class Scene;
+class WageEngine;
enum {
- kMenuHeight = 20,
- kMenuLeftMargin = 7,
- kMenuSpacing = 13,
- kMenuPadding = 16,
- kMenuDropdownPadding = 14,
- kMenuDropdownItemHeight = 16,
- kMenuItemHeight = 20,
- kDesktopArc = 7,
- kComponentsPadding = 10,
kCursorHeight = 12
};
-enum {
- kPatternSolid = 1,
- kPatternStripes = 2,
- kPatternCheckers = 3,
- kPatternCheckers2 = 4
-};
-
class Gui {
public:
Gui(WageEngine *engine);
@@ -89,17 +75,12 @@ public:
void draw();
void appendText(const char *str);
void clearOutput();
- void mouseMove(int x, int y);
- void mouseDown(int x, int y);
- Designed *mouseUp(int x, int y);
+ bool processEvent(Common::Event &event);
+
void drawInput();
void setSceneDirty() { _sceneDirty = true; }
- const Graphics::Font *getFont(const char *name, Graphics::FontManager::FontUsage fallback);
void regenCommandsMenu();
void regenWeaponsMenu();
- void processMenuShortCut(byte flags, uint16 ascii);
- void pushArrowCursor();
- void popCursor();
void actionCopy();
void actionPaste();
@@ -110,19 +91,15 @@ public:
void disableAllMenus();
void enableNewGameMenus();
- bool builtInFonts() { return _builtInFonts; }
+ bool processSceneEvents(WindowClick click, Common::Event &event);
+ bool processConsoleEvents(WindowClick click, Common::Event &event);
+ void executeMenuCommand(int action, Common::String &text);
private:
void drawScene();
void drawConsole();
void undrawCursor();
- void drawDesktop();
- void paintBorder(Graphics::ManagedSurface *g, Common::Rect &r, WindowType windowType, int highlightedPart = kBorderNone,
- float scrollPos = 0.0, float scrollSize = 0.0);
void renderConsole(Graphics::ManagedSurface *g, const Common::Rect &r);
- void drawBox(Graphics::ManagedSurface *g, int x, int y, int w, int h);
- void fillRect(Graphics::ManagedSurface *g, int x, int y, int w, int h, int color = kColorBlack);
- void loadFonts();
void flowText(Common::String &str);
const Graphics::Font *getConsoleFont();
const Graphics::Font *getTitleFont();
@@ -135,26 +112,24 @@ public:
Graphics::ManagedSurface _screen;
int _cursorX, _cursorY;
bool _cursorState;
- Common::Rect _consoleTextArea;
- bool _builtInFonts;
WageEngine *_engine;
- Patterns _patterns;
-
bool _cursorDirty;
Common::Rect _cursorRect;
bool _cursorOff;
- bool _menuDirty;
+ Scene *_scene;
+
+ MacWindowManager _wm;
+ MacWindow *_sceneWindow;
+ MacWindow *_consoleWindow;
private:
Graphics::ManagedSurface _console;
Menu *_menu;
- Scene *_scene;
bool _sceneDirty;
bool _consoleDirty;
- bool _bordersDirty;
Common::StringArray _out;
Common::StringArray _lines;
@@ -163,10 +138,6 @@ private:
uint _consoleNumLines;
bool _consoleFullRedraw;
- Common::Rect _sceneArea;
- bool _sceneIsActive;
- bool _cursorIsArrow;
-
bool _inTextSelection;
int _selectionStartX;
int _selectionStartY;
@@ -178,9 +149,8 @@ private:
int _inputTextLineNum;
- MacWindowManager _wm;
- int _sceneWindowId;
- int _consoleWindowId;
+ int _commandsMenuId;
+ int _weaponsMenuId;
};
} // End of namespace Wage
diff --git a/engines/wage/menu.cpp b/engines/wage/macmenu.cpp
index 27cbf5e4f5..ed5f5070ff 100644
--- a/engines/wage/menu.cpp
+++ b/engines/wage/macmenu.cpp
@@ -48,15 +48,25 @@
#include "common/system.h"
#include "common/keyboard.h"
-#include "wage/wage.h"
-#include "wage/entities.h"
-#include "wage/design.h"
-#include "wage/gui.h"
-#include "wage/menu.h"
-#include "wage/world.h"
+#include "graphics/primitives.h"
+#include "graphics/font.h"
+
+#include "wage/macwindowmanager.h"
+#include "wage/macwindow.h"
+#include "wage/macmenu.h"
namespace Wage {
+enum {
+ kMenuHeight = 20,
+ kMenuLeftMargin = 7,
+ kMenuSpacing = 13,
+ kMenuPadding = 16,
+ kMenuDropdownPadding = 14,
+ kMenuDropdownItemHeight = 16,
+ kMenuItemHeight = 20
+};
+
struct MenuSubItem {
Common::String text;
int action;
@@ -79,66 +89,65 @@ struct MenuItem {
MenuItem(const char *n) : name(n) {}
};
-struct MenuData {
- int menunum;
- const char *title;
- int action;
- byte shortcut;
- bool enabled;
-} static const menuSubItems[] = {
- { kMenuFile, "New", kMenuActionNew, 0, false },
- { kMenuFile, "Open...", kMenuActionOpen, 0, false },
- { kMenuFile, "Close", kMenuActionClose, 0, true },
- { kMenuFile, "Save", kMenuActionSave, 0, false },
- { kMenuFile, "Save as...", kMenuActionSaveAs, 0, true },
- { kMenuFile, "Revert", kMenuActionRevert, 0, false },
- { kMenuFile, "Quit", kMenuActionQuit, 0, true },
-
- { kMenuEdit, "Undo", kMenuActionUndo, 'Z', false },
- { kMenuEdit, NULL, 0, 0, false },
- { kMenuEdit, "Cut", kMenuActionCut, 'K', false },
- { kMenuEdit, "Copy", kMenuActionCopy, 'C', false },
- { kMenuEdit, "Paste", kMenuActionPaste, 'V', false },
- { kMenuEdit, "Clear", kMenuActionClear, 'B', false },
-
- { 0, NULL, 0, 0, false }
-};
+Menu::Menu(int id, const Common::Rect &bounds, MacWindowManager *wm)
+ : BaseMacWindow(id, false, wm) {
+ _font = getMenuFont();
-Menu::Menu(Gui *gui) : _gui(gui) {
- assert(_gui->_engine);
- assert(_gui->_engine->_world);
+ _screen.create(bounds.width(), bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
- _font = getMenuFont();
+ _bbox.left = 0;
+ _bbox.top = 0;
+ _bbox.right = _screen.w;
+ _bbox.bottom = kMenuHeight;
+
+ _menuActivated = false;
+ _activeItem = -1;
+ _activeSubItem = -1;
+
+ _ccallback = NULL;
+ _cdata = NULL;
+
+ _tempSurface.create(_screen.w, _font->getFontHeight(), Graphics::PixelFormat::createFormatCLUT8());
+}
+
+Menu::~Menu() {
+ for (uint i = 0; i < _items.size(); i++) {
+ for (uint j = 0; j < _items[i]->subitems.size(); j++)
+ delete _items[i]->subitems[j];
+ delete _items[i];
+ }
+}
- MenuItem *about = new MenuItem(_gui->_builtInFonts ? "\xa9" : "\xf0"); // (c) Symbol as the most resembling apple
+void Menu::addStaticMenus(const MenuData *data) {
+ MenuItem *about = new MenuItem(_wm->hasBuiltInFonts() ? "\xa9" : "\xf0"); // (c) Symbol as the most resembling apple
_items.push_back(about);
- _items[0]->subitems.push_back(new MenuSubItem(_gui->_engine->_world->getAboutMenuItemName(), kMenuActionAbout));
- MenuItem *file = new MenuItem("File");
- _items.push_back(file);
+ for (int i = 0; data[i].menunum; i++) {
+ const MenuData *m = &data[i];
- MenuItem *edit = new MenuItem("Edit");
- _items.push_back(edit);
+ if (m->menunum == kMenuHighLevel) {
+ MenuItem *item = new MenuItem(m->title);
+ _items.push_back(item);
- for (int i = 0; menuSubItems[i].menunum; i++) {
- const MenuData *m = &menuSubItems[i];
+ continue;
+ }
_items[m->menunum]->subitems.push_back(new MenuSubItem(m->title, m->action, 0, m->shortcut, m->enabled));
}
+}
- _commands = new MenuItem(_gui->_engine->_world->_commandsMenuName.c_str());
- _items.push_back(_commands);
- regenCommandsMenu();
-
- _weapons = NULL;
+int Menu::addMenuItem(const char *name) {
+ MenuItem *i = new MenuItem(name);
+ _items.push_back(i);
- if (!_gui->_engine->_world->_weaponMenuDisabled) {
- _weapons = new MenuItem(_gui->_engine->_world->_weaponsMenuName.c_str());
- _items.push_back(_weapons);
+ return _items.size() - 1;
+}
- regenWeaponsMenu();
- }
+void Menu::addMenuSubItem(int id, const char *text, int action, int style, char shortcut, bool enabled) {
+ _items[id]->subitems.push_back(new MenuSubItem(text, action, style, shortcut, enabled));
+}
+void Menu::calcDimensions() {
// Calculate menu dimensions
int y = 1;
int x = 18;
@@ -150,47 +159,29 @@ Menu::Menu(Gui *gui) : _gui(gui) {
_items[i]->bbox.left = x - kMenuLeftMargin;
_items[i]->bbox.top = y;
_items[i]->bbox.right = x + w + kMenuSpacing - kMenuLeftMargin;
- _items[i]->bbox.bottom = y + _font->getFontHeight() + (_gui->_builtInFonts ? 3 : 2);
+ _items[i]->bbox.bottom = y + _font->getFontHeight() + (_wm->hasBuiltInFonts() ? 3 : 2);
}
calcMenuBounds(_items[i]);
x += w + kMenuSpacing;
}
-
- _bbox.left = 0;
- _bbox.top = 0;
- _bbox.right = _gui->_screen.w - 1;
- _bbox.bottom = kMenuHeight - 1;
-
- _menuActivated = false;
- _activeItem = -1;
- _activeSubItem = -1;
-
- _screenCopy.create(_gui->_screen.w, _gui->_screen.h, Graphics::PixelFormat::createFormatCLUT8());
- _tempSurface.create(_gui->_screen.w, _font->getFontHeight(), Graphics::PixelFormat::createFormatCLUT8());
-}
-
-Menu::~Menu() {
- for (uint i = 0; i < _items.size(); i++) {
- for (uint j = 0; j < _items[i]->subitems.size(); j++)
- delete _items[i]->subitems[j];
- delete _items[i];
- }
}
-void Menu::regenCommandsMenu() {
- for (uint j = 0; j < _commands->subitems.size(); j++)
- delete _commands->subitems[j];
+void Menu::clearSubMenu(int id) {
+ MenuItem *menu = _items[id];
- _commands->subitems.clear();
+ for (uint j = 0; j < menu->subitems.size(); j++)
+ delete menu->subitems[j];
- createCommandsMenu(_commands);
- calcMenuBounds(_commands);
+ menu->subitems.clear();
}
-void Menu::createCommandsMenu(MenuItem *menu) {
- Common::String string(_gui->_engine->_world->_commandsMenu);
+void Menu::createSubMenuFromString(int id, const char *str) {
+ clearSubMenu(id);
+
+ MenuItem *menu = _items[id];
+ Common::String string(str);
Common::String item;
@@ -253,45 +244,12 @@ void Menu::createCommandsMenu(MenuItem *menu) {
item.clear();
}
-}
-
-void Menu::regenWeaponsMenu() {
- if (_gui->_engine->_world->_weaponMenuDisabled)
- return;
-
- for (uint j = 0; j < _weapons->subitems.size(); j++)
- delete _weapons->subitems[j];
-
- _weapons->subitems.clear();
-
- createWeaponsMenu(_weapons);
- calcMenuBounds(_weapons);
-}
-
-void Menu::createWeaponsMenu(MenuItem *menu) {
- Chr *player = _gui->_engine->_world->_player;
- ObjArray *weapons = player->getWeapons(true);
-
- for (uint i = 0; i < weapons->size(); i++) {
- Obj *obj = (*weapons)[i];
- if (obj->_type == Obj::REGULAR_WEAPON ||
- obj->_type == Obj::THROW_WEAPON ||
- obj->_type == Obj::MAGICAL_OBJECT) {
- Common::String command(obj->_operativeVerb);
- command += " ";
- command += obj->_name;
-
- menu->subitems.push_back(new MenuSubItem(command.c_str(), kMenuActionCommand, 0, 0, true));
- }
- }
- delete weapons;
- if (menu->subitems.empty())
- menu->subitems.push_back(new MenuSubItem("You have no weapons", 0, 0, 0, false));
+ calcMenuBounds(menu);
}
const Graphics::Font *Menu::getMenuFont() {
- return _gui->getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
+ return _wm->getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
}
const char *Menu::getAcceleratorString(MenuSubItem *item, const char *prefix) {
@@ -299,7 +257,7 @@ const char *Menu::getAcceleratorString(MenuSubItem *item, const char *prefix) {
*res = 0;
if (item->shortcut != 0)
- sprintf(res, "%s%c%c", prefix, (_gui->_builtInFonts ? '^' : '\x11'), item->shortcut);
+ sprintf(res, "%s%c%c", prefix, (_wm->hasBuiltInFonts() ? '^' : '\x11'), item->shortcut);
return res;
}
@@ -338,14 +296,35 @@ void Menu::calcMenuBounds(MenuItem *menu) {
menu->subbbox.bottom = y2;
}
-void Menu::render() {
+static void drawPixelPlain(int x, int y, int color, void *data) {
+ Graphics::ManagedSurface *surface = (Graphics::ManagedSurface *)data;
+
+ if (x >= 0 && x < surface->w && y >= 0 && y < surface->h)
+ *((byte *)surface->getBasePtr(x, y)) = (byte)color;
+}
+
+static void drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color) {
+ Graphics::drawRoundRect(rect, arc, color, true, drawPixelPlain, surface);
+}
+
+bool Menu::draw(Graphics::ManagedSurface *g, bool forceRedraw) {
Common::Rect r(_bbox);
- Design::drawFilledRoundRect(&_gui->_screen, r, kDesktopArc, kColorWhite, _gui->_patterns, kPatternSolid);
+ if (!_contentIsDirty && !forceRedraw)
+ return false;
+
+ _contentIsDirty = false;
+
+ _screen.clear(kColorGreen);
+
+ drawFilledRoundRect(&_screen, r, kDesktopArc, kColorWhite);
r.top = 7;
- Design::drawFilledRect(&_gui->_screen, r, kColorWhite, _gui->_patterns, kPatternSolid);
+ _screen.fillRect(r, kColorWhite);
r.top = kMenuHeight - 1;
- Design::drawFilledRect(&_gui->_screen, r, kColorBlack, _gui->_patterns, kPatternSolid);
+ r.bottom++;
+ _screen.fillRect(r, kColorGreen);
+ r.bottom--;
+ _screen.fillRect(r, kColorBlack);
for (uint i = 0; i < _items.size(); i++) {
int color = kColorBlack;
@@ -355,19 +334,24 @@ void Menu::render() {
Common::Rect hbox = it->bbox;
hbox.left -= 1;
- hbox.right += 2;
+ hbox.right += 3;
+ hbox.bottom += 1;
- Design::drawFilledRect(&_gui->_screen, hbox, kColorBlack, _gui->_patterns, kPatternSolid);
+ _screen.fillRect(hbox, kColorBlack);
color = kColorWhite;
if (!it->subitems.empty())
renderSubmenu(it);
}
- _font->drawString(&_gui->_screen, it->name, it->bbox.left + kMenuLeftMargin, it->bbox.top + (_gui->_builtInFonts ? 2 : 1), it->bbox.width(), color);
+ _font->drawString(&_screen, it->name, it->bbox.left + kMenuLeftMargin, it->bbox.top + (_wm->hasBuiltInFonts() ? 2 : 1), it->bbox.width(), color);
}
- g_system->copyRectToScreen(_gui->_screen.getPixels(), _gui->_screen.pitch, 0, 0, _gui->_screen.w, kMenuHeight);
+ g->transBlitFrom(_screen, kColorGreen);
+
+ g_system->copyRectToScreen(g->getPixels(), g->pitch, 0, 0, g->w, g->h);
+
+ return true;
}
void Menu::renderSubmenu(MenuItem *menu) {
@@ -376,10 +360,12 @@ void Menu::renderSubmenu(MenuItem *menu) {
if (r->width() == 0 || r->height() == 0)
return;
- Design::drawFilledRect(&_gui->_screen, *r, kColorWhite, _gui->_patterns, kPatternSolid);
- Design::drawRect(&_gui->_screen, *r, 1, kColorBlack, _gui->_patterns, kPatternSolid);
- Design::drawVLine(&_gui->_screen, r->right + 1, r->top + 3, r->bottom + 1, 1, kColorBlack, _gui->_patterns, kPatternSolid);
- Design::drawHLine(&_gui->_screen, r->left + 3, r->right + 1, r->bottom + 1, 1, kColorBlack, _gui->_patterns, kPatternSolid);
+ _screen.fillRect(*r, kColorWhite);
+ _screen.frameRect(*r, kColorBlack);
+ _screen.vLine(r->right, r->top + 3, r->bottom + 1, kColorBlack);
+ _screen.vLine(r->right + 1, r->top + 3, r->bottom + 1, kColorBlack);
+ _screen.hLine(r->left + 3, r->bottom, r->right + 1, kColorBlack);
+ _screen.hLine(r->left + 3, r->bottom + 1, r->right + 1, kColorBlack);
int x = r->left + kMenuDropdownPadding;
int y = r->top + 1;
@@ -391,13 +377,13 @@ void Menu::renderSubmenu(MenuItem *menu) {
int color = kColorBlack;
if (i == (uint)_activeSubItem && !text.empty() && menu->subitems[i]->enabled) {
color = kColorWhite;
- Common::Rect trect(r->left, y - (_gui->_builtInFonts ? 1 : 0), r->right, y + _font->getFontHeight());
+ Common::Rect trect(r->left, y - (_wm->hasBuiltInFonts() ? 1 : 0), r->right, y + _font->getFontHeight());
- Design::drawFilledRect(&_gui->_screen, trect, kColorBlack, _gui->_patterns, kPatternSolid);
+ _screen.fillRect(trect, kColorBlack);
}
if (!text.empty()) {
- Graphics::ManagedSurface *s = &_gui->_screen;
+ Graphics::ManagedSurface *s = &_screen;
int tx = x, ty = y;
if (!menu->subitems[i]->enabled) {
@@ -419,8 +405,8 @@ void Menu::renderSubmenu(MenuItem *menu) {
// fake it here
for (int ii = 0; ii < _tempSurface.h; ii++) {
const byte *src = (const byte *)_tempSurface.getBasePtr(0, ii);
- byte *dst = (byte *)_gui->_screen.getBasePtr(x, y+ii);
- byte pat = _gui->_patterns[kPatternCheckers2 - 1][ii % 8];
+ byte *dst = (byte *)_screen.getBasePtr(x, y+ii);
+ byte pat = _wm->getPatterns()[kPatternCheckers2 - 1][ii % 8];
for (int j = 0; j < r->width(); j++) {
if (*src != kColorGreen && (pat & (1 << (7 - (x + j) % 8))))
*dst = *src;
@@ -430,20 +416,51 @@ void Menu::renderSubmenu(MenuItem *menu) {
}
}
} else { // Delimiter
- Design::drawHLine(&_gui->_screen, r->left + 1, r->right - 1, y + kMenuDropdownItemHeight / 2, 1, kColorBlack, _gui->_patterns, kPatternStripes);
+ bool flip = r->left & 2;
+ byte *ptr = (byte *)_screen.getBasePtr(r->left + 1, y + kMenuDropdownItemHeight / 2);
+ for (int xx = r->left + 1; xx <= r->right - 1; xx++, ptr++) {
+ *ptr = flip ? kColorBlack : kColorWhite;
+ flip = !flip;
+ }
}
y += kMenuDropdownItemHeight;
}
- g_system->copyRectToScreen(_gui->_screen.getBasePtr(r->left, r->top), _gui->_screen.pitch, r->left, r->top, r->width() + 3, r->height() + 3);
+ _contentIsDirty = true;
+ //g_system->copyRectToScreen(_screen.getBasePtr(r->left, r->top), _screen.pitch, r->left, r->top, r->width() + 2, r->height() + 2);
+}
+
+bool Menu::processEvent(Common::Event &event) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ return keyEvent(event);
+ case Common::EVENT_LBUTTONDOWN:
+ return mouseClick(event.mouse.x, event.mouse.y);
+ case Common::EVENT_LBUTTONUP:
+ return mouseRelease(event.mouse.x, event.mouse.y);
+ case Common::EVENT_MOUSEMOVE:
+ return mouseMove(event.mouse.x, event.mouse.y);
+ default:
+ return false;
+ }
+}
+
+bool Menu::keyEvent(Common::Event &event) {
+ if (event.type != Common::EVENT_KEYDOWN)
+ return false;
+
+ if (event.kbd.flags & (Common::KBD_ALT | Common::KBD_CTRL | Common::KBD_META)) {
+ if (event.kbd.ascii >= 0x20 && event.kbd.ascii <= 0x7f) {
+ return processMenuShortCut(event.kbd.flags, event.kbd.ascii);
+ }
+ }
+
+ return false;
}
bool Menu::mouseClick(int x, int y) {
if (_bbox.contains(x, y)) {
- if (!_menuActivated)
- _screenCopy.copyFrom(_gui->_screen);
-
for (uint i = 0; i < _items.size(); i++)
if (_items[i]->bbox.contains(x, y)) {
if ((uint)_activeItem == i)
@@ -454,14 +471,15 @@ bool Menu::mouseClick(int x, int y) {
r.right += 3;
r.bottom += 3;
- _gui->_screen.copyRectToSurface(_screenCopy, r.left, r.top, r);
- g_system->copyRectToScreen(_gui->_screen.getBasePtr(r.left, r.top), _gui->_screen.pitch, r.left, r.top, r.width() + 1, r.height() + 1);
+ _wm->setFullRefresh(true);
}
_activeItem = i;
_activeSubItem = -1;
_menuActivated = true;
+ _contentIsDirty = true;
+
return true;
}
} else if (_menuActivated && _items[_activeItem]->subbbox.contains(x, y)) {
@@ -472,11 +490,13 @@ bool Menu::mouseClick(int x, int y) {
_activeSubItem = numSubItem;
renderSubmenu(_items[_activeItem]);
+ _contentIsDirty = true;
}
} else if (_menuActivated && _activeItem != -1) {
_activeSubItem = -1;
renderSubmenu(_items[_activeItem]);
+ _contentIsDirty = true;
}
return false;
@@ -495,77 +515,49 @@ bool Menu::mouseRelease(int x, int y) {
_menuActivated = false;
if (_activeItem != -1 && _activeSubItem != -1 && _items[_activeItem]->subitems[_activeSubItem]->enabled)
- executeCommand(_items[_activeItem]->subitems[_activeSubItem]);
+ (*_ccallback)(_items[_activeItem]->subitems[_activeSubItem]->action,
+ _items[_activeItem]->subitems[_activeSubItem]->text, _cdata);
_activeItem = -1;
_activeSubItem = -1;
+ _wm->setFullRefresh(true);
+
return true;
}
return false;
}
-void Menu::executeCommand(MenuSubItem *subitem) {
- switch(subitem->action) {
- case kMenuActionAbout:
- case kMenuActionNew:
- case kMenuActionOpen:
- case kMenuActionClose:
- case kMenuActionSave:
- case kMenuActionSaveAs:
- case kMenuActionRevert:
- case kMenuActionQuit:
-
- case kMenuActionUndo:
- _gui->actionUndo();
- break;
- case kMenuActionCut:
- _gui->actionCut();
- break;
- case kMenuActionCopy:
- _gui->actionCopy();
- break;
- case kMenuActionPaste:
- _gui->actionPaste();
- break;
- case kMenuActionClear:
- _gui->actionClear();
- break;
-
- case kMenuActionCommand:
- _gui->_engine->processTurn(&subitem->text, NULL);
- break;
-
- default:
- warning("Unknown action: %d", subitem->action);
-
- }
-}
-
-void Menu::processMenuShortCut(byte flags, uint16 ascii) {
+bool Menu::processMenuShortCut(byte flags, uint16 ascii) {
ascii = tolower(ascii);
if (flags & (Common::KBD_CTRL | Common::KBD_META)) {
for (uint i = 0; i < _items.size(); i++)
for (uint j = 0; j < _items[i]->subitems.size(); j++)
if (_items[i]->subitems[j]->enabled && tolower(_items[i]->subitems[j]->shortcut) == ascii) {
- executeCommand(_items[i]->subitems[j]);
- break;
+ (*_ccallback)(_items[i]->subitems[j]->action, _items[i]->subitems[j]->text, _cdata);
+ return true;
}
}
+
+ return false;
}
void Menu::enableCommand(int menunum, int action, bool state) {
for (uint i = 0; i < _items[menunum]->subitems.size(); i++)
if (_items[menunum]->subitems[i]->action == action)
_items[menunum]->subitems[i]->enabled = state;
+
+ _contentIsDirty = true;
}
void Menu::disableAllMenus() {
for (uint i = 1; i < _items.size(); i++) // Leave About menu on
for (uint j = 0; j < _items[i]->subitems.size(); j++)
_items[i]->subitems[j]->enabled = false;
+
+ _contentIsDirty = true;
}
} // End of namespace Wage
diff --git a/engines/wage/menu.h b/engines/wage/macmenu.h
index 916ef6d50e..e73e4c48a9 100644
--- a/engines/wage/menu.h
+++ b/engines/wage/macmenu.h
@@ -45,8 +45,8 @@
*
*/
-#ifndef WAGE_MENU_H
-#define WAGE_MENU_H
+#ifndef WAGE_MACMENU_H
+#define WAGE_MACMENU_H
namespace Wage {
@@ -64,6 +64,7 @@ enum {
};
enum {
+ kMenuHighLevel = -1,
kMenuAbout = 0,
kMenuFile = 1,
kMenuEdit = 2,
@@ -90,28 +91,42 @@ enum {
kMenuActionCommand
};
-class Menu {
+struct MenuData {
+ int menunum;
+ const char *title;
+ int action;
+ byte shortcut;
+ bool enabled;
+};
+
+class Menu : public BaseMacWindow {
public:
- Menu(Gui *gui);
+ Menu(int id, const Common::Rect &bounds, MacWindowManager *wm);
~Menu();
- void render();
- bool mouseClick(int x, int y);
- bool mouseRelease(int x, int y);
- bool mouseMove(int x, int y);
+ void setCommandsCallback(void (*callback)(int, Common::String &, void *), void *data) { _ccallback = callback; _cdata = data; }
+
+ void addStaticMenus(const MenuData *data);
+ void calcDimensions();
+
+ int addMenuItem(const char *name);
+ void addMenuSubItem(int id, const char *text, int action, int style = 0, char shortcut = 0, bool enabled = true);
+ void createSubMenuFromString(int id, const char *string);
+ void clearSubMenu(int id);
+
+ bool draw(Graphics::ManagedSurface *g, bool forceRedraw = false);
+ bool processEvent(Common::Event &event);
- void regenCommandsMenu();
- void regenWeaponsMenu();
- void processMenuShortCut(byte flags, uint16 ascii);
void enableCommand(int menunum, int action, bool state);
void disableAllMenus();
- bool _menuActivated;
+ void setActive(bool active) { _menuActivated = active; }
+ bool hasAllFocus() { return _menuActivated; }
+
Common::Rect _bbox;
private:
- Gui *_gui;
- Graphics::ManagedSurface _screenCopy;
+ Graphics::ManagedSurface _screen;
Graphics::ManagedSurface _tempSurface;
private:
@@ -120,18 +135,25 @@ private:
int calculateMenuWidth(MenuItem *menu);
void calcMenuBounds(MenuItem *menu);
void renderSubmenu(MenuItem *menu);
- void createCommandsMenu(MenuItem *menu);
- void createWeaponsMenu(MenuItem *menu);
- void executeCommand(MenuSubItem *subitem);
+
+ bool keyEvent(Common::Event &event);
+ bool mouseClick(int x, int y);
+ bool mouseRelease(int x, int y);
+ bool mouseMove(int x, int y);
+
+ bool processMenuShortCut(byte flags, uint16 ascii);
Common::Array<MenuItem *> _items;
- MenuItem *_weapons;
- MenuItem *_commands;
const Graphics::Font *_font;
+ bool _menuActivated;
+
int _activeItem;
int _activeSubItem;
+
+ void (*_ccallback)(int action, Common::String &text, void *data);
+ void *_cdata;
};
} // End of namespace Wage
diff --git a/engines/wage/macwindow.cpp b/engines/wage/macwindow.cpp
index 41d842286a..8903936061 100644
--- a/engines/wage/macwindow.cpp
+++ b/engines/wage/macwindow.cpp
@@ -45,26 +45,49 @@
*
*/
+#include "graphics/font.h"
#include "graphics/primitives.h"
+#include "common/events.h"
-#include "wage/wage.h"
-#include "wage/gui.h"
#include "wage/macwindow.h"
+#include "wage/macwindowmanager.h"
namespace Wage {
-MacWindow::MacWindow(bool scrollable) : _scrollable(scrollable) {
+BaseMacWindow::BaseMacWindow(int id, bool editable, MacWindowManager *wm) :
+ _id(id), _editable(editable), _wm(wm) {
+ _callback = 0;
+ _dataPtr = 0;
+
+ _contentIsDirty = true;
+
+ _type = kWindowUnknown;
+}
+
+MacWindow::MacWindow(int id, bool scrollable, bool resizable, bool editable, MacWindowManager *wm) :
+ BaseMacWindow(id, editable, wm), _scrollable(scrollable), _resizable(resizable) {
_active = false;
_borderIsDirty = true;
_highlightedPart = kBorderNone;
_scrollPos = _scrollSize = 0.0;
+
+ _beingDragged = false;
+ _beingResized = false;
+
+ _draggedX = _draggedY = 0;
+
+ _type = kWindowWindow;
}
MacWindow::~MacWindow() {
}
+const Graphics::Font *MacWindow::getTitleFont() {
+ return _wm->getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
+}
+
void MacWindow::setActive(bool active) {
if (active == _active)
return;
@@ -86,34 +109,47 @@ void MacWindow::resize(int w, int h) {
_dims.setWidth(w);
_dims.setHeight(h);
+
+ updateInnerDims();
+
+ _contentIsDirty = true;
+ _borderIsDirty = true;
}
void MacWindow::move(int x, int y) {
+ if (_dims.left == x && _dims.top == y)
+ return;
+
_dims.moveTo(x, y);
+ updateInnerDims();
+
+ _contentIsDirty = true;
}
void MacWindow::setDimensions(const Common::Rect &r) {
resize(r.width(), r.height());
_dims.moveTo(r.left, r.top);
+ updateInnerDims();
+
+ _contentIsDirty = true;
}
-void MacWindow::draw(Graphics::ManagedSurface *g, bool forceRedraw) {
+bool MacWindow::draw(Graphics::ManagedSurface *g, bool forceRedraw) {
+ if (!_borderIsDirty && !_contentIsDirty && !forceRedraw)
+ return false;
+
if (_borderIsDirty || forceRedraw)
drawBorder();
+ _contentIsDirty = false;
+
// Compose
_composeSurface.blitFrom(_surface, Common::Rect(0, 0, _surface.w - 2, _surface.h - 2), Common::Point(2, 2));
_composeSurface.transBlitFrom(_borderSurface, kColorGreen);
g->transBlitFrom(_composeSurface, _composeSurface.getBounds(), Common::Point(_dims.left - 2, _dims.top - 2), kColorGreen2);
-}
-const Graphics::Font *MacWindow::getTitleFont() {
- return ((WageEngine *)g_engine)->_gui->getFont("Chicago-12", Graphics::FontManager::kBigGUIFont);
-}
-
-bool MacWindow::builtInFonts() {
- return ((WageEngine *)g_engine)->_gui->builtInFonts();
+ return true;
}
#define ARROW_W 12
@@ -136,6 +172,11 @@ static void drawPixelInverted(int x, int y, int color, void *data) {
}
}
+void MacWindow::updateInnerDims() {
+ _innerDims = _dims;
+ _innerDims.grow(-kBorderWidth);
+}
+
void MacWindow::drawBorder() {
_borderIsDirty = false;
@@ -163,11 +204,11 @@ void MacWindow::drawBorder() {
drawBox(g, x + width - size + 1, y + size, size - 4, height - 2 * size - 1);
if (active) {
- fillRect(g, x + size, y + 5, width - 2 * size - 1, 8);
- fillRect(g, x + size, y + height - 13, width - 2 * size - 1, 8);
- fillRect(g, x + 5, y + size, 8, height - 2 * size - 1);
+ fillRect(g, x + size, y + 5, width - 2 * size - 1, 8, kColorBlack);
+ fillRect(g, x + size, y + height - 13, width - 2 * size - 1, 8, kColorBlack);
+ fillRect(g, x + 5, y + size, 8, height - 2 * size - 1, kColorBlack);
if (!scrollable) {
- fillRect(g, x + width - 13, y + size, 8, height - 2 * size - 1);
+ fillRect(g, x + width - 13, y + size, 8, height - 2 * size - 1, kColorBlack);
} else {
int x1 = x + width - 15;
int y1 = y + size + 1;
@@ -177,7 +218,7 @@ void MacWindow::drawBorder() {
g->hLine(x1 + xx, y1 + yy, x1 + xx, (arrowPixels[yy][xx] != 0 ? kColorBlack : kColorWhite));
}
- fillRect(g, x + width - 13, y + size + ARROW_H, 8, height - 2 * size - 1 - ARROW_H * 2);
+ fillRect(g, x + width - 13, y + size + ARROW_H, 8, height - 2 * size - 1 - ARROW_H * 2, kColorBlack);
y1 += height - 2 * size - ARROW_H - 2;
for (int yy = 0; yy < ARROW_H; yy++) {
@@ -197,7 +238,7 @@ void MacWindow::drawBorder() {
}
if (closeable) {
if (_highlightedPart == kBorderCloseButton) {
- fillRect(g, x + 6, y + 6, 6, 6);
+ fillRect(g, x + 6, y + 6, 6, 6, kColorBlack);
} else {
drawBox(g, x + 5, y + 5, 7, 7);
}
@@ -206,7 +247,7 @@ void MacWindow::drawBorder() {
if (drawTitle) {
const Graphics::Font *font = getTitleFont();
- int yOff = builtInFonts() ? 3 : 1;
+ int yOff = _wm->hasBuiltInFonts() ? 3 : 1;
int w = font->getStringWidth(_title) + 10;
int maxWidth = width - size * 2 - 7;
@@ -217,6 +258,24 @@ void MacWindow::drawBorder() {
}
}
+void MacWindow::setHighlight(WindowClick highlightedPart) {
+ if (_highlightedPart == highlightedPart)
+ return;
+
+ _highlightedPart = highlightedPart;
+ _borderIsDirty = true;
+ }
+
+ void MacWindow::setScroll(float scrollPos, float scrollSize) {
+ if (_scrollPos == scrollPos && _scrollSize == scrollSize)
+ return;
+
+ _scrollPos = scrollPos;
+ _scrollSize = scrollSize;
+ _borderIsDirty = true;
+ }
+
+
void MacWindow::drawBox(Graphics::ManagedSurface *g, int x, int y, int w, int h) {
Common::Rect r(x, y, x + w + 1, y + h + 1);
@@ -230,4 +289,88 @@ void MacWindow::fillRect(Graphics::ManagedSurface *g, int x, int y, int w, int h
g->fillRect(r, color);
}
+WindowClick MacWindow::isInBorder(int x, int y) {
+ if (_innerDims.contains(x, y))
+ return kBorderInner;
+
+ if (x >= _innerDims.left - kBorderWidth && x < _innerDims.left && y >= _innerDims.top - kBorderWidth && y < _innerDims.top)
+ return kBorderCloseButton;
+
+ if (_resizable)
+ if (x >= _innerDims.right && x < _innerDims.right + kBorderWidth && y >= _innerDims.bottom && y < _innerDims.bottom + kBorderWidth)
+ return kBorderResizeButton;
+
+ if (_scrollable && x >= _innerDims.right && x < _innerDims.right + kBorderWidth) {
+ if (y < _innerDims.top - kBorderWidth)
+ return kBorderBorder;
+
+ if (y >= _innerDims.bottom + kBorderWidth)
+ return kBorderBorder;
+
+ if (y >= _innerDims.top + _innerDims.height() / 2)
+ return kBorderScrollDown;
+
+ return kBorderScrollUp;
+ }
+
+ return kBorderBorder;
+}
+
+bool MacWindow::processEvent(Common::Event &event) {
+ WindowClick click = isInBorder(event.mouse.x, event.mouse.y);
+
+ switch (event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ if (_beingDragged) {
+ _dims.translate(event.mouse.x - _draggedX, event.mouse.y - _draggedY);
+ updateInnerDims();
+
+ _draggedX = event.mouse.x;
+ _draggedY = event.mouse.y;
+
+ _wm->setFullRefresh(true);
+ }
+
+ if (_beingResized) {
+ resize(MAX(kBorderWidth * 4, _dims.width() + event.mouse.x - _draggedX),
+ MAX(kBorderWidth * 4, _dims.height() + event.mouse.y - _draggedY));
+
+ _draggedX = event.mouse.x;
+ _draggedY = event.mouse.y;
+
+ _wm->setFullRefresh(true);
+ (*_callback)(click, event, _dataPtr);
+ }
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ setHighlight(click);
+
+ if (click == kBorderBorder) {
+ _beingDragged = true;
+
+ _draggedX = event.mouse.x;
+ _draggedY = event.mouse.y;
+ }
+
+ if (click == kBorderResizeButton) {
+ _beingResized = true;
+
+ _draggedX = event.mouse.x;
+ _draggedY = event.mouse.y;
+ }
+
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _beingDragged = false;
+ _beingResized = false;
+
+ setHighlight(kBorderNone);
+ break;
+ default:
+ return false;
+ }
+
+ return (*_callback)(click, event, _dataPtr);
+}
+
} // End of namespace Wage
diff --git a/engines/wage/macwindow.h b/engines/wage/macwindow.h
index e635528c23..4c6e9efeff 100644
--- a/engines/wage/macwindow.h
+++ b/engines/wage/macwindow.h
@@ -52,55 +52,106 @@
namespace Wage {
+class MacWindowManager;
+
enum WindowType {
- kWindowScene,
- kWindowConsole
+ kWindowUnknown,
+ kWindowWindow,
+ kWindowMenu
};
enum {
kBorderWidth = 17
};
-enum BorderHighlight {
+enum WindowClick {
kBorderNone = 0,
kBorderScrollUp,
kBorderScrollDown,
- kBorderCloseButton
+ kBorderCloseButton,
+ kBorderInner,
+ kBorderBorder,
+ kBorderResizeButton
};
-class MacWindow {
+class BaseMacWindow {
public:
- MacWindow(bool scrollable);
- ~MacWindow();
+ BaseMacWindow(int id, bool editable, MacWindowManager *wm);
+ virtual ~BaseMacWindow() {}
+
+ const Common::Rect &getDimensions() { return _dims; }
+ int getId() { return _id; }
+ WindowType getType() { return _type; }
+ bool isEditable() { return _editable; }
+ Graphics::ManagedSurface *getSurface() { return &_surface; }
+ virtual void setActive(bool active) = 0;
+ void setDirty(bool dirty) { _contentIsDirty = dirty; }
+
+ virtual bool draw(Graphics::ManagedSurface *g, bool forceRedraw = false) = 0;
+ virtual bool processEvent(Common::Event &event) = 0;
+
+ virtual bool hasAllFocus() = 0;
+
+ void setCallback(bool (*callback)(WindowClick, Common::Event &, void *), void *data) { _callback = callback; _dataPtr = data; }
+
+protected:
+ int _id;
+ WindowType _type;
+
+ bool _editable;
+
+ Graphics::ManagedSurface _surface;
+ bool _contentIsDirty;
+
+ Common::Rect _dims;
+
+ bool (*_callback)(WindowClick, Common::Event &, void *);
+ void *_dataPtr;
+
+ MacWindowManager *_wm;
+};
+
+class MacWindow : public BaseMacWindow {
+public:
+ MacWindow(int id, bool scrollable, bool resizable, bool editable, MacWindowManager *wm);
+ virtual ~MacWindow();
void move(int x, int y);
void resize(int w, int h);
void setDimensions(const Common::Rect &r);
- void draw(Graphics::ManagedSurface *g, bool forceRedraw = false);
+ const Common::Rect &getInnerDimensions() { return _innerDims; }
+
+ bool draw(Graphics::ManagedSurface *g, bool forceRedraw = false);
+
void setActive(bool active);
- Graphics::ManagedSurface *getSurface() { return &_surface; }
void setTitle(Common::String &title) { _title = title; }
- void setHighlight(BorderHighlight highlightedPart) { _highlightedPart = highlightedPart; }
- void setScroll(float scrollPos, float scrollSize) { _scrollPos = scrollPos; _scrollSize = scrollSize; }
+ void setHighlight(WindowClick highlightedPart);
+ void setScroll(float scrollPos, float scrollSize);
+ bool processEvent(Common::Event &event);
+ bool hasAllFocus() { return _beingDragged || _beingResized; }
private:
void drawBorder();
void drawBox(Graphics::ManagedSurface *g, int x, int y, int w, int h);
- void fillRect(Graphics::ManagedSurface *g, int x, int y, int w, int h, int color = kColorBlack);
+ void fillRect(Graphics::ManagedSurface *g, int x, int y, int w, int h, int color);
const Graphics::Font *getTitleFont();
- bool builtInFonts();
+ void updateInnerDims();
+ WindowClick isInBorder(int x, int y);
private:
- Graphics::ManagedSurface _surface;
Graphics::ManagedSurface _borderSurface;
Graphics::ManagedSurface _composeSurface;
bool _scrollable;
+ bool _resizable;
bool _active;
bool _borderIsDirty;
- BorderHighlight _highlightedPart;
+ bool _beingDragged, _beingResized;
+ int _draggedX, _draggedY;
+
+ WindowClick _highlightedPart;
float _scrollPos, _scrollSize;
- Common::Rect _dims;
+ Common::Rect _innerDims;
Common::String _title;
};
diff --git a/engines/wage/macwindowmanager.cpp b/engines/wage/macwindowmanager.cpp
index 72f01fac67..5cc54d648a 100644
--- a/engines/wage/macwindowmanager.cpp
+++ b/engines/wage/macwindowmanager.cpp
@@ -45,38 +45,127 @@
*
*/
-#include "common/list.h"
#include "common/array.h"
+#include "common/events.h"
+#include "common/list.h"
+#include "common/unzip.h"
+#include "common/system.h"
+#include "common/stream.h"
+#include "graphics/cursorman.h"
+#include "graphics/fonts/bdf.h"
#include "graphics/managed_surface.h"
+#include "graphics/palette.h"
+#include "graphics/primitives.h"
-#include "wage/wage.h"
-#include "wage/macwindow.h"
#include "wage/macwindowmanager.h"
+#include "wage/macwindow.h"
+#include "wage/macmenu.h"
namespace Wage {
+static const byte palette[] = {
+ 0, 0, 0, // Black
+ 0x80, 0x80, 0x80, // Gray
+ 0xff, 0xff, 0xff, // White
+ 0x00, 0xff, 0x00, // Green
+ 0x00, 0xcf, 0x00 // Green2
+};
+
+static byte fillPatterns[][8] = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, // kPatternSolid
+ { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, // kPatternStripes
+ { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }, // kPatternCheckers
+ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa } // kPatternCheckers2
+};
+
+static const byte macCursorArrow[] = {
+ 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 0, 0, 2, 3, 3, 3, 3, 3, 3, 3,
+ 2, 0, 0, 0, 2, 3, 3, 3, 3, 3, 3,
+ 2, 0, 0, 0, 0, 2, 3, 3, 3, 3, 3,
+ 2, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3,
+ 2, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3,
+ 2, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3,
+ 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ 2, 0, 0, 2, 0, 0, 2, 3, 3, 3, 3,
+ 2, 0, 2, 3, 2, 0, 0, 2, 3, 3, 3,
+ 2, 2, 3, 3, 2, 0, 0, 2, 3, 3, 3,
+ 2, 3, 3, 3, 3, 2, 0, 0, 2, 3, 3,
+ 3, 3, 3, 3, 3, 2, 0, 0, 2, 3, 3,
+ 3, 3, 3, 3, 3, 3, 2, 2, 2, 3, 3
+};
+
+static const byte macCursorBeam[] = {
+ 0, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3,
+ 3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3,
+ 0, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3,
+};
+
MacWindowManager::MacWindowManager() {
+ _screen = 0;
_lastId = 0;
_activeWindow = -1;
+
+ _menu = 0;
+
+ _fullRefresh = true;
+
+ _builtInFonts = true;
+
+ for (int i = 0; i < ARRAYSIZE(fillPatterns); i++)
+ _patterns.push_back(fillPatterns[i]);
+
+ loadFonts();
+
+ g_system->getPaletteManager()->setPalette(palette, 0, ARRAYSIZE(palette) / 3);
+
+ CursorMan.replaceCursorPalette(palette, 0, ARRAYSIZE(palette) / 3);
+ CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3);
+ _cursorIsArrow = true;
+ CursorMan.showMouse(true);
}
MacWindowManager::~MacWindowManager() {
- for (uint i = 0; i < _lastId; i++)
+ for (int i = 0; i < _lastId; i++)
delete _windows[i];
}
-int MacWindowManager::add(bool scrollable) {
- MacWindow *w = new MacWindow(scrollable);
+MacWindow *MacWindowManager::addWindow(bool scrollable, bool resizable, bool editable) {
+ MacWindow *w = new MacWindow(_lastId, scrollable, resizable, editable, this);
_windows.push_back(w);
_windowStack.push_back(w);
- _activeWindow = _lastId;
+ setActive(_lastId);
_lastId++;
- return _activeWindow;
+ return w;
+}
+
+Menu *MacWindowManager::addMenu() {
+ _menu = new Menu(_lastId, _screen->getBounds(), this);
+
+ _windows.push_back(_menu);
+
+ _lastId++;
+
+ return _menu;
}
void MacWindowManager::setActive(int id) {
@@ -86,6 +175,8 @@ void MacWindowManager::setActive(int id) {
if (_activeWindow != -1)
_windows[_activeWindow]->setActive(false);
+ _activeWindow = id;
+
_windows[id]->setActive(true);
_windowStack.remove(_windows[id]);
@@ -94,11 +185,196 @@ void MacWindowManager::setActive(int id) {
_fullRefresh = true;
}
-void MacWindowManager::draw(Graphics::ManagedSurface *g) {
- for (Common::List<MacWindow *>::const_iterator it = _windowStack.begin(); it != _windowStack.end(); it++)
- (*it)->draw(g, _fullRefresh);
+struct PlotData {
+ Graphics::ManagedSurface *surface;
+ Patterns *patterns;
+ uint fillType;
+ int thickness;
+
+ PlotData(Graphics::ManagedSurface *s, Patterns *p, int f, int t) :
+ surface(s), patterns(p), fillType(f), thickness(t) {}
+};
+
+static void drawPixel(int x, int y, int color, void *data) {
+ PlotData *p = (PlotData *)data;
+
+ if (p->fillType > p->patterns->size())
+ return;
+
+ byte *pat = p->patterns->operator[](p->fillType - 1);
+
+ if (p->thickness == 1) {
+ if (x >= 0 && x < p->surface->w && y >= 0 && y < p->surface->h) {
+ uint xu = (uint)x; // for letting compiler optimize it
+ uint yu = (uint)y;
+
+ *((byte *)p->surface->getBasePtr(xu, yu)) =
+ (pat[yu % 8] & (1 << (7 - xu % 8))) ?
+ color : kColorWhite;
+ }
+ } else {
+ int x1 = x;
+ int x2 = x1 + p->thickness;
+ int y1 = y;
+ int y2 = y1 + p->thickness;
+
+ for (y = y1; y < y2; y++)
+ for (x = x1; x < x2; x++)
+ if (x >= 0 && x < p->surface->w && y >= 0 && y < p->surface->h) {
+ uint xu = (uint)x; // for letting compiler optimize it
+ uint yu = (uint)y;
+ *((byte *)p->surface->getBasePtr(xu, yu)) =
+ (pat[yu % 8] & (1 << (7 - xu % 8))) ?
+ color : kColorWhite;
+ }
+ }
+}
+
+void MacWindowManager::drawDesktop() {
+ Common::Rect r(_screen->getBounds());
+
+ PlotData pd(_screen, &_patterns, kPatternCheckers, 1);
+
+ Graphics::drawRoundRect(r, kDesktopArc, kColorBlack, true, drawPixel, &pd);
+
+ g_system->copyRectToScreen(_screen->getPixels(), _screen->pitch, 0, 0, _screen->w, _screen->h);
+}
+
+void MacWindowManager::draw() {
+ assert(_screen);
+
+ if (_fullRefresh)
+ drawDesktop();
+
+ for (Common::List<BaseMacWindow *>::const_iterator it = _windowStack.begin(); it != _windowStack.end(); it++) {
+ BaseMacWindow *w = *it;
+ if (w->draw(_screen, _fullRefresh)) {
+ w->setDirty(false);
+
+ Common::Rect clip(w->getDimensions().left - 2, w->getDimensions().top - 2, w->getDimensions().right - 2, w->getDimensions().bottom - 2);
+ clip.clip(_screen->getBounds());
+
+ g_system->copyRectToScreen(_screen->getBasePtr(clip.left, clip.top), _screen->pitch, clip.left, clip.top, clip.width(), clip.height());
+ }
+ }
+
+ // Menu is drawn on top of everything and always
+ if (_menu)
+ _menu->draw(_screen, _fullRefresh);
_fullRefresh = false;
}
+bool MacWindowManager::processEvent(Common::Event &event) {
+ // Menu gets events first fir shortcuts and menu bar
+ if (_menu && _menu->processEvent(event))
+ return true;
+
+ if (event.type != Common::EVENT_MOUSEMOVE && event.type != Common::EVENT_LBUTTONDOWN &&
+ event.type != Common::EVENT_LBUTTONUP)
+ return false;
+
+ if (_windows[_activeWindow]->isEditable() && _windows[_activeWindow]->getType() == kWindowWindow &&
+ ((MacWindow *)_windows[_activeWindow])->getInnerDimensions().contains(event.mouse.x, event.mouse.y)) {
+ if (_cursorIsArrow) {
+ CursorMan.replaceCursor(macCursorBeam, 11, 16, 3, 8, 3);
+ _cursorIsArrow = false;
+ }
+ } else {
+ if (_cursorIsArrow == false) {
+ CursorMan.replaceCursor(macCursorArrow, 11, 16, 1, 1, 3);
+ _cursorIsArrow = true;
+ }
+ }
+
+ for (Common::List<BaseMacWindow *>::const_iterator it = _windowStack.end(); it != _windowStack.begin();) {
+ it--;
+ BaseMacWindow *w = *it;
+
+ if (w->hasAllFocus() || w->getDimensions().contains(event.mouse.x, event.mouse.y)) {
+ if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_LBUTTONUP)
+ setActive(w->getId());
+
+ return w->processEvent(event);
+ }
+ }
+
+ return false;
+}
+
+//////////////////////
+// Font stuff
+//////////////////////
+void MacWindowManager::loadFonts() {
+ Common::Archive *dat;
+
+ dat = Common::makeZipArchive("classicmacfonts.dat");
+
+ if (!dat) {
+ warning("Could not find classicmacfonts.dat. Falling back to built-in fonts");
+ _builtInFonts = true;
+
+ return;
+ }
+
+ Common::ArchiveMemberList list;
+ dat->listMembers(list);
+
+ for (Common::ArchiveMemberList::iterator it = list.begin(); it != list.end(); ++it) {
+ Common::SeekableReadStream *stream = dat->createReadStreamForMember((*it)->getName());
+
+ Graphics::BdfFont *font = Graphics::BdfFont::loadFont(*stream);
+
+ delete stream;
+
+ Common::String fontName = (*it)->getName();
+
+ // Trim the .bdf extension
+ for (int i = fontName.size() - 1; i >= 0; --i) {
+ if (fontName[i] == '.') {
+ while ((uint)i < fontName.size()) {
+ fontName.deleteLastChar();
+ }
+ break;
+ }
+ }
+
+ FontMan.assignFontToName(fontName, font);
+
+ debug(2, " %s", fontName.c_str());
+ }
+
+ _builtInFonts = false;
+
+ delete dat;
+}
+
+const Graphics::Font *MacWindowManager::getFont(const char *name, Graphics::FontManager::FontUsage fallback) {
+ const Graphics::Font *font = 0;
+
+ if (!_builtInFonts) {
+ font = FontMan.getFontByName(name);
+
+ if (!font)
+ warning("Cannot load font %s", name);
+ }
+
+ if (_builtInFonts || !font)
+ font = FontMan.getFontByUsage(fallback);
+
+ return font;
+}
+
+/////////////////
+// Cursor stuff
+/////////////////
+void MacWindowManager::pushArrowCursor() {
+ CursorMan.pushCursor(macCursorArrow, 11, 16, 1, 1, 3);
+}
+
+void MacWindowManager::popCursor() {
+ CursorMan.popCursor();
+}
+
+
} // End of namespace Wage
diff --git a/engines/wage/macwindowmanager.h b/engines/wage/macwindowmanager.h
index 1c8ed02a85..13f85cddd4 100644
--- a/engines/wage/macwindowmanager.h
+++ b/engines/wage/macwindowmanager.h
@@ -48,30 +48,92 @@
#ifndef WAGE_MACWINDOWMANAGER_H
#define WAGE_MACWINDOWMANAGER_H
+#include "common/array.h"
+#include "common/list.h"
+#include "common/events.h"
+#include "common/archive.h"
+
+#include "graphics/fontman.h"
+
+namespace Graphics {
+class ManagedSurface;
+}
+
namespace Wage {
+enum {
+ kDesktopArc = 7
+};
+
+enum {
+ kColorBlack = 0,
+ kColorGray = 1,
+ kColorWhite = 2,
+ kColorGreen = 3,
+ kColorGreen2 = 4
+};
+
+enum {
+ kPatternSolid = 1,
+ kPatternStripes = 2,
+ kPatternCheckers = 3,
+ kPatternCheckers2 = 4
+};
+
+class BaseMacWindow;
class MacWindow;
+class Menu;
+
+typedef Common::Array<byte *> Patterns;
class MacWindowManager {
public:
MacWindowManager();
~MacWindowManager();
- int add(bool scrollable);
+ void setScreen(Graphics::ManagedSurface *screen) { _screen = screen; }
+ bool hasBuiltInFonts() { return _builtInFonts; }
+ const Graphics::Font *getFont(const char *name, Graphics::FontManager::FontUsage fallback);
+
+ MacWindow *addWindow(bool scrollable, bool resizable, bool editable);
+ Menu *addMenu();
void setActive(int id);
- void draw(Graphics::ManagedSurface *g);
+ void setFullRefresh(bool redraw) { _fullRefresh = true; }
- MacWindow *getWindow(int id) { return _windows[id]; }
+ void draw();
+
+ bool processEvent(Common::Event &event);
+
+ BaseMacWindow *getWindow(int id) { return _windows[id]; }
+
+ Patterns &getPatterns() { return _patterns; }
+ void drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color);
+
+ void pushArrowCursor();
+ void popCursor();
+
+private:
+ void drawDesktop();
+ void loadFonts();
private:
- Common::List<MacWindow *> _windowStack;
- Common::Array<MacWindow *> _windows;
+ Graphics::ManagedSurface *_screen;
+
+ Common::List<BaseMacWindow *> _windowStack;
+ Common::Array<BaseMacWindow *> _windows;
int _lastId;
int _activeWindow;
bool _fullRefresh;
+
+ Patterns _patterns;
+
+ Menu *_menu;
+
+ bool _builtInFonts;
+ bool _cursorIsArrow;
};
} // End of namespace Wage
diff --git a/engines/wage/module.mk b/engines/wage/module.mk
index d65934fc2b..e150d5f27e 100644
--- a/engines/wage/module.mk
+++ b/engines/wage/module.mk
@@ -9,9 +9,9 @@ MODULE_OBJS := \
entities.o \
gui.o \
gui-console.o \
+ macmenu.o \
macwindow.o \
macwindowmanager.o \
- menu.o \
randomhat.o \
script.o \
sound.o \
diff --git a/engines/wage/wage.cpp b/engines/wage/wage.cpp
index 3a52aed1c4..567e2768d8 100644
--- a/engines/wage/wage.cpp
+++ b/engines/wage/wage.cpp
@@ -86,6 +86,7 @@ WageEngine::WageEngine(OSystem *syst, const ADGameDescription *desc) : Engine(sy
_offer = NULL;
_resManager = NULL;
+ _debugger = NULL;
debug("WageEngine::WageEngine()");
}
@@ -148,24 +149,14 @@ void WageEngine::processEvents() {
Common::Event event;
while (_eventMan->pollEvent(event)) {
+ if (_gui->processEvent(event))
+ continue;
+
switch (event.type) {
case Common::EVENT_QUIT:
if (saveDialog())
_shouldQuit = true;
break;
- case Common::EVENT_MOUSEMOVE:
- _gui->mouseMove(event.mouse.x, event.mouse.y);
- break;
- case Common::EVENT_LBUTTONDOWN:
- _gui->mouseDown(event.mouse.x, event.mouse.y);
- break;
- case Common::EVENT_LBUTTONUP:
- {
- Designed *obj = _gui->mouseUp(event.mouse.x, event.mouse.y);
- if (obj != NULL)
- processTurn(NULL, obj);
- }
- break;
case Common::EVENT_KEYDOWN:
switch (event.kbd.keycode) {
case Common::KEYCODE_BACKSPACE:
@@ -189,13 +180,6 @@ void WageEngine::processEvents() {
break;
}
- if (event.kbd.flags & (Common::KBD_ALT | Common::KBD_CTRL | Common::KBD_META)) {
- if (event.kbd.ascii >= 0x20 && event.kbd.ascii <= 0x7f) {
- _gui->processMenuShortCut(event.kbd.flags, event.kbd.ascii);
- }
- break;
- }
-
if (event.kbd.ascii >= 0x20 && event.kbd.ascii <= 0x7f) {
_inputText += (char)event.kbd.ascii;
_gui->drawInput();
@@ -236,7 +220,6 @@ void WageEngine::gameOver() {
_gui->disableAllMenus();
_gui->enableNewGameMenus();
- _gui->_menuDirty = true;
}
bool WageEngine::saveDialog() {
diff --git a/engines/wage/wage.h b/engines/wage/wage.h
index 87009c2350..eb50a2e3dd 100644
--- a/engines/wage/wage.h
+++ b/engines/wage/wage.h
@@ -103,14 +103,6 @@ enum {
// the current limitation is 32 debug levels (1 << 31 is the last one)
};
-enum {
- kColorBlack = 0,
- kColorGray = 1,
- kColorWhite = 2,
- kColorGreen = 3,
- kColorGreen2 = 4
-};
-
Common::String readPascalString(Common::SeekableReadStream *in);
Common::Rect *readRect(Common::SeekableReadStream *in);
const char *getIndefiniteArticle(const Common::String &word);
@@ -118,8 +110,6 @@ const char *prependGenderSpecificPronoun(int gender);
const char *getGenderSpecificPronoun(int gender, bool capitalize);
bool isStorageScene(const Common::String &name);
-typedef Common::Array<byte *> Patterns;
-
class WageEngine : public Engine {
friend class Dialog;
public:
diff --git a/engines/wage/world.cpp b/engines/wage/world.cpp
index 954a425b7b..53fc1b4742 100644
--- a/engines/wage/world.cpp
+++ b/engines/wage/world.cpp
@@ -73,6 +73,8 @@ World::World(WageEngine *engine) {
_weaponMenuDisabled = true;
_engine = engine;
+
+ _patterns = new Patterns;
}
World::~World() {
@@ -88,8 +90,10 @@ World::~World() {
for (uint i = 0; i < _orderedScenes.size(); i++)
delete _orderedScenes[i];
- for (uint i = 0; i < _patterns.size(); i++)
- free(_patterns[i]);
+ for (uint i = 0; i < _patterns->size(); i++)
+ free(_patterns->operator[](i));
+
+ delete _patterns;
delete _globalScript;
@@ -261,7 +265,7 @@ bool World::loadWorld(Common::MacResManager *resMan) {
byte *pattern = (byte *)malloc(8);
res->read(pattern, 8);
- _patterns.push_back(pattern);
+ _patterns->push_back(pattern);
}
delete res;
@@ -274,7 +278,7 @@ bool World::loadWorld(Common::MacResManager *resMan) {
byte *pattern = (byte *)malloc(8);
res->read(pattern, 8);
- _patterns.push_back(pattern);
+ _patterns->push_back(pattern);
}
}
delete res;
diff --git a/engines/wage/world.h b/engines/wage/world.h
index 355d660c8d..468bedbc59 100644
--- a/engines/wage/world.h
+++ b/engines/wage/world.h
@@ -48,6 +48,8 @@
#ifndef WAGE_WORLD_H
#define WAGE_WORLD_H
+#include "wage/macwindowmanager.h"
+
namespace Wage {
class Sound;
@@ -85,7 +87,7 @@ public:
ObjArray _orderedObjs;
ChrArray _orderedChrs;
Common::Array<Sound *> _orderedSounds;
- Patterns _patterns;
+ Patterns *_patterns;
Scene *_storageScene;
Chr *_player;
//List<MoveListener> moveListeners;
diff --git a/engines/wintermute/base/base_engine.cpp b/engines/wintermute/base/base_engine.cpp
index 2166a3e070..4ce334aceb 100644
--- a/engines/wintermute/base/base_engine.cpp
+++ b/engines/wintermute/base/base_engine.cpp
@@ -84,7 +84,7 @@ void BaseEngine::LOG(bool res, const char *fmt, ...) {
va_end(va);
if (instance()._gameRef) {
- instance()._gameRef->LOG("%s", buff);
+ instance()._gameRef->LOG(res, "%s", buff);
} else {
debugCN(kWintermuteDebugLog, "%02d:%02d:%02d: %s\n", hours, mins, secs, buff);
}
diff --git a/engines/wintermute/base/sound/base_sound_manager.cpp b/engines/wintermute/base/sound/base_sound_manager.cpp
index f1e0c3b1f9..74c0086817 100644
--- a/engines/wintermute/base/sound/base_sound_manager.cpp
+++ b/engines/wintermute/base/sound/base_sound_manager.cpp
@@ -100,15 +100,14 @@ BaseSoundBuffer *BaseSoundMgr::addSound(const Common::String &filename, Audio::M
BaseSoundBuffer *sound;
Common::String useFilename = filename;
+ useFilename.toLowercase();
// try to switch WAV to OGG file (if available)
- AnsiString ext = PathUtil::getExtension(filename);
- if (StringUtil::compareNoCase(ext, "wav")) {
- AnsiString path = PathUtil::getDirectoryName(filename);
- AnsiString name = PathUtil::getFileNameWithoutExtension(filename);
-
- AnsiString newFile = PathUtil::combine(path, name + "ogg");
- if (BaseFileManager::getEngineInstance()->hasFile(newFile)) {
- useFilename = newFile;
+ if (useFilename.hasSuffix(".wav")) {
+ Common::String oggFilename = useFilename;
+ oggFilename.erase(oggFilename.size() - 4);
+ oggFilename = oggFilename + ".ogg";
+ if (BaseFileManager::getEngineInstance()->hasFile(oggFilename)) {
+ useFilename = oggFilename;
}
}
diff --git a/gui/Tooltip.h b/gui/Tooltip.h
index 58b6d8a429..60688412e6 100644
--- a/gui/Tooltip.h
+++ b/gui/Tooltip.h
@@ -41,6 +41,8 @@ public:
void setup(Dialog *parent, Widget *widget, int x, int y);
void drawDialog();
+
+ virtual void receivedFocus(int x = -1, int y = -1) {}
protected:
virtual void handleMouseDown(int x, int y, int button, int clickCount) {
close();
@@ -64,7 +66,6 @@ protected:
}
virtual void handleMouseMoved(int x, int y, int button) {
close();
- _parent->handleMouseMoved(x + (getAbsX() - _parent->getAbsX()), y + (getAbsY() - _parent->getAbsY()), button);
}
int _maxWidth;
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index c9b435963d..72d05e2973 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -42,6 +42,7 @@
#elif defined(USE_READLINE)
#include <readline/readline.h>
#include <readline/history.h>
+ #include "common/events.h"
#endif
@@ -191,6 +192,15 @@ char *readline_completionFunction(const char *text, int state) {
return g_readline_debugger->readlineComplete(text, state);
}
+void readline_eventFunction() {
+ Common::EventManager *eventMan = g_system->getEventManager();
+
+ Common::Event event;
+ while (eventMan->pollEvent(event)) {
+ // drop all events
+ }
+}
+
#ifdef USE_READLINE_INT_COMPLETION
typedef int RLCompFunc_t(const char *, int);
#else
@@ -228,6 +238,7 @@ void Debugger::enter() {
g_readline_debugger = this;
rl_completion_entry_function = (RLCompFunc_t *)&readline_completionFunction;
+ rl_event_hook = (rl_hook_func_t *)&readline_eventFunction;
char *line_read = 0;
do {
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index 315c24e9bf..075a3bb533 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -119,6 +119,8 @@ void Dialog::reflowLayout() {
}
void Dialog::lostFocus() {
+ _dragWidget = NULL;
+
if (_tickleWidget) {
_tickleWidget->lostFocus();
}
diff --git a/gui/dialog.h b/gui/dialog.h
index 593ee13458..0e06effabd 100644
--- a/gui/dialog.h
+++ b/gui/dialog.h
@@ -82,7 +82,7 @@ public:
virtual void reflowLayout();
virtual void lostFocus();
- virtual void receivedFocus() {}
+ virtual void receivedFocus(int x = -1, int y = -1) { if (x >= 0 && y >= 0) handleMouseMoved(x, y, 0); }
protected:
virtual void open();
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 4ddf62b2fe..3ce8bee020 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -281,15 +281,10 @@ void GuiManager::runLoop() {
redraw();
}
- _lastMousePosition.x = _lastMousePosition.y = -1;
- _lastMousePosition.time = 0;
-
Common::EventManager *eventMan = _system->getEventManager();
uint32 lastRedraw = 0;
const uint32 waitTime = 1000 / 60;
- bool tooltipCheck = false;
-
while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) {
redraw();
@@ -336,11 +331,6 @@ void GuiManager::runLoop() {
processEvent(event, activeDialog);
- if (event.type == Common::EVENT_MOUSEMOVE) {
- tooltipCheck = true;
- }
-
-
if (lastRedraw + waitTime < _system->getMillis(true)) {
lastRedraw = _system->getMillis(true);
_theme->updateScreen();
@@ -348,7 +338,7 @@ void GuiManager::runLoop() {
}
}
- if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) {
+ if (_lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) {
Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y);
if (wdg && wdg->hasTooltip() && !(wdg->getFlags() & WIDGET_PRESSED)) {
Tooltip *tooltip = new Tooltip();
@@ -415,7 +405,7 @@ void GuiManager::restoreState() {
}
void GuiManager::openDialog(Dialog *dialog) {
- dialog->receivedFocus();
+ giveFocusToDialog(dialog);
if (!_dialogStack.empty())
getTopDialog()->lostFocus();
@@ -439,8 +429,10 @@ void GuiManager::closeTopDialog() {
// Remove the dialog from the stack
_dialogStack.pop()->lostFocus();
- if (!_dialogStack.empty())
- getTopDialog()->receivedFocus();
+ if (!_dialogStack.empty()) {
+ Dialog *dialog = getTopDialog();
+ giveFocusToDialog(dialog);
+ }
if (_redrawStatus != kRedrawFull)
_redrawStatus = kRedrawCloseDialog;
@@ -515,6 +507,7 @@ void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDi
int button;
uint32 time;
Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y);
+
switch (event.type) {
case Common::EVENT_KEYDOWN:
activeDialog->handleKeyDown(event.kbd);
@@ -523,12 +516,12 @@ void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDi
activeDialog->handleKeyUp(event.kbd);
break;
case Common::EVENT_MOUSEMOVE:
+ _globalMousePosition.x = event.mouse.x;
+ _globalMousePosition.y = event.mouse.y;
activeDialog->handleMouseMoved(mouse.x, mouse.y, 0);
if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) {
- _lastMousePosition.x = mouse.x;
- _lastMousePosition.y = mouse.y;
- _lastMousePosition.time = _system->getMillis(true);
+ setLastMousePos(mouse.x, mouse.y);
}
break;
@@ -571,4 +564,17 @@ void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDi
}
}
+void GuiManager::giveFocusToDialog(Dialog *dialog) {
+ int16 dialogX = _globalMousePosition.x - dialog->_x;
+ int16 dialogY = _globalMousePosition.y - dialog->_y;
+ dialog->receivedFocus(dialogX, dialogY);
+ setLastMousePos(dialogX, dialogY);
+}
+
+void GuiManager::setLastMousePos(int16 x, int16 y) {
+ _lastMousePosition.x = x;
+ _lastMousePosition.y = y;
+ _lastMousePosition.time = _system->getMillis(true);
+}
+
} // End of namespace GUI
diff --git a/gui/gui-manager.h b/gui/gui-manager.h
index 26c8d6def9..35779215b2 100644
--- a/gui/gui-manager.h
+++ b/gui/gui-manager.h
@@ -124,11 +124,12 @@ protected:
bool _useStdCursor;
// position and time of last mouse click (used to detect double clicks)
- struct {
+ struct MousePos {
+ MousePos() : x(-1), y(-1), count(0) { time = 0; }
int16 x, y; // Position of mouse when the click occurred
uint32 time; // Time
int count; // How often was it already pressed?
- } _lastClick, _lastMousePosition;
+ } _lastClick, _lastMousePosition, _globalMousePosition;
// mouse cursor state
int _cursorAnimateCounter;
@@ -155,6 +156,9 @@ protected:
Dialog *getTopDialog() const;
void screenChange();
+
+ void giveFocusToDialog(Dialog *dialog);
+ void setLastMousePos(int16 x, int16 y);
};
} // End of namespace GUI
diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp
index 9557da1206..63b69a39ea 100644
--- a/gui/predictivedialog.cpp
+++ b/gui/predictivedialog.cpp
@@ -190,7 +190,7 @@ void PredictiveDialog::saveUserDictToFile() {
void PredictiveDialog::handleKeyUp(Common::KeyState state) {
if (_curPressedButton != kNoAct && !_needRefresh) {
- _button[_curPressedButton]->startAnimatePressedState();
+ _button[_curPressedButton]->setUnpressedState();
processButton(_curPressedButton);
}
}
@@ -352,7 +352,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) {
}
if (_lastButton != _curPressedButton)
- _button[_lastButton]->stopAnimatePressedState();
+ _button[_lastButton]->setUnpressedState();
if (_curPressedButton != kNoAct && !_needRefresh)
_button[_curPressedButton]->setPressedState();
@@ -604,18 +604,6 @@ void PredictiveDialog::processButton(ButtonId button) {
}
}
-void PredictiveDialog::handleTickle() {
- if (_lastTime) {
- if ((_curTime - _lastTime) > kRepeatDelay) {
- _lastTime = 0;
- }
- }
-
- if (getTickleWidget()) {
- getTickleWidget()->handleTickle();
- }
-}
-
void PredictiveDialog::mergeDicts() {
_unitedDict.dictLineCount = _predictiveDict.dictLineCount + _userDict.dictLineCount;
_unitedDict.dictLine = (char **)calloc(_unitedDict.dictLineCount, sizeof(char *));
diff --git a/gui/predictivedialog.h b/gui/predictivedialog.h
index 4c167c3efa..1f6bdf84e0 100644
--- a/gui/predictivedialog.h
+++ b/gui/predictivedialog.h
@@ -43,7 +43,6 @@ public:
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
virtual void handleKeyUp(Common::KeyState state);
virtual void handleKeyDown(Common::KeyState state);
- virtual void handleTickle();
const char *getResult() const { return _predictiveResult; }
diff --git a/gui/widget.cpp b/gui/widget.cpp
index 4143111e54..03540f7b91 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -299,7 +299,7 @@ ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Co
void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
if (isEnabled() && _duringPress && x >= 0 && x < _w && y >= 0 && y < _h) {
- startAnimatePressedState();
+ setUnpressedState();
sendCommand(_cmd, 0);
}
_duringPress = false;
@@ -344,40 +344,17 @@ void ButtonWidget::setHighLighted(bool enable) {
draw();
}
-void ButtonWidget::handleTickle() {
- if (_lastTime) {
- uint32 curTime = g_system->getMillis();
- if (curTime - _lastTime > kPressedButtonTime) {
- stopAnimatePressedState();
- }
- }
-}
-
void ButtonWidget::setPressedState() {
- wantTickle(true);
setFlags(WIDGET_PRESSED);
clearFlags(WIDGET_HILITED);
draw();
}
-void ButtonWidget::stopAnimatePressedState() {
- wantTickle(false);
- _lastTime = 0;
+void ButtonWidget::setUnpressedState() {
clearFlags(WIDGET_PRESSED);
draw();
}
-void ButtonWidget::startAnimatePressedState() {
- _lastTime = g_system->getMillis();
-}
-
-void ButtonWidget::wantTickle(bool tickled) {
- if (tickled)
- ((GUI::Dialog *)_boss)->setTickleWidget(this);
- else
- ((GUI::Dialog *)_boss)->unSetTickleWidget();
-}
-
#pragma mark -
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
diff --git a/gui/widget.h b/gui/widget.h
index 4f181954b5..7f6f0c0533 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -201,17 +201,12 @@ public:
void handleMouseDown(int x, int y, int button, int clickCount);
void handleMouseEntered(int button) { if (_duringPress) { setFlags(WIDGET_PRESSED); } else { setFlags(WIDGET_HILITED); } draw(); }
void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED | WIDGET_PRESSED); draw(); }
- void handleTickle();
void setHighLighted(bool enable);
void setPressedState();
- void startAnimatePressedState();
- void stopAnimatePressedState();
-
- void lostFocusWidget() { stopAnimatePressedState(); }
+ void setUnpressedState();
protected:
void drawWidget();
- void wantTickle(bool tickled);
bool _duringPress;
private:
uint32 _lastTime;
diff --git a/gui/widgets/popup.cpp b/gui/widgets/popup.cpp
index b10b4fb5fe..0b2ea9fd4e 100644
--- a/gui/widgets/popup.cpp
+++ b/gui/widgets/popup.cpp
@@ -388,6 +388,8 @@ PopUpWidget::PopUpWidget(GuiObject *boss, int x, int y, int w, int h, const char
_type = kPopUpWidget;
_selectedItem = -1;
+
+ _leftPadding = _rightPadding = 0;
}
void PopUpWidget::handleMouseDown(int x, int y, int button, int clickCount) {
diff --git a/po/de_DE.po b/po/de_DE.po
index 8cfa723ece..65765ecca0 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.9.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2016-04-07 08:55+0100\n"
-"PO-Revision-Date: 2016-04-10 11:00+0100\n"
+"POT-Creation-Date: 2016-04-07 08:55+0200\n"
+"PO-Revision-Date: 2016-05-01 15:45+0200\n"
"Last-Translator: Lothar Serra Mari <rootfather@scummvm.org>\n"
"Language-Team: Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari "
"<rootfather@scummvm.org>\n"
@@ -978,7 +978,7 @@ msgstr "Musiklautstärke:"
#: gui/options.cpp:970
msgid "Mute All"
-msgstr "Alles aus"
+msgstr "Stumm"
#: gui/options.cpp:973
msgid "SFX volume:"
@@ -2967,7 +2967,7 @@ msgstr "Objektzeile zeigen"
#: engines/scumm/detection.cpp:1336
msgid "Show the names of objects at the bottom of the screen"
-msgstr "Die Objektzeile wird während des Spiels im unteren Bildbereich eingeblendet"
+msgstr "Objektnamen und Verben am unteren Bildrand anzeigen"
#: engines/scumm/dialogs.cpp:176
#, c-format
diff --git a/po/hu_HU.po b/po/hu_HU.po
index 1033063868..1033063868 100755..100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po