From 563d83701313fcd71ac7090deb61e7f3910e6070 Mon Sep 17 00:00:00 2001
From: Joel Teichroeb
Date: Wed, 22 Jan 2014 14:23:30 -0800
Subject: ANDROID: Modernize build system
Written originally by @Botje for ResidualVM
---
backends/platform/android/android.mk | 193 +++++++++--------------------------
dists/android/custom_rules.xml | 31 ++++++
dists/android/jni/Android.mk | 9 ++
dists/android/project.properties | 11 ++
dists/android/res/layout/main.xml | 4 -
5 files changed, 102 insertions(+), 146 deletions(-)
create mode 100644 dists/android/custom_rules.xml
create mode 100644 dists/android/jni/Android.mk
create mode 100644 dists/android/project.properties
diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index 69aa9d8303..f9a2bc9813 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -2,183 +2,92 @@
# These must be incremented for each market upload
ANDROID_VERSIONCODE = 6
-ANDROID_PLUGIN_VERSIONCODE = 6
-JAVA_FILES = \
- ScummVM.java \
- ScummVMEvents.java \
- ScummVMEventsHoneycomb.java \
- ScummVMApplication.java \
- ScummVMActivity.java \
- EditableSurfaceView.java \
- MouseHelper.java \
- Unpacker.java
+ANDROID_TARGET_VERSION = 14
-JAVA_FILES_PLUGIN = \
- PluginProvider.java
-
-JAVA_FILES_GEN = \
- Manifest.java \
- R.java
+NDK_BUILD = $(ANDROID_NDK)/ndk-build
+SDK_ANDROID = $(ANDROID_SDK)/tools/android
PATH_DIST = $(srcdir)/dists/android
PATH_RESOURCES = $(PATH_DIST)/res
PORT_DISTFILES = $(PATH_DIST)/README.Android
+DIST_JAVA_SRC_DIR = $(srcdir)/backends/platform/android/org
RESOURCES = \
- $(PATH_RESOURCES)/values/strings.xml \
- $(PATH_RESOURCES)/values/margins.xml \
- $(PATH_RESOURCES)/values-television/margins.xml \
- $(PATH_RESOURCES)/layout/main.xml \
- $(PATH_RESOURCES)/layout/splash.xml \
- $(PATH_RESOURCES)/drawable/gradient.xml \
- $(PATH_RESOURCES)/drawable/scummvm.png \
- $(PATH_RESOURCES)/drawable/scummvm_big.png \
- $(PATH_RESOURCES)/drawable-xhdpi/ouya_icon.png
-
-PLUGIN_RESOURCES = \
- $(PATH_RESOURCES)/values/strings.xml \
- $(PATH_RESOURCES)/drawable/scummvm.png
-
-# FIXME: find/mark plugin entry points and add all this back again:
-#LDFLAGS += -Wl,--gc-sections
-#CXXFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden
-
-AAPT = $(ANDROID_SDK)/$(ANDROID_BTOOLS)/aapt
-ADB = $(ANDROID_SDK)/platform-tools/adb
-DX = $(ANDROID_SDK)/$(ANDROID_BTOOLS)/dx
-APKBUILDER = java -Xmx128M -classpath $(ANDROID_SDK)/tools/lib/sdklib.jar com.android.sdklib.build.ApkBuilderMain
-JAVAC ?= javac
-JAVACFLAGS = -source 1.5 -target 1.5
-
-ANDROID_JAR = $(ANDROID_SDK)/platforms/android-14/android.jar
+ $(PATH_BUILD_RES)/values/strings.xml \
+ $(PATH_BUILD_RES)/values-television/margins.xml \
+ $(PATH_BUILD_RES)/layout/main.xml \
+ $(PATH_BUILD_RES)/layout/splash.xml \
+ $(PATH_BUILD_RES)/drawable/gradient.xml \
+ $(PATH_BUILD_RES)/drawable/scummvm.png \
+ $(PATH_BUILD_RES)/drawable/scummvm_big.png \
+ $(PATH_BUILD_RES)/drawable-xhdpi/ouya_icon.png
+
+DIST_ANDROID_MK = $(PATH_DIST)/jni/Android.mk
+DIST_BUILD_XML = $(PATH_DIST)/custom_rules.xml
PATH_BUILD = ./build.tmp
PATH_BUILD_ASSETS = $(PATH_BUILD)/assets
-PATH_BUILD_CLASSES_MAIN_TOP = $(PATH_BUILD)/classes.main
-PATH_BUILD_CLASSES_PLUGIN_TOP = $(PATH_BUILD)/classes.plugin
-
-PATH_STAGE_PREFIX = build.stage
-PATH_STAGE_MAIN = $(PATH_STAGE_PREFIX).main
-
-PATH_REL = org/scummvm/scummvm
-PATH_SRC_TOP = $(srcdir)/backends/platform/android
-PATH_SRC = $(PATH_SRC_TOP)/$(PATH_REL)
-
-PATH_GEN_TOP = $(PATH_BUILD)/java
-PATH_GEN = $(PATH_GEN_TOP)/$(PATH_REL)
-PATH_CLASSES_MAIN = $(PATH_BUILD_CLASSES_MAIN_TOP)/$(PATH_REL)
-PATH_CLASSES_PLUGIN = $(PATH_BUILD_CLASSES_PLUGIN_TOP)/$(PATH_REL)
+PATH_BUILD_RES = $(PATH_BUILD)/res
+PATH_BUILD_LIBSCUMMVM = $(PATH_BUILD)/mylib/armeabi/libscummvm.so
FILE_MANIFEST_SRC = $(srcdir)/dists/android/AndroidManifest.xml
FILE_MANIFEST = $(PATH_BUILD)/AndroidManifest.xml
-FILE_DEX = $(PATH_BUILD)/classes.dex
-FILE_DEX_PLUGIN = $(PATH_BUILD)/plugins/classes.dex
-FILE_RESOURCES = resources.ap_
-FILE_RESOURCES_MAIN = $(PATH_BUILD)/$(FILE_RESOURCES)
-
-SRC_GEN = $(addprefix $(PATH_GEN)/, $(JAVA_FILES_GEN))
-
-CLASSES_MAIN = $(addprefix $(PATH_CLASSES_MAIN)/, $(JAVA_FILES:%.java=%.class))
-CLASSES_GEN = $(addprefix $(PATH_CLASSES_MAIN)/, $(JAVA_FILES_GEN:%.java=%.class))
-CLASSES_PLUGIN = $(addprefix $(PATH_CLASSES_PLUGIN)/, $(JAVA_FILES_PLUGIN:%.java=%.class))
-APK_MAIN = scummvm.apk
+APK_MAIN = ScummVM-debug.apk
+APK_MAIN_RELEASE = ScummVM-release-unsigned.apk
APK_PLUGINS = $(patsubst plugins/lib%.so, scummvm-engine-%.apk, $(PLUGINS))
-$(FILE_MANIFEST): $(FILE_MANIFEST_SRC)
+$(FILE_MANIFEST): $(FILE_MANIFEST_SRC) | $(PATH_BUILD)
@$(MKDIR) -p $(@D)
sed "s/@ANDROID_VERSIONCODE@/$(ANDROID_VERSIONCODE)/" < $< > $@
-$(SRC_GEN): $(FILE_MANIFEST) $(filter %.xml,$(RESOURCES)) $(ANDROID_JAR)
- @$(MKDIR) -p $(PATH_GEN_TOP)
- $(AAPT) package -m -J $(PATH_GEN_TOP) -M $< -S $(PATH_RESOURCES) -I $(ANDROID_JAR)
-
-$(PATH_CLASSES_MAIN)/%.class: $(PATH_GEN)/%.java $(SRC_GEN)
+$(PATH_BUILD)/res/%: $(PATH_DIST)/res/% | $(PATH_BUILD)
@$(MKDIR) -p $(@D)
- $(JAVAC) $(JAVACFLAGS) -cp $(PATH_SRC_TOP) -d $(PATH_BUILD_CLASSES_MAIN_TOP) -bootclasspath $(ANDROID_JAR) $<
+ $(CP) $< $@
-$(PATH_CLASSES_MAIN)/%.class: $(PATH_SRC)/%.java $(SRC_GEN)
+$(PATH_BUILD)/libs/%: $(PATH_DIST)/libs/% | $(PATH_BUILD)
@$(MKDIR) -p $(@D)
- $(JAVAC) $(JAVACFLAGS) -cp $(PATH_SRC_TOP):$(PATH_GEN_TOP) -d $(PATH_BUILD_CLASSES_MAIN_TOP) -bootclasspath $(ANDROID_JAR) $<
+ $(CP) $< $@
-$(PATH_CLASSES_PLUGIN)/%.class: $(PATH_SRC)/%.java
- @$(MKDIR) -p $(@D)
- $(JAVAC) $(JAVACFLAGS) -cp $(PATH_SRC_TOP) -d $(PATH_BUILD_CLASSES_PLUGIN_TOP) -bootclasspath $(ANDROID_JAR) $<
+$(PATH_BUILD_ASSETS): $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_SHADERS) $(DIST_BUILD_XML) | $(PATH_BUILD)
+ $(INSTALL) -d $(PATH_BUILD_ASSETS)
+ $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(PATH_BUILD_ASSETS)/
+ $(INSTALL) -d $(PATH_BUILD)/jni
+ $(INSTALL) -c -m 644 $(DIST_ANDROID_MK) $(PATH_BUILD)/jni
+ $(INSTALL) -c -m 644 $(DIST_BUILD_XML) $(PATH_BUILD)
-$(FILE_DEX): $(CLASSES_MAIN) $(CLASSES_GEN)
- $(DX) --dex --output=$@ $(PATH_BUILD_CLASSES_MAIN_TOP)
+$(PATH_BUILD): $(DIST_ANDROID_MK)
+ $(MKDIR) -p $(PATH_BUILD) $(PATH_BUILD)/res
+ $(MKDIR) -p $(PATH_BUILD)/libs
-$(FILE_DEX_PLUGIN): $(CLASSES_PLUGIN)
- @$(MKDIR) -p $(@D)
- $(DX) --dex --output=$@ $(PATH_BUILD_CLASSES_PLUGIN_TOP)
+$(PATH_BUILD_LIBSCUMMVM): libscummvm.so | $(PATH_BUILD)
+ $(INSTALL) -c -m 644 libscummvm.so $(PATH_BUILD)
+ $(STRIP) $(PATH_BUILD)/libscummvm.so
+ cd $(PATH_BUILD); $(NDK_BUILD)
-$(PATH_BUILD)/%/AndroidManifest.xml: $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $(PATH_DIST)/plugin-manifest.xml
- @$(MKDIR) -p $(@D)
- $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $* $(PATH_DIST)/plugin-manifest.xml $(ANDROID_PLUGIN_VERSIONCODE) $@
+$(PATH_BUILD_RES): $(RESOURCES) | $(PATH_BUILD)
-$(PATH_STAGE_PREFIX).%/res/values/strings.xml: $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $(PATH_DIST)/plugin-manifest.xml
- @$(MKDIR) -p $(@D)
- $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $* $(PATH_DIST)/plugin-strings.xml $(ANDROID_PLUGIN_VERSIONCODE) $@
+setupapk: $(FILE_MANIFEST) $(PATH_BUILD_RES) $(PATH_BUILD_ASSETS) $(PATH_BUILD_LIBSCUMMVM) | $(PATH_BUILD)
+ $(SDK_ANDROID) update project -p $(PATH_BUILD) -t android-$(ANDROID_TARGET_VERSION) -n ScummVM
-$(PATH_STAGE_PREFIX).%/res/drawable/scummvm.png: $(PATH_RESOURCES)/drawable/scummvm.png
- @$(MKDIR) -p $(@D)
- $(CP) $< $@
+$(APK_MAIN): setupapk | $(PATH_BUILD)
+ (cd $(PATH_BUILD); ant debug -Dsource.dir="$(realpath $(DIST_JAVA_SRC_DIR))")
+ $(CP) $(PATH_BUILD)/bin/ScummVM-debug.apk $@
-$(FILE_RESOURCES_MAIN): $(FILE_MANIFEST) $(RESOURCES) $(ANDROID_JAR) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA)
- $(INSTALL) -d $(PATH_BUILD_ASSETS)
- $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(PATH_BUILD_ASSETS)/
- work_dir=`pwd`; \
- for i in $(PATH_BUILD_ASSETS)/*.zip; do \
- echo "recompress $$i"; \
- cd "$$work_dir"; \
- $(RM) -rf $(PATH_BUILD_ASSETS)/tmp; \
- $(MKDIR) $(PATH_BUILD_ASSETS)/tmp; \
- unzip -q $$i -d $(PATH_BUILD_ASSETS)/tmp; \
- cd $(PATH_BUILD_ASSETS)/tmp; \
- zip -r ../`basename $$i` *; \
- done
- @$(RM) -rf $(PATH_BUILD_ASSETS)/tmp
- $(AAPT) package -f -0 zip -M $< -S $(PATH_RESOURCES) -A $(PATH_BUILD_ASSETS) -I $(ANDROID_JAR) -F $@
-
-$(PATH_BUILD)/%/$(FILE_RESOURCES): $(PATH_BUILD)/%/AndroidManifest.xml $(PATH_STAGE_PREFIX).%/res/values/strings.xml $(PATH_STAGE_PREFIX).%/res/drawable/scummvm.png plugins/lib%.so $(ANDROID_JAR)
- $(AAPT) package -f -M $< -S $(PATH_STAGE_PREFIX).$*/res -I $(ANDROID_JAR) -F $@
-
-# Package installer won't delete old libscummvm.so on upgrade so
-# replace it with a zero size file
-$(APK_MAIN): $(EXECUTABLE) $(FILE_RESOURCES_MAIN) $(FILE_DEX)
- $(INSTALL) -d $(PATH_STAGE_MAIN)/common/lib/armeabi
- touch $(PATH_STAGE_MAIN)/common/lib/armeabi/libscummvm.so
- $(INSTALL) -d $(PATH_STAGE_MAIN)/common/mylib/armeabi
- $(INSTALL) -c -m 644 libscummvm.so $(PATH_STAGE_MAIN)/common/mylib/armeabi/
- $(STRIP) $(PATH_STAGE_MAIN)/common/mylib/armeabi/libscummvm.so
- $(APKBUILDER) $@ -z $(FILE_RESOURCES_MAIN) -f $(FILE_DEX) -rf $(PATH_STAGE_MAIN)/common || { $(RM) $@; exit 1; }
-
-scummvm-engine-%.apk: plugins/lib%.so $(PATH_BUILD)/%/$(FILE_RESOURCES) $(FILE_DEX_PLUGIN)
- $(INSTALL) -d $(PATH_STAGE_PREFIX).$*/apk/mylib/armeabi/
- $(INSTALL) -c -m 644 plugins/lib$*.so $(PATH_STAGE_PREFIX).$*/apk/mylib/armeabi/
- $(STRIP) $(PATH_STAGE_PREFIX).$*/apk/mylib/armeabi/lib$*.so
- $(APKBUILDER) $@ -z $(PATH_BUILD)/$*/$(FILE_RESOURCES) -f $(FILE_DEX_PLUGIN) -rf $(PATH_STAGE_PREFIX).$*/apk || { $(RM) $@; exit 1; }
-
-all: $(APK_MAIN) $(APK_PLUGINS)
+$(APK_MAIN_RELEASE): setupapk | $(PATH_BUILD)
+ (cd $(PATH_BUILD); ant release -Dsource.dir="$(realpath $(DIST_JAVA_SRC_DIR))")
+ $(CP) $(PATH_BUILD)/bin/ScummVM-release-unsigned.apk $@
+
+all: $(APK_MAIN)
clean: androidclean
androidclean:
- @$(RM) -rf $(PATH_BUILD) $(PATH_STAGE_PREFIX).* *.apk release
-
-# remove debugging signature
-release/%.apk: %.apk
- @$(MKDIR) -p $(@D)
- @$(RM) $@
- $(CP) $< $@.tmp
- zip -d $@.tmp META-INF/\*
- jarsigner $(JARSIGNER_FLAGS) $@.tmp release
- zipalign 4 $@.tmp $@
- $(RM) $@.tmp
+ @$(RM) -rf $(PATH_BUILD) *.apk release
-androidrelease: $(addprefix release/, $(APK_MAIN) $(APK_PLUGINS))
+androidrelease: $(APK_MAIN_RELEASE)
androidtestmain: $(APK_MAIN)
$(ADB) install -r $(APK_MAIN)
@@ -198,4 +107,4 @@ androiddistdebug: all
sed 's/$$/\r/' < $$i > debug/`basename $$i`.txt; \
done
-.PHONY: androidrelease androidtest
+.PHONY: androidrelease androidtest $(PATH_BUILD_SRC)
diff --git a/dists/android/custom_rules.xml b/dists/android/custom_rules.xml
new file mode 100644
index 0000000000..5ed81b7273
--- /dev/null
+++ b/dists/android/custom_rules.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dists/android/jni/Android.mk b/dists/android/jni/Android.mk
new file mode 100644
index 0000000000..d5b398412f
--- /dev/null
+++ b/dists/android/jni/Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+APP_ABI := armeabi
+LOCAL_MODULE := scummvm
+LOCAL_SRC_FILES := ../libscummvm.so
+
+include $(PREBUILT_SHARED_LIBRARY)
diff --git a/dists/android/project.properties b/dists/android/project.properties
new file mode 100644
index 0000000000..730e911f2f
--- /dev/null
+++ b/dists/android/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-14
diff --git a/dists/android/res/layout/main.xml b/dists/android/res/layout/main.xml
index 31aa345cc7..8b0d515d62 100644
--- a/dists/android/res/layout/main.xml
+++ b/dists/android/res/layout/main.xml
@@ -9,8 +9,4 @@
android:keepScreenOn="true"
android:focusable="true"
android:focusableInTouchMode="true"
- android:layout_marginTop="@dimen/verticalMargin"
- android:layout_marginLeft="@dimen/horizontalMargin"
- android:layout_marginBottom="@dimen/verticalMargin"
- android:layout_marginRight="@dimen/horizontalMargin"
/>
--
cgit v1.2.3
From c58f7146102be3aac2cef5d69bdceb109da3f09f Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Tue, 16 Sep 2014 13:49:27 -0500
Subject: COMMON: Add support for endian-safe reading/writing of int64
---
common/endian.h | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
common/stream.h | 66 +++++++++++++++++++++
2 files changed, 239 insertions(+)
diff --git a/common/endian.h b/common/endian.h
index 6d6563f802..a18e6f088b 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -49,6 +49,17 @@
# error No endianness defined
#endif
+
+#define SWAP_CONSTANT_64(a) \
+ ((uint64)((((a) >> 56) & 0x000000FF) | \
+ (((a) >> 40) & 0x0000FF00) | \
+ (((a) >> 24) & 0x00FF0000) | \
+ (((a) >> 8) & 0xFF000000) | \
+ (((a) & 0xFF000000) << 8) | \
+ (((a) & 0x00FF0000) << 24) | \
+ (((a) & 0x0000FF00) << 40) | \
+ (((a) & 0x000000FF) << 56) ))
+
#define SWAP_CONSTANT_32(a) \
((uint32)((((a) >> 24) & 0x00FF) | \
(((a) >> 8) & 0xFF00) | \
@@ -59,6 +70,62 @@
((uint16)((((a) >> 8) & 0x00FF) | \
(((a) << 8) & 0xFF00) ))
+/**
+ * Swap the bytes in a 64 bit word in order to convert LE encoded data to BE
+ * and vice versa.
+ */
+
+// machine/compiler-specific variants come first, fallback last
+
+// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
+//
+// TODO: Fix this #if statement. It isn't changed from 32 bit. Is there a 64 bit swap instruction?
+#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
+
+ FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) {
+ if (__builtin_constant_p(a)) {
+ return SWAP_CONSTANT_32(a);
+ } else {
+ uint32 result;
+# if defined(__psp__)
+ // use special allegrex instruction
+ __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
+# else
+ __asm__ ("wsbh %0,%1\n"
+ "rotr %0,%0,16" : "=r" (result) : "r" (a));
+# endif
+ return result;
+ }
+ }
+
+// Test for GCC >= 4.3.0 as this version added the bswap builtin
+#elif GCC_ATLEAST(4, 3)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return __builtin_bswap64(a);
+ }
+
+#elif defined(_MSC_VER)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return _byteswap_uint64(a);
+ }
+
+// generic fallback
+#else
+
+ inline uint64 SWAP_BYTES_64(uint64 a) {
+ uint32 low = (uint32)a, high = (uint32)(a >> 32);
+ uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16),
+ highLow = (uint16)high, highHigh = (uint16)(high >> 16);
+
+ return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) |
+ (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) |
+ (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) |
+ (uint16)((highHigh >> 8) | (highHigh << 8)))
+ }
+#endif
+
/**
* Swap the bytes in a 32 bit word in order to convert LE encoded data to BE
* and vice versa.
@@ -173,6 +240,11 @@
return ((const Unaligned32 *)ptr)->val;
}
+ FORCEINLINE uint64 READ_UINT64(const void *ptr) {
+ struct Unaligned64 { uint64 val; } __attribute__ ((__packed__, __may_alias__));
+ return ((const Unaligned64 *)ptr)->val;
+ }
+
FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__));
((Unaligned16 *)ptr)->val = value;
@@ -183,6 +255,11 @@
((Unaligned32 *)ptr)->val = value;
}
+ FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
+ struct Unaligned64 { uint64 val; } __attribute__((__packed__, __may_alias__));
+ ((Unaligned64 *)ptr)->val = value;
+ }
+
#elif !defined(SCUMM_NEED_ALIGNMENT)
FORCEINLINE uint16 READ_UINT16(const void *ptr) {
@@ -193,6 +270,10 @@
return *(const uint32 *)(ptr);
}
+ FORCEINLINE uint64 READ_UINT64(const void *ptr) {
+ return *(const uint64 *)(ptr);
+ }
+
FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
@@ -201,6 +282,10 @@
*(uint32 *)(ptr) = value;
}
+ FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
+ *(uint64 *)(ptr) = value;
+ }
+
// use software fallback by loading each byte explicitely
#else
@@ -215,6 +300,10 @@
const uint8 *b = (const uint8 *)ptr;
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
}
+ inline uint64 READ_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[7] << 56) | (b[6] << 48) | (b[5] << 40) | (b[4] << 32) | (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
+ }
inline void WRITE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 0);
@@ -227,6 +316,17 @@
b[2] = (uint8)(value >> 16);
b[3] = (uint8)(value >> 24);
}
+ inline void WRITE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 0);
+ b[1] = (uint8)(value >> 8);
+ b[2] = (uint8)(value >> 16);
+ b[3] = (uint8)(value >> 24);
+ b[4] = (uint8)(value >> 32);
+ b[5] = (uint8)(value >> 40);
+ b[6] = (uint8)(value >> 48);
+ b[7] = (uint8)(value >> 56);
+ }
# elif defined(SCUMM_BIG_ENDIAN)
@@ -238,6 +338,10 @@
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
}
+ inline uint64 READ_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3] << 32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
+ }
inline void WRITE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 8);
@@ -250,6 +354,17 @@
b[2] = (uint8)(value >> 8);
b[3] = (uint8)(value >> 0);
}
+ inline void WRITE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 56);
+ b[1] = (uint8)(value >> 48);
+ b[2] = (uint8)(value >> 40);
+ b[3] = (uint8)(value >> 32);
+ b[4] = (uint8)(value >> 24);
+ b[5] = (uint8)(value >> 16);
+ b[6] = (uint8)(value >> 8);
+ b[7] = (uint8)(value >> 0);
+ }
# endif
@@ -261,25 +376,33 @@
#define READ_LE_UINT16(a) READ_UINT16(a)
#define READ_LE_UINT32(a) READ_UINT32(a)
+ #define READ_LE_UINT64(a) READ_UINT64(a)
#define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v)
#define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v)
+ #define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v)
+ #define FROM_LE_64(a) ((uint64)(a))
#define FROM_LE_32(a) ((uint32)(a))
#define FROM_LE_16(a) ((uint16)(a))
+ #define FROM_BE_64(a) SWAP_BYTES_64(a)
#define FROM_BE_32(a) SWAP_BYTES_32(a)
#define FROM_BE_16(a) SWAP_BYTES_16(a)
+ #define TO_LE_64(a) ((uint64)(a))
#define TO_LE_32(a) ((uint32)(a))
#define TO_LE_16(a) ((uint16)(a))
+ #define TO_BE_64(a) SWAP_BYTES_64(a)
#define TO_BE_32(a) SWAP_BYTES_32(a)
#define TO_BE_16(a) SWAP_BYTES_16(a)
+ #define CONSTANT_LE_64(a) ((uint64)(a))
#define CONSTANT_LE_32(a) ((uint32)(a))
#define CONSTANT_LE_16(a) ((uint16)(a))
+ #define CONSTANT_BE_64(a) SWAP_CONSTANT_64(a)
#define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a)
#define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a)
@@ -294,6 +417,10 @@
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
}
+ inline uint64 READ_BE_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[0] << 56) | b[1] << 48) | b[2] << 40) | b[3] << 32) | b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
+ }
inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 8);
@@ -306,6 +433,17 @@
b[2] = (uint8)(value >> 8);
b[3] = (uint8)(value >> 0);
}
+ inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 56);
+ b[1] = (uint8)(value >> 48);
+ b[2] = (uint8)(value >> 40);
+ b[3] = (uint8)(value >> 32);
+ b[4] = (uint8)(value >> 24);
+ b[5] = (uint8)(value >> 16);
+ b[6] = (uint8)(value >> 8);
+ b[7] = (uint8)(value >> 0);
+ }
# else
inline uint16 READ_BE_UINT16(const void *ptr) {
@@ -314,12 +452,18 @@
inline uint32 READ_BE_UINT32(const void *ptr) {
return SWAP_BYTES_32(READ_UINT32(ptr));
}
+ inline uint32 READ_BE_UINT64(const void *ptr) {
+ return SWAP_BYTES_64(READ_UINT64(ptr));
+ }
inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
WRITE_UINT16(ptr, SWAP_BYTES_16(value));
}
inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
WRITE_UINT32(ptr, SWAP_BYTES_32(value));
}
+ inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
+ WRITE_UINT64(ptr, SWAP_BYTES_64(value));
+ }
# endif // if defined(SCUMM_NEED_ALIGNMENT)
@@ -327,25 +471,33 @@
#define READ_BE_UINT16(a) READ_UINT16(a)
#define READ_BE_UINT32(a) READ_UINT32(a)
+ #define READ_BE_UINT64(a) READ_UINT64(a)
#define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v)
#define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v)
+ #define WRITE_BE_UINT64(a, v) WRITE_UINT64(a, v)
+ #define FROM_LE_64(a) SWAP_BYTES_64(a)
#define FROM_LE_32(a) SWAP_BYTES_32(a)
#define FROM_LE_16(a) SWAP_BYTES_16(a)
+ #define FROM_BE_64(a) ((uint64)(a))
#define FROM_BE_32(a) ((uint32)(a))
#define FROM_BE_16(a) ((uint16)(a))
+ #define TO_LE_64(a) SWAP_BYTES_64(a)
#define TO_LE_32(a) SWAP_BYTES_32(a)
#define TO_LE_16(a) SWAP_BYTES_16(a)
+ #define TO_BE_64(a) ((uint64)(a))
#define TO_BE_32(a) ((uint32)(a))
#define TO_BE_16(a) ((uint16)(a))
+ #define CONSTANT_LE_64(a) SWAP_CONSTANT_64(a)
#define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a)
#define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a)
+ #define CONSTANT_BE_64(a) ((uint64)(a))
#define CONSTANT_BE_32(a) ((uint32)(a))
#define CONSTANT_BE_16(a) ((uint16)(a))
@@ -360,6 +512,10 @@
const uint8 *b = (const uint8 *)ptr;
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
}
+ inline uint64 READ_LE_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[7] << 56) | (b[6] << 48) | (b[5] << 40) | (b[4] << 32) | (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
+ }
inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 0);
@@ -372,6 +528,17 @@
b[2] = (uint8)(value >> 16);
b[3] = (uint8)(value >> 24);
}
+ inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 0);
+ b[1] = (uint8)(value >> 8);
+ b[2] = (uint8)(value >> 16);
+ b[3] = (uint8)(value >> 24);
+ b[4] = (uint8)(value >> 32);
+ b[5] = (uint8)(value >> 40);
+ b[6] = (uint8)(value >> 48);
+ b[7] = (uint8)(value >> 56);
+ }
# else
inline uint16 READ_LE_UINT16(const void *ptr) {
@@ -380,12 +547,18 @@
inline uint32 READ_LE_UINT32(const void *ptr) {
return SWAP_BYTES_32(READ_UINT32(ptr));
}
+ inline uint64 READ_LE_UINT64(const void *ptr) {
+ return SWAP_BYTES_64(READ_UINT64(ptr));
+ }
inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
WRITE_UINT16(ptr, SWAP_BYTES_16(value));
}
inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
WRITE_UINT32(ptr, SWAP_BYTES_32(value));
}
+ inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
+ WRITE_UINT64(ptr, SWAP_BYTES_64(value));
+ }
# endif // if defined(SCUMM_NEED_ALIGNMENT)
diff --git a/common/stream.h b/common/stream.h
index 2702068cf3..5655f0fcb4 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -125,6 +125,11 @@ public:
write(&value, 4);
}
+ void writeUint64LE(uint64 value) {
+ value = TO_LE_64(value);
+ write(&value, 8);
+ }
+
void writeUint16BE(uint16 value) {
value = TO_BE_16(value);
write(&value, 2);
@@ -135,6 +140,11 @@ public:
write(&value, 4);
}
+ void writeUint64BE(uint64 value) {
+ value = TO_BE_64(value);
+ write(&value, 8);
+ }
+
FORCEINLINE void writeSint16LE(int16 value) {
writeUint16LE((uint16)value);
}
@@ -143,6 +153,10 @@ public:
writeUint32LE((uint32)value);
}
+ FORCEINLINE void writeSint64LE(int64 value) {
+ writeUint64LE((uint64)value);
+ }
+
FORCEINLINE void writeSint16BE(int16 value) {
writeUint16BE((uint16)value);
}
@@ -151,6 +165,10 @@ public:
writeUint32BE((uint32)value);
}
+ FORCEINLINE void writeSint64BE(int64 value) {
+ writeUint64BE((uint64)value);
+ }
+
/**
* Write the given string to the stream.
* This writes str.size() characters, but no terminating zero byte.
@@ -241,6 +259,19 @@ public:
return FROM_LE_32(val);
}
+ /**
+ * Read an unsigned 64-bit word stored in little endian (LSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ uint32 readUint64LE() {
+ uint64 val;
+ read(&val, 8);
+ return FROM_LE_64(val);
+ }
+
/**
* Read an unsigned 16-bit word stored in big endian (MSB first) order
* from the stream and return it.
@@ -267,6 +298,19 @@ public:
return FROM_BE_32(val);
}
+ /**
+ * Read an unsigned 64-bit word stored in big endian (MSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ uint32 readUint64BE() {
+ uint64 val;
+ read(&val, 8);
+ return FROM_BE_64(val);
+ }
+
/**
* Read a signed 16-bit word stored in little endian (LSB first) order
* from the stream and return it.
@@ -289,6 +333,17 @@ public:
return (int32)readUint32LE();
}
+ /**
+ * Read a signed 64-bit word stored in little endian (LSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ FORCEINLINE int64 readSint64LE() {
+ return (int64)readUint64LE();
+ }
+
/**
* Read a signed 16-bit word stored in big endian (MSB first) order
* from the stream and return it.
@@ -311,6 +366,17 @@ public:
return (int32)readUint32BE();
}
+ /**
+ * Read a signed 64-bit word stored in big endian (MSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ FORCEINLINE int64 readSint64BE() {
+ return (int64)readUint64BE();
+ }
+
/**
* Read the specified amount of data into a malloc'ed buffer
* which then is wrapped into a MemoryReadStream.
--
cgit v1.2.3
From ff35d7118c0a61a472b74d87337ee62eac993ce1 Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Wed, 17 Sep 2014 15:49:44 -0500
Subject: SWORD25: Create a set of functions for manually serializing a double
Since we can't assume IEEE.
---
engines/sword25/util/double_serializer.cpp | 138 +++++++++++++++++++++++++++++
engines/sword25/util/double_serializer.h | 95 ++++++++++++++++++++
2 files changed, 233 insertions(+)
create mode 100644 engines/sword25/util/double_serializer.cpp
create mode 100644 engines/sword25/util/double_serializer.h
diff --git a/engines/sword25/util/double_serializer.cpp b/engines/sword25/util/double_serializer.cpp
new file mode 100644
index 0000000000..d7ba4f3052
--- /dev/null
+++ b/engines/sword25/util/double_serializer.cpp
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sword25/util/double_serializer.h"
+
+#include "common/scummsys.h"
+
+
+namespace Util {
+
+SerializedDouble encodeDouble(double value) {
+ // Split the value into its significand and exponent
+ int exponent;
+ double significand = frexp(value, &exponent);
+
+ // Shift the the first part of the significand into the integer range
+ double shiftedsignificandPart = ldexp(abs(significand), 32);
+ uint32 significandOne = uint32(floor(shiftedsignificandPart));
+
+ // Shift the remainder of the significand into the integer range
+ shiftedsignificandPart -= significandOne;
+ uint32 significandTwo = (uint32)(ldexp(shiftedsignificandPart, 31));
+
+ SerializedDouble returnValue;
+ returnValue.significandOne = significandOne; // SignificandOne
+ returnValue.signAndSignificandTwo = ((uint32)(value < 0 ? 1 : 0) << 31) | // Sign
+ significandTwo; // SignificandTwo
+ returnValue.exponent = (int16)exponent;
+ return returnValue;
+}
+
+double decodeDouble(SerializedDouble value) {
+ // Expand the exponent and the parts of the significand
+ int exponent = (int)value.exponent;
+ double expandedsignificandOne = (double)value.significandOne;
+ double expandedsignificandTwo = (double)(value.signAndSignificandTwo & 0x7FFFFFFF);
+
+ // Deflate the significand
+ double shiftedsignificand = ldexp(expandedsignificandTwo, -21);
+ double significand = ldexp(expandedsignificandOne + shiftedsignificand, -32);
+
+ // Re-calculate the actual double
+ double returnValue = ldexp(significand, exponent);
+
+ // Check the sign bit and return
+ return ((value.signAndSignificandTwo & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
+}
+
+uint64 encodeDouble_64(double value) {
+ // Split the value into its significand and exponent
+ int exponent;
+ double significand = frexp(value, &exponent);
+
+ // Shift the significand into the integer range
+ double shiftedsignificand = ldexp(abs(significand), 53);
+
+ // Combine everything using the IEEE standard
+ uint64 uintsignificand = (uint64)shiftedsignificand;
+ return ((uint64)(value < 0 ? 1 : 0) << 63) | // Sign
+ ((uint64)(exponent + 1023) << 52) | // Exponent stored as an offset to 1023
+ (uintsignificand & 0x000FFFFFFFFFFFFF); // significand with MSB inferred
+}
+
+double decodeDouble_64(uint64 value) {
+ // Expand the exponent and significand
+ int exponent = (int)((value >> 52) & 0x7FF) - 1023;
+ double expandedsignificand = (double)(0x10000000000000 /* Inferred MSB */ | (value & 0x000FFFFFFFFFFFFF));
+
+ // Deflate the significand
+ int temp;
+ double significand = frexp(expandedsignificand, &temp);
+
+ // Re-calculate the actual double
+ double returnValue = ldexp(significand, exponent);
+
+ // Check the sign bit and return
+ return ((value & 0x8000000000000000) == 0x8000000000000000) ? -returnValue : returnValue;
+}
+
+CompactSerializedDouble encodeDouble_Compact(double value) {
+ // Split the value into its significand and exponent
+ int exponent;
+ double significand = frexp(value, &exponent);
+
+ // Shift the the first part of the significand into the integer range
+ double shiftedsignificandPart = ldexp(abs(significand), 32);
+ uint32 significandOne = uint32(floor(shiftedsignificandPart));
+
+ // Shift the remainder of the significand into the integer range
+ shiftedsignificandPart -= significandOne;
+ uint32 significandTwo = (uint32)(ldexp(shiftedsignificandPart, 21));
+
+ CompactSerializedDouble returnValue;
+ returnValue.signAndSignificandOne = ((uint32)(value < 0 ? 1 : 0) << 31) | // Sign
+ (significandOne & 0x7FFFFFFF); // significandOne with MSB inferred
+ // Exponent stored as an offset to 1023
+ returnValue.exponentAndSignificandTwo = ((uint32)(exponent + 1023) << 21) | significandTwo;
+
+ return returnValue;
+}
+
+double decodeDouble_Compact(CompactSerializedDouble value) {
+ // Expand the exponent and the parts of the significand
+ int exponent = (int)(value.exponentAndSignificandTwo >> 21) - 1023;
+ double expandedsignificandOne = (double)(0x80000000 /* Inferred MSB */ | (value.signAndSignificandOne & 0x7FFFFFFF));
+ double expandedsignificandTwo = (double)(value.exponentAndSignificandTwo & 0x1FFFFF);
+
+ // Deflate the significand
+ double shiftedsignificand = ldexp(expandedsignificandTwo, -21);
+ double significand = ldexp(expandedsignificandOne + shiftedsignificand, -32);
+
+ // Re-calculate the actual double
+ double returnValue = ldexp(significand, exponent);
+
+ // Check the sign bit and return
+ return ((value.signAndSignificandOne & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/util/double_serializer.h b/engines/sword25/util/double_serializer.h
new file mode 100644
index 0000000000..e90338c369
--- /dev/null
+++ b/engines/sword25/util/double_serializer.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 DOUBLE_SERIALIZATION_H
+#define DOUBLE_SERIALIZATION_H
+
+#include "common/types.h"
+
+
+namespace Util {
+
+struct SerializedDouble {
+ uint32 significandOne;
+ uint32 signAndSignificandTwo;
+ int16 exponent;
+};
+
+struct CompactSerializedDouble {
+ uint32 signAndSignificandOne;
+ uint32 exponentAndSignificandTwo;
+};
+
+/**
+ * Encodes a double as two uint32 and a one int16
+ *
+ * Supports denormalized numbers. Does NOT support NaN, or Inf
+ *
+ * @param value The value to encode
+ * @return The encoded value
+ */
+SerializedDouble encodeDouble(double value);
+/**
+ * Decodes a previously encoded double
+ *
+ * @param value The value to decode
+ * @return The decoded value
+ */
+double decodeDouble(SerializedDouble value);
+
+/**
+ * Encodes a double as a uint64
+ *
+ * Does NOT support denormalized numbers. Does NOT support NaN, or Inf
+ *
+ * @param value The value to encode
+ * @return The encoded value
+ */
+uint64 encodeDouble_64(double value);
+/**
+ * Decodes a previously encoded double
+ *
+ * @param value The value to decode
+ * @return The decoded value
+ */
+double decodeDouble_64(uint64 value);
+
+/**
+ * Encodes a double as two uint32
+ *
+ * Does NOT support denormalized numbers. Does NOT support NaN, or Inf
+ *
+ * @param value The value to encode
+ * @return The encoded value
+ */
+CompactSerializedDouble encodeDouble_Compact(double value);
+/**
+ * Decodes a previously encoded double
+ *
+ * @param value The value to decode
+ * @return The decoded value
+ */
+double decodeDouble_Compact(CompactSerializedDouble value);
+
+} // End of namespace Sword25
+
+#endif
--
cgit v1.2.3
From efcd6196eeaa2bff468bbed8d07040e60ca3c136 Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Wed, 17 Sep 2014 15:52:26 -0500
Subject: SWORD25: Create a function for serializing lua objects
This function is very similar to the Pluto function. However, this code
is much cleaner and is endian-safe
---
engines/sword25/util/lua_serialization.h | 42 ++
engines/sword25/util/lua_serializer.cpp | 852 +++++++++++++++++++++++++++++++
2 files changed, 894 insertions(+)
create mode 100644 engines/sword25/util/lua_serialization.h
create mode 100644 engines/sword25/util/lua_serializer.cpp
diff --git a/engines/sword25/util/lua_serialization.h b/engines/sword25/util/lua_serialization.h
new file mode 100644
index 0000000000..0f0c3bd0b2
--- /dev/null
+++ b/engines/sword25/util/lua_serialization.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LUA_SERIALIZATION_H
+#define LUA_SERIALIZATION_H
+
+#include "sword25/util/lua/lua.h"
+
+
+namespace Common {
+class WriteStream;
+}
+
+
+namespace Lua {
+
+#define PERMANENT_TYPE 101
+
+void serializeLua(lua_State *luaState, Common::WriteStream *writeStream);
+
+} // End of namespace Lua
+
+#endif
diff --git a/engines/sword25/util/lua_serializer.cpp b/engines/sword25/util/lua_serializer.cpp
new file mode 100644
index 0000000000..b2bbca6be9
--- /dev/null
+++ b/engines/sword25/util/lua_serializer.cpp
@@ -0,0 +1,852 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "sword25/util/lua_serialization.h"
+
+#include "sword25/util/double_serializer.h"
+
+#include "common/stream.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+
+
+namespace Lua {
+
+#define NUMTYPES 9
+
+static const char* typenames[] = {
+ "nil",
+ "boolean",
+ "lightuserdata",
+ "number",
+ "string",
+ "table",
+ "function",
+ "userdata",
+ "thread"
+};
+
+#define PERMANENT_TYPE 101
+
+/* A simple reimplementation of the unfortunately static function luaA_index.
+ * Does not support the global table, registry, or upvalues. */
+static StkId getobject(lua_State *luaState, int stackpos) {
+ if(stackpos > 0) {
+ lua_assert(luaState->base+stackpos-1 < luaState->top);
+ return luaState->base+stackpos-1;
+ } else {
+ lua_assert(L->top-stackpos >= L->base);
+ return luaState->top+stackpos;
+ }
+}
+
+
+struct SerializationInfo {
+ lua_State *luaState;
+ Common::WriteStream *writeStream;
+ uint counter;
+};
+
+static void serializeObject(SerializationInfo *info);
+
+static void serializeBoolean(SerializationInfo *info);
+static void serializeLightUserData(SerializationInfo *info);
+static void serializeNumber(SerializationInfo *info);
+static void serializeString(SerializationInfo *info);
+static void serializeTable(SerializationInfo *info);
+static void serializeFunction(SerializationInfo *info);
+static void serializeThread(SerializationInfo *info);
+static void serializeProto(SerializationInfo *info);
+static void serializeUpValue(SerializationInfo *info);
+static void serializeUserData(SerializationInfo *info);
+
+
+void serializeLua(lua_State *luaState, Common::WriteStream *writeStream) {
+ SerializationInfo info;
+ info.luaState = luaState;
+ info.writeStream = writeStream;
+ info.counter = 0u;
+
+ // The process starts with the lua stack as follows:
+ // >>>>> permTbl rootObj
+ // That's the table of permanents and the root object to be serialized
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(luaState, 4);
+ assert(lua_gettop(luaState) == 2);
+ // And that the root isn't nil
+ assert(!lua_isnil(luaState, 2));
+
+ // Create a table to hold indexes of everything that's serialized
+ // This allows us to only serialize an object once
+ // Every other time, just reference the index
+ lua_newtable(luaState);
+ // >>>>> permTbl rootObj indexTbl
+
+ // Now we're going to make the table weakly keyed. This prevents the
+ // GC from visiting it and trying to mark things it doesn't want to
+ // mark in tables, e.g. upvalues. All objects in the table are
+ // a priori reachable, so it doesn't matter that we do this.
+
+ // Create the metatable
+ lua_newtable(luaState);
+ // >>>>> permTbl rootObj indexTbl metaTbl
+
+ lua_pushstring(luaState, "__mode");
+ // >>>>> permTbl rootObj indexTbl metaTbl "__mode"
+
+ lua_pushstring(luaState, "k");
+ // >>>>> permTbl rootObj indexTbl metaTbl "__mode" "k"
+
+ lua_settable(luaState, 4);
+ // >>>>> permTbl rootObj indexTbl metaTbl
+
+ lua_setmetatable(luaState, 3);
+ // >>>>> permTbl rootObj indexTbl
+
+ // Swap the indexTable and the rootObj
+ lua_insert(luaState, 2);
+ // >>>>> permTbl indexTbl rootObj
+
+ // Serialize the root recursively
+ serializeObject(&info);
+
+ // Return the stack back to the original state
+ lua_remove(luaState, 2);
+ // >>>>> permTbl rootObj
+}
+
+static void serializeObject(SerializationInfo *info) {
+ // The stack can potentially have many things on it
+ // The object we want to serialize is the item on the top of the stack
+ // >>>>> permTbl indexTbl rootObj ...... obj
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // If the object has already been written, don't write it again
+ // Instead write the index of the object from the indexTbl
+
+ // Check the indexTbl
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ lua_rawget(info->luaState, 2);
+ // >>>>> permTbl indexTbl rootObj ...... obj ?index?
+
+ // If the index isn't nil, the object has already been written
+ if (!lua_isnil(info->luaState, -1)) {
+ // Write out a flag that indicates that it's an index
+ info->writeStream->writeByte(0);
+
+ // Retrieve the index from the stack
+ uint *index = (uint *)lua_touserdata(info->luaState, -1);
+
+ // Write out the index
+ info->writeStream->writeUint32LE(*index);
+
+ // Pop the index off the stack
+ lua_pop(info->luaState, 1);
+
+ return;
+ }
+
+ // Pop the nil off the stack
+ lua_pop(info->luaState, 1);
+
+ // Write out a flag that indicates that this is a real object
+ info->writeStream->writeByte(1);
+
+ // If the object itself is nil, then write out a zero as a placeholder
+ if (lua_isnil(info->luaState, -1)) {
+ info->writeStream->writeByte(0);
+
+ return;
+ }
+
+ // Add the object to the indexTbl
+
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ uint *ref = (uint *)lua_newuserdata(info->luaState, sizeof(uint));
+ *ref = ++(info->counter);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj index
+
+ lua_rawset(info->luaState, 2);
+ // >>>>> permTbl indexTbl rootObj ...... obj
+
+
+ // Write out the index
+ info->writeStream->writeUint32LE(info->counter);
+
+
+ // Objects that are in the permanents table are serialized in a special way
+
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ lua_gettable(info->luaState, 1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj ?permKey?
+
+ if (!lua_isnil(info->luaState, -1)) {
+ // Write out the type
+ info->writeStream->writeSint32LE(PERMANENT_TYPE);
+
+ // Serialize the key
+ serializeObject(info);
+
+ // Pop the key off the stack
+ lua_pop(info->luaState, 1);
+
+ return;
+ }
+
+ // Pop the nil off the stack
+ lua_pop(info->luaState, 1);
+
+ // Query the type of the object
+ int objType = lua_type(info->luaState, -1);
+
+ // Write it out
+ info->writeStream->writeSint32LE(objType);
+
+ // Serialize the object by its type
+
+ switch (objType) {
+ case LUA_TBOOLEAN:
+ serializeBoolean(info);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ // You can't serialize a pointer
+ // It would be meaningless on the next run
+ assert(0);
+ break;
+ case LUA_TNUMBER:
+ serializeNumber(info);
+ break;
+ case LUA_TSTRING:
+ serializeString(info);
+ break;
+ case LUA_TTABLE:
+ serializeTable(info);
+ break;
+ case LUA_TFUNCTION:
+ serializeFunction(info);
+ break;
+ case LUA_TTHREAD:
+ serializeThread(info);
+ break;
+ case LUA_TPROTO:
+ serializeProto(info);
+ break;
+ case LUA_TUPVAL:
+ serializeUpValue(info);
+ break;
+ case LUA_TUSERDATA:
+ serializeUserData(info);
+ break;
+ default:
+ assert(0);
+ }
+}
+
+static void serializeBoolean(SerializationInfo *info) {
+ int value = lua_toboolean(info->luaState, -1);
+
+ info->writeStream->writeSint32LE(value);
+}
+
+static void serializeNumber(SerializationInfo *info) {
+ lua_Number value = lua_tonumber(info->luaState, -1);
+
+#if 1
+ Util::SerializedDouble serializedValue(Util::encodeDouble(value));
+
+ info->writeStream->writeUint32LE(serializedValue.significandOne);
+ info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
+ info->writeStream->writeSint16LE(serializedValue.exponent);
+#else
+ // NOTE: We need to store a double. Unfortunately, we have to accommodate endianness.
+ // Also, I don't know if we can assume all compilers use IEEE double
+ // Therefore, I have chosen to store the double as a string.
+ Common::String buffer = Common::String::format("%f", value);
+
+ info->writeStream->write(buffer.c_str(), buffer.size());
+#endif
+
+}
+
+static void serializeString(SerializationInfo *info) {
+ // Hard cast to a uint32 to force size_t to an explicit size
+ // *Theoretically* this could truncate, but if we have a 4gb string, we have bigger problems
+ uint32 length = static_cast(lua_strlen(info->luaState, -1));
+ info->writeStream->writeUint32LE(length);
+
+ const char* str = lua_tostring(info->luaState, -1);
+ info->writeStream->write(str, length);
+}
+
+/* Choose whether to do a regular or special persistence based on an object's
+ * metatable. "default" is whether the object, if it doesn't have a __persist
+ * entry, is literally persistable or not.
+ * Pushes the unpersist closure and returns true if special persistence is
+ * used. */
+static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 4);
+
+ // Check whether we should persist literally, or via the __persist metafunction
+ if (!lua_getmetatable(info->luaState, -1)) {
+ if (defaction) {
+ // Write out a flag declaring that the metatable doesn't exist
+ info->writeStream->writeSint32LE(0);
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Type not literally persistable by default");
+ lua_error(info->luaState);
+ }
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl
+ lua_pushstring(info->luaState, "__persist");
+ // >>>>> permTbl indexTbl rootObj ...... obj metaTbl "__persist"
+
+ lua_rawget(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... obj metaTbl ?__persist?
+
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... obj metaTbl nil
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ if (defaction) {
+ // Write out a flag declaring there is no persistence metafunction
+ info->writeStream->writeSint32LE(0);
+
+ return 0;
+ } else {
+ lua_pushstring(info->luaState, "Type not literally persistable by default");
+ lua_error(info->luaState);
+
+ return 0; /* not reached */
+ }
+
+ } else if (lua_isboolean(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... obj metaTbl bool
+ if (lua_toboolean(info->luaState, -1)) {
+ // Write out a flag declaring such
+ info->writeStream->writeSint32LE(0);
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl true */
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Metatable forbade persistence");
+ lua_error(info->luaState);
+
+ return false; /* not reached */
+ }
+ } else if (!lua_isfunction(info->luaState, -1)) {
+ lua_pushstring(info->luaState, "__persist not nil, boolean, or function");
+ lua_error(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl __persist
+ lua_pushvalue(info->luaState, -3);
+ // >>>>> permTbl indexTbl ...... obj metaTbl __persist obj
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl ?func?
+
+ if (!lua_isfunction(info->luaState, -1)) {
+ lua_pushstring(info->luaState, "__persist function did not return a function");
+ lua_error(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl func
+
+ // Write out a flag that the function exists
+ info->writeStream->writeSint32LE(1);
+
+ // Serialize the function
+ serializeObject(info);
+
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ return true;
+}
+
+static void serializeTable(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 3);
+
+ // Test if the object needs special serialization
+ if (serializeSpecialObject(info, 1)) {
+ return;
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // First, serialize the metatable (if any)
+ if (!lua_getmetatable(info->luaState, -1)) {
+ lua_pushnil(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl metaTbl/nil */
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+
+
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... tbl nil
+
+ // Now, persist all k/v pairs
+ while (lua_next(info->luaState, -2)) {
+ // >>>>> permTbl indexTbl ...... tbl k v */
+
+ lua_pushvalue(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... tbl k v k */
+
+ // Serialize the key
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl k v */
+
+ // Serialize the value
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl k */
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Terminate the list with a nil
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+}
+
+static void pushObject(lua_State *luaState, TValue *obj) {
+ setobj2s(luaState, luaState->top, obj);
+
+ api_check(luaState, luaState->top < luaState->ci->top);
+ luaState->top++;
+}
+
+static void pushProto(lua_State *luaState, Proto *proto) {
+ TValue obj;
+ setptvalue(luaState, &obj, proto);
+
+ pushObject(luaState, &obj);
+}
+
+static void pushUpVal(lua_State *luaState, UpVal *upval) {
+ TValue obj;
+
+ obj.value.gc = cast(GCObject *, upval);
+ obj.tt = LUA_TUPVAL;
+ checkliveness(G(L), obj);
+
+ pushObject(luaState, &obj);
+}
+
+static void pushString(lua_State *luaState, TString *str) {
+ TValue o;
+ setsvalue(luaState, &o, str);
+
+ pushObject(luaState, &o);
+}
+
+static void serializeFunction(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... func
+ Closure *cl = clvalue(getobject(info->luaState, -1));
+ lua_checkstack(info->luaState, 2);
+
+ if (cl->c.isC) {
+ /* It's a C function. For now, we aren't going to allow
+ * persistence of C closures, even if the "C proto" is
+ * already in the permanents table. */
+ lua_pushstring(info->luaState, "Attempt to persist a C function");
+ lua_error(info->luaState);
+ } else {
+ // It's a Lua closure
+
+ // We don't really _NEED_ the number of upvals, but it'll simplify things a bit
+ info->writeStream->writeByte(cl->l.p->nups);
+
+ // Serialize the prototype
+ pushProto(info->luaState, cl->l.p);
+ // >>>>> permTbl indexTbl ...... func proto */
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ // Serialize upvalue values (not the upvalue objects themselves)
+ for (byte i=0; il.p->nups; i++) {
+ // >>>>> permTbl indexTbl ...... func
+ pushUpVal(info->luaState, cl->l.upvals[i]);
+ // >>>>> permTbl indexTbl ...... func upval
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // >>>>> permTbl indexTbl ...... func
+
+ // Serialize function environment
+ lua_getfenv(info->luaState, -1);
+ // >>>>> permTbl indexTbl ...... func fenv
+
+ if (lua_equal(info->luaState, -1, LUA_GLOBALSINDEX)) {
+ // Function has the default fenv
+
+ // >>>>> permTbl indexTbl ...... func _G
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... func nil
+ }
+
+ // >>>>> permTbl indexTbl ...... func fenv/nil
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+}
+
+/* Appends one stack to another stack, but the stack is reversed in the process */
+static size_t appendStackToStack_rev(lua_State *from, lua_State *to) {
+ for (StkId id = from->top - 1; id >= from->stack; --id) {
+ setobj2s(to, to->top, id);
+ to->top++;
+ }
+
+ return from->top - from->stack;
+}
+
+static void serializeThread(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... thread
+ lua_State *threadState = lua_tothread(info->luaState, -1);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, threadState->top - threadState->stack + 1);
+
+ if (info->luaState == threadState) {
+ lua_pushstring(info->luaState, "Can't persist currently running thread");
+ lua_error(info->luaState);
+ return; /* not reached */
+ }
+
+ // Persist the stack
+
+ // We *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
+ uint stackSize = static_cast(appendStackToStack_rev(threadState, info->luaState));
+ info->writeStream->writeUint32LE(stackSize);
+
+ // >>>>> permTbl indexTbl ...... thread (reversed contents of thread stack) */
+ for (; stackSize > 0; --stackSize) {
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+
+ // Now, serialize the CallInfo stack
+
+ // Again, we *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
+ uint32 numFrames = static_cast((threadState->ci - threadState->base_ci) + 1);
+ info->writeStream->writeUint32LE(numFrames);
+
+ for (uint32 i = 0; i < numFrames; i++) {
+ CallInfo *ci = threadState->base_ci + i;
+
+ // Same argument as above about truncation
+ uint32 stackBase = static_cast(ci->base - threadState->stack);
+ uint32 stackFunc = static_cast(ci->func - threadState->stack);
+ uint32 stackTop = static_cast(ci->top - threadState->stack);
+
+ info->writeStream->writeUint32LE(stackBase);
+ info->writeStream->writeUint32LE(stackFunc);
+ info->writeStream->writeUint32LE(stackTop);
+
+ info->writeStream->writeSint32LE(ci->nresults);
+
+ uint32 savedpc = (ci != threadState->base_ci) ? static_cast(ci->savedpc - ci_func(ci)->l.p->code) : 0u;
+ info->writeStream->writeUint32LE(savedpc);
+ }
+
+
+ // Serialize the state's other parameters, with the exception of upval stuff
+
+ assert(threadState->nCcalls <= 1);
+ info->writeStream->writeByte(threadState->status);
+
+ // Same argument as above about truncation
+ uint32 stackBase = static_cast(threadState->base - threadState->stack);
+ uint32 stackFunc = static_cast(threadState->top - threadState->stack);
+ info->writeStream->writeUint32LE(stackBase);
+ info->writeStream->writeUint32LE(stackFunc);
+
+ // Same argument as above about truncation
+ uint32 stackOffset = static_cast(threadState->errfunc);
+ info->writeStream->writeUint32LE(stackOffset);
+
+ // Finally, record upvalues which need to be reopened
+ // See the comment above serializeUpVal() for why we do this
+
+ UpVal *upVal;
+
+ // >>>>> permTbl indexTbl ...... thread
+ for (GCObject *gcObject = threadState->openupval; gcObject != NULL; gcObject = upVal->next) {
+ upVal = gco2uv(gcObject);
+
+ /* Make sure upvalue is really open */
+ assert(upVal->v != &upVal->u.value);
+
+ pushUpVal(info->luaState, upVal);
+ // >>>>> permTbl indexTbl ...... thread upVal
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+
+ // Same argument as above about truncation
+ uint32 stackpos = static_cast(upVal->v - threadState->stack);
+ info->writeStream->writeUint32LE(stackpos);
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... thread nil
+
+ // Use nil as a terminator
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+}
+
+static void serializeProto(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... proto
+ Proto *proto = gco2p(getobject(info->luaState, -1)->value.gc);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // Serialize constant refs */
+ info->writeStream->writeSint32LE(proto->sizek);
+
+ for (int i = 0; i < proto->sizek; ++i) {
+ pushObject(info->luaState, &proto->k[i]);
+ // >>>>> permTbl indexTbl ...... proto const
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize inner Proto refs
+ info->writeStream->writeSint32LE(proto->sizep);
+
+ for (int i = 0; i < proto->sizep; ++i)
+ {
+ pushProto(info->luaState, proto->p[i]);
+ // >>>>> permTbl indexTbl ...... proto subProto */
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize the code
+ info->writeStream->writeSint32LE(proto->sizecode);
+
+ uint32 len = static_cast(sizeof(Instruction) * proto->sizecode);
+ info->writeStream->write(proto->code, len);
+
+
+ // Serialize upvalue names
+ info->writeStream->writeSint32LE(proto->sizeupvalues);
+
+ for (int i = 0; i < proto->sizeupvalues; ++i)
+ {
+ pushString(info->luaState, proto->upvalues[i]);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+
+ // Serialize local variable infos
+ info->writeStream->writeSint32LE(proto->sizelocvars);
+
+ for (int i = 0; i < proto->sizelocvars; ++i) {
+ pushString(info->luaState, proto->locvars[i].varname);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ info->writeStream->writeSint32LE(proto->locvars[i].startpc);
+ info->writeStream->writeSint32LE(proto->locvars[i].endpc);
+ }
+
+
+ // Serialize source string
+ pushString(info->luaState, proto->source);
+ // >>>>> permTbl indexTbl ...... proto sourceStr
+
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize line numbers
+ info->writeStream->writeSint32LE(proto->sizelineinfo);
+
+ if (proto->sizelineinfo) {
+ uint32 len = static_cast(sizeof(int) * proto->sizelineinfo);
+ info->writeStream->write(proto->lineinfo, len);
+ }
+
+ // Serialize linedefined and lastlinedefined
+ info->writeStream->writeSint32LE(proto->linedefined);
+ info->writeStream->writeSint32LE(proto->lastlinedefined);
+
+
+ // Serialize misc values
+ info->writeStream->writeByte(proto->nups);
+ info->writeStream->writeByte(proto->numparams);
+ info->writeStream->writeByte(proto->is_vararg);
+ info->writeStream->writeByte(proto->maxstacksize);
+}
+
+/* Upvalues are tricky. Here's why.
+ *
+ * A particular upvalue may be either "open", in which case its member v
+ * points into a thread's stack, or "closed" in which case it points to the
+ * upvalue itself. An upvalue is closed under any of the following conditions:
+ * -- The function that initially declared the variable "local" returns
+ * -- The thread in which the closure was created is garbage collected
+ *
+ * To make things wackier, just because a thread is reachable by Lua doesn't
+ * mean it's in our root set. We need to be able to treat an open upvalue
+ * from an unreachable thread as a closed upvalue.
+ *
+ * The solution:
+ * (a) For the purposes of serializing, don't indicate whether an upvalue is
+ * closed or not.
+ * (b) When unserializing, pretend that all upvalues are closed.
+ * (c) When serializing, persist all open upvalues referenced by a thread
+ * that is persisted, and tag each one with the corresponding stack position
+ * (d) When unserializing, "reopen" each of these upvalues as the thread is
+ * unserialized
+ */
+static void serializeUpValue(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... upval
+ assert(ttype(getobject(info->luaState, -1)) == LUA_TUPVAL);
+ UpVal *upValue = gco2uv(getobject(info->luaState, -1)->value.gc);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ // We can't permit the upValue to linger around on the stack, as Lua
+ // will bail if its GC finds it.
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ......
+
+ pushObject(info->luaState, upValue->v);
+ // >>>>> permTbl indexTbl ...... obj
+
+ serializeObject(info);
+ // >>>>> permTbl indexTbl ...... obj
+}
+
+static void serializeUserData(SerializationInfo *info) {
+ // >>>>> permTbl rootObj ...... udata
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // Test if the object needs special serialization
+ if (serializeSpecialObject(info, 0)) {
+ return;
+ }
+
+ // Use literal persistence
+
+ // Hard cast to a uint32 length
+ // This could lead to truncation, but if we have a 4gb block of data, we have bigger problems
+ uint32 length = static_cast(uvalue(getobject(info->luaState, -1))->len);
+ info->writeStream->writeUint32LE(length);
+
+ info->writeStream->write(lua_touserdata(info->luaState, -1), length);
+
+ // Serialize the metatable (if any)
+ if (!lua_getmetatable(info->luaState, -1)) {
+ lua_pushnil(info->luaState);
+ }
+
+ // >>>>> permTbl rootObj ...... udata metaTbl/nil
+ serializeObject(info);
+
+ lua_pop(info->luaState, 1);
+ /* perms reftbl ... udata */
+}
+
+
+} // End of namespace Lua
--
cgit v1.2.3
From a4685796ce2e876ec4025a1a084f8c3f4500af4e Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Fri, 19 Dec 2014 11:49:42 -0600
Subject: TEST: Add unit tests for uint64 reading
---
test/common/endian.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/test/common/endian.h b/test/common/endian.h
index cba7618c43..f083d1248c 100644
--- a/test/common/endian.h
+++ b/test/common/endian.h
@@ -10,6 +10,18 @@ class EndianTestSuite : public CxxTest::TestSuite
TS_ASSERT_EQUALS(MKTAG('A','B','C','D'), tag);
}
+ void test_READ_BE_UINT64() {
+ const char data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
+ uint64 value = READ_BE_UINT64(data);
+ TS_ASSERT_EQUALS(value, 0x123456789ABCDEFFULL);
+ }
+
+ void test_READ_LE_UINT64() {
+ const char data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
+ uint64 value = READ_LE_UINT64(data);
+ TS_ASSERT_EQUALS(value, 0xFFEDCBA978563412ULL);
+ }
+
void test_READ_BE_UINT32() {
const char data[4] = { 0x12, 0x34, 0x56, 0x78 };
uint32 value = READ_BE_UINT32(data);
--
cgit v1.2.3
From dedfd7aa84360b5950b653109b3679c7f469aebc Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Fri, 19 Dec 2014 13:38:26 -0600
Subject: SWORD25: Move common functions to their own set of files so they can
be shared
---
engines/sword25/util/lua_serialization_util.cpp | 77 +++++++++++++++++++++
engines/sword25/util/lua_serialization_util.h | 43 ++++++++++++
engines/sword25/util/lua_serializer.cpp | 91 +++++--------------------
3 files changed, 138 insertions(+), 73 deletions(-)
create mode 100644 engines/sword25/util/lua_serialization_util.cpp
create mode 100644 engines/sword25/util/lua_serialization_util.h
diff --git a/engines/sword25/util/lua_serialization_util.cpp b/engines/sword25/util/lua_serialization_util.cpp
new file mode 100644
index 0000000000..80009aff60
--- /dev/null
+++ b/engines/sword25/util/lua_serialization_util.cpp
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distri8buted in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "sword25/util/lua_serialization_util.h"
+
+#include "common/scummsys.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+
+
+namespace Lua {
+
+void pushObject(lua_State *luaState, TValue *obj) {
+ setobj2s(luaState, luaState->top, obj);
+
+ api_check(luaState, luaState->top < luaState->ci->top);
+ luaState->top++;
+}
+
+void pushProto(lua_State *luaState, Proto *proto) {
+ TValue obj;
+ setptvalue(luaState, &obj, proto);
+
+ pushObject(luaState, &obj);
+}
+
+void pushUpValue(lua_State *luaState, UpVal *upval) {
+ TValue obj;
+
+ obj.value.gc = cast(GCObject *, upval);
+ obj.tt = LUA_TUPVAL;
+ checkliveness(G(L), obj);
+
+ pushObject(luaState, &obj);
+}
+
+void pushString(lua_State *luaState, TString *str) {
+ TValue o;
+ setsvalue(luaState, &o, str);
+
+ pushObject(luaState, &o);
+}
+
+/* A simple reimplementation of the unfortunately static function luaA_index.
+ * Does not support the global table, registry, or upvalues. */
+StkId getObject(lua_State *luaState, int stackpos) {
+ if(stackpos > 0) {
+ lua_assert(luaState->base+stackpos-1 < luaState->top);
+ return luaState->base+stackpos-1;
+ } else {
+ lua_assert(L->top-stackpos >= L->base);
+ return luaState->top+stackpos;
+ }
+}
+
+} // End of namespace Lua
diff --git a/engines/sword25/util/lua_serialization_util.h b/engines/sword25/util/lua_serialization_util.h
new file mode 100644
index 0000000000..6c55d0dd53
--- /dev/null
+++ b/engines/sword25/util/lua_serialization_util.h
@@ -0,0 +1,43 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distri8buted in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 LUA_SERIALIZATION_UTIL_H
+#define LUA_SERIALIZATION_UTIL_H
+
+
+struct lua_State;
+
+#include "lua/lobject.h"
+
+typedef TValue *StkId;
+
+namespace Lua {
+
+void pushObject(lua_State *luaState, TValue *obj);
+void pushProto(lua_State *luaState, Proto *proto);
+void pushUpValue(lua_State *luaState, UpVal *upval);
+void pushString(lua_State *luaState, TString *str);
+StkId getObject(lua_State *luaState, int stackpos);
+
+} // End of namespace Lua
+
+#endif
diff --git a/engines/sword25/util/lua_serializer.cpp b/engines/sword25/util/lua_serializer.cpp
index b2bbca6be9..8c61383fba 100644
--- a/engines/sword25/util/lua_serializer.cpp
+++ b/engines/sword25/util/lua_serializer.cpp
@@ -23,44 +23,19 @@
#include "sword25/util/lua_serialization.h"
#include "sword25/util/double_serializer.h"
+#include "sword25/util/lua_serialization_util.h"
#include "common/stream.h"
#include "lua/lobject.h"
#include "lua/lstate.h"
+#include "lua/lgc.h"
namespace Lua {
-#define NUMTYPES 9
-
-static const char* typenames[] = {
- "nil",
- "boolean",
- "lightuserdata",
- "number",
- "string",
- "table",
- "function",
- "userdata",
- "thread"
-};
-
#define PERMANENT_TYPE 101
-/* A simple reimplementation of the unfortunately static function luaA_index.
- * Does not support the global table, registry, or upvalues. */
-static StkId getobject(lua_State *luaState, int stackpos) {
- if(stackpos > 0) {
- lua_assert(luaState->base+stackpos-1 < luaState->top);
- return luaState->base+stackpos-1;
- } else {
- lua_assert(L->top-stackpos >= L->base);
- return luaState->top+stackpos;
- }
-}
-
-
struct SerializationInfo {
lua_State *luaState;
Common::WriteStream *writeStream;
@@ -70,7 +45,6 @@ struct SerializationInfo {
static void serializeObject(SerializationInfo *info);
static void serializeBoolean(SerializationInfo *info);
-static void serializeLightUserData(SerializationInfo *info);
static void serializeNumber(SerializationInfo *info);
static void serializeString(SerializationInfo *info);
static void serializeTable(SerializationInfo *info);
@@ -319,13 +293,15 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
// Check whether we should persist literally, or via the __persist metafunction
if (!lua_getmetatable(info->luaState, -1)) {
if (defaction) {
- // Write out a flag declaring that the metatable doesn't exist
+ // Write out a flag declaring that the object isn't special and should be persisted normally
info->writeStream->writeSint32LE(0);
return false;
} else {
lua_pushstring(info->luaState, "Type not literally persistable by default");
lua_error(info->luaState);
+
+ return false; // Not reached
}
}
@@ -342,21 +318,21 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
// >>>>> permTbl indexTbl ...... obj
if (defaction) {
- // Write out a flag declaring there is no persistence metafunction
+ // Write out a flag declaring that the object isn't special and should be persisted normally
info->writeStream->writeSint32LE(0);
- return 0;
+ return false;
} else {
lua_pushstring(info->luaState, "Type not literally persistable by default");
lua_error(info->luaState);
- return 0; /* not reached */
+ return false; // Return false
}
} else if (lua_isboolean(info->luaState, -1)) {
// >>>>> permTbl indexTbl ...... obj metaTbl bool
if (lua_toboolean(info->luaState, -1)) {
- // Write out a flag declaring such
+ // Write out a flag declaring that the object isn't special and should be persisted normally
info->writeStream->writeSint32LE(0);
// >>>>> permTbl indexTbl ...... obj metaTbl true */
@@ -368,7 +344,7 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
lua_pushstring(info->luaState, "Metatable forbade persistence");
lua_error(info->luaState);
- return false; /* not reached */
+ return false; // Not reached
}
} else if (!lua_isfunction(info->luaState, -1)) {
lua_pushstring(info->luaState, "__persist not nil, boolean, or function");
@@ -460,40 +436,9 @@ static void serializeTable(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... tbl
}
-static void pushObject(lua_State *luaState, TValue *obj) {
- setobj2s(luaState, luaState->top, obj);
-
- api_check(luaState, luaState->top < luaState->ci->top);
- luaState->top++;
-}
-
-static void pushProto(lua_State *luaState, Proto *proto) {
- TValue obj;
- setptvalue(luaState, &obj, proto);
-
- pushObject(luaState, &obj);
-}
-
-static void pushUpVal(lua_State *luaState, UpVal *upval) {
- TValue obj;
-
- obj.value.gc = cast(GCObject *, upval);
- obj.tt = LUA_TUPVAL;
- checkliveness(G(L), obj);
-
- pushObject(luaState, &obj);
-}
-
-static void pushString(lua_State *luaState, TString *str) {
- TValue o;
- setsvalue(luaState, &o, str);
-
- pushObject(luaState, &o);
-}
-
static void serializeFunction(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... func
- Closure *cl = clvalue(getobject(info->luaState, -1));
+ Closure *cl = clvalue(getObject(info->luaState, -1));
lua_checkstack(info->luaState, 2);
if (cl->c.isC) {
@@ -520,7 +465,7 @@ static void serializeFunction(SerializationInfo *info) {
// Serialize upvalue values (not the upvalue objects themselves)
for (byte i=0; il.p->nups; i++) {
// >>>>> permTbl indexTbl ...... func
- pushUpVal(info->luaState, cl->l.upvals[i]);
+ pushUpValue(info->luaState, cl->l.upvals[i]);
// >>>>> permTbl indexTbl ...... func upval
serializeObject(info);
@@ -580,7 +525,7 @@ static void serializeThread(SerializationInfo *info) {
// Persist the stack
// We *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
- uint stackSize = static_cast(appendStackToStack_rev(threadState, info->luaState));
+ uint32 stackSize = static_cast(appendStackToStack_rev(threadState, info->luaState));
info->writeStream->writeUint32LE(stackSize);
// >>>>> permTbl indexTbl ...... thread (reversed contents of thread stack) */
@@ -644,7 +589,7 @@ static void serializeThread(SerializationInfo *info) {
/* Make sure upvalue is really open */
assert(upVal->v != &upVal->u.value);
- pushUpVal(info->luaState, upVal);
+ pushUpValue(info->luaState, upVal);
// >>>>> permTbl indexTbl ...... thread upVal
serializeObject(info);
@@ -670,7 +615,7 @@ static void serializeThread(SerializationInfo *info) {
static void serializeProto(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... proto
- Proto *proto = gco2p(getobject(info->luaState, -1)->value.gc);
+ Proto *proto = gco2p(getObject(info->luaState, -1)->value.gc);
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 2);
@@ -797,8 +742,8 @@ static void serializeProto(SerializationInfo *info) {
*/
static void serializeUpValue(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... upval
- assert(ttype(getobject(info->luaState, -1)) == LUA_TUPVAL);
- UpVal *upValue = gco2uv(getobject(info->luaState, -1)->value.gc);
+ assert(ttype(getObject(info->luaState, -1)) == LUA_TUPVAL);
+ UpVal *upValue = gco2uv(getObject(info->luaState, -1)->value.gc);
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 1);
@@ -831,7 +776,7 @@ static void serializeUserData(SerializationInfo *info) {
// Hard cast to a uint32 length
// This could lead to truncation, but if we have a 4gb block of data, we have bigger problems
- uint32 length = static_cast(uvalue(getobject(info->luaState, -1))->len);
+ uint32 length = static_cast(uvalue(getObject(info->luaState, -1))->len);
info->writeStream->writeUint32LE(length);
info->writeStream->write(lua_touserdata(info->luaState, -1), length);
--
cgit v1.2.3
From de20880d9d3dbe9ebbc26848d7a672c104495aeb Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Fri, 19 Dec 2014 13:41:58 -0600
Subject: SWORD25: Re-write the pluto unserializing function(s)
---
engines/sword25/util/lua_serialization.h | 2 +
engines/sword25/util/lua_unserializer.cpp | 1007 +++++++++++++++++++++++++++++
2 files changed, 1009 insertions(+)
create mode 100644 engines/sword25/util/lua_unserializer.cpp
diff --git a/engines/sword25/util/lua_serialization.h b/engines/sword25/util/lua_serialization.h
index 0f0c3bd0b2..549ea7968d 100644
--- a/engines/sword25/util/lua_serialization.h
+++ b/engines/sword25/util/lua_serialization.h
@@ -28,6 +28,7 @@
namespace Common {
class WriteStream;
+class ReadStream;
}
@@ -36,6 +37,7 @@ namespace Lua {
#define PERMANENT_TYPE 101
void serializeLua(lua_State *luaState, Common::WriteStream *writeStream);
+void unserializeLua(lua_State *luaState, Common::ReadStream *readStream);
} // End of namespace Lua
diff --git a/engines/sword25/util/lua_unserializer.cpp b/engines/sword25/util/lua_unserializer.cpp
new file mode 100644
index 0000000000..c561a3d99f
--- /dev/null
+++ b/engines/sword25/util/lua_unserializer.cpp
@@ -0,0 +1,1007 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "sword25/util/lua_serialization.h"
+
+#include "sword25/util/double_serializer.h"
+#include "sword25/util/lua_serialization_util.h"
+
+#include "common/stream.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+#include "lua/lopcodes.h"
+
+
+namespace Lua {
+
+struct UnSerializationInfo {
+ lua_State *luaState;
+ Common::ReadStream *readStream;
+};
+
+static void unserializeObject(UnSerializationInfo *info);
+
+static void unserializeBoolean(UnSerializationInfo *info);
+static void unserializeNumber(UnSerializationInfo *info);
+static void unserializeString(UnSerializationInfo *info);
+static void unserializeTable(UnSerializationInfo *info, int index);
+static void unserializeFunction(UnSerializationInfo *info, int index);
+static void unserializeThread(UnSerializationInfo *info, int index);
+static void unserializeProto(UnSerializationInfo *info, int index);
+static void unserializeUpValue(UnSerializationInfo *info, int index);
+static void unserializeUserData(UnSerializationInfo *info, int index);
+static void unserializePermanent(UnSerializationInfo *info, int index);
+
+
+void unserializeLua(lua_State *luaState, Common::ReadStream *readStream) {
+ UnSerializationInfo info;
+ info.luaState = luaState;
+ info.readStream = readStream;
+
+ // The process starts with the lua stack as follows:
+ // >>>>> permTbl
+ // That's the table of permanents
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(luaState, 3);
+
+ // Create a table to hold indexes of everything thats already been read
+ lua_newtable(luaState);
+ // >>>>> permTbl indexTbl
+
+ // Prevent garbage collection while we unserialize
+ lua_gc(luaState, LUA_GCSTOP, 0);
+
+ // Unserialize the root object
+ unserializeObject(&info);
+ // >>>>> permTbl indexTbl rootObj
+
+ // Re-start garbage collection
+ lua_gc(luaState, LUA_GCRESTART, 0);
+
+ // Remove the indexTbl
+ lua_replace(luaState, 2);
+ // >>>>> permTbl rootObj
+}
+
+/* The object is left on the stack. This is primarily used by unpersist, but
+ * may be used by GCed objects that may incur cycles in order to preregister
+ * the object. */
+static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ...... obj
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ lua_pushlightuserdata(info->luaState, (void *)index);
+ // >>>>> permTbl indexTbl ...... obj index
+
+ lua_pushvalue(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... obj index obj
+
+ // Push the k/v pair into the indexTbl
+ lua_settable(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+}
+
+static void unserializeObject(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ byte isARealValue = info->readStream->readByte();
+ if(isARealValue) {
+ int index = info->readStream->readSint32LE();
+ int type = info->readStream->readSint32LE();
+
+ switch(type) {
+ case LUA_TBOOLEAN:
+ unserializeBoolean(info);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ // You can't serialize a pointer
+ // It would be meaningless on the next run
+ assert(0);
+ break;
+ case LUA_TNUMBER:
+ unserializeNumber(info);
+ break;
+ case LUA_TSTRING:
+ unserializeString(info);
+ break;
+ case LUA_TTABLE:
+ unserializeTable(info, index);
+ break;
+ case LUA_TFUNCTION:
+ unserializeFunction(info, index);
+ break;
+ case LUA_TTHREAD:
+ unserializeThread(info, index);
+ break;
+ case LUA_TPROTO:
+ unserializeProto(info, index);
+ break;
+ case LUA_TUPVAL:
+ unserializeUpValue(info, index);
+ break;
+ case LUA_TUSERDATA:
+ unserializeUserData(info, index);
+ break;
+ case PERMANENT_TYPE:
+ unserializePermanent(info, index);
+ break;
+ default:
+ assert(0);
+ }
+
+
+ // >>>>> permTbl indexTbl ...... obj
+ assert(lua_type(info->luaState, -1) == type ||
+ type == PERMANENT_TYPE ||
+ // Remember, upvalues get a special dispensation, as described in boxUpValue
+ (lua_type(info->luaState, -1) == LUA_TFUNCTION && type == LUA_TUPVAL));
+
+ registerObjectInIndexTable(info, index);
+ // >>>>> permTbl indexTbl ...... obj
+ } else {
+ int index = info->readStream->readSint32LE();
+
+ if(index == 0) {
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... nil
+ } else {
+ // Fetch the object from the indexTbl
+
+ lua_pushlightuserdata(info->luaState, (void *)index);
+ // >>>>> permTbl indexTbl ...... index
+
+ lua_gettable(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... ?obj?
+
+ assert(!lua_isnil(info->luaState, -1));
+ }
+ // >>>>> permTbl indexTbl ...... obj/nil
+ }
+
+ // >>>>> permTbl indexTbl ...... obj/nil
+}
+
+static void unserializeBoolean(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ int value = info->readStream->readSint32LE();
+
+ lua_pushboolean(info->luaState, value);
+ // >>>>> permTbl indexTbl ...... bool
+}
+
+static void unserializeNumber(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ // Read the serialized double
+ Util::SerializedDouble serializedValue;
+ serializedValue.significandOne = info->readStream->readUint32LE();
+ serializedValue.signAndSignificandTwo = info->readStream->readUint32LE();
+ serializedValue.exponent = info->readStream->readSint16LE();
+
+ lua_Number value = Util::decodeDouble(serializedValue);
+
+ lua_pushnumber(info->luaState, value);
+ // >>>>> permTbl indexTbl ...... num
+}
+
+static void unserializeString(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ uint32 length = info->readStream->readUint32LE();
+ char *string = new char[length];
+
+ info->readStream->read(string, length);
+ lua_pushlstring(info->luaState, string, length);
+
+ // >>>>> permTbl indexTbl ...... string
+
+ delete[] string;
+}
+
+static void unserializeSpecialTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ unserializeObject(info);
+
+ // >>>>> permTbl indexTbl ...... spfunc
+ lua_call(info->luaState, 0, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+}
+
+static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 3);
+
+ // Preregister table for handling of cycles
+ lua_newtable(info->luaState);
+
+ // >>>>> permTbl indexTbl ...... tbl
+ registerObjectInIndexTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Unserialize metatable
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
+
+ if (lua_istable(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... tbl metaTbl
+ lua_setmetatable(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... tbl
+ } else {
+ // >>>>> permTbl indexTbl ...... tbl nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+ // >>>>> permTbl indexTbl ...... tbl
+
+
+ while (1) {
+ // >>>>> permTbl indexTbl ...... tbl
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... tbl key/nil
+
+ // The table serialization is nil terminated
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... tbl nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ break;
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl key
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... tbl value
+
+ lua_rawset(info->luaState, -3);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+}
+
+void unserializeTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ int isSpecial = info->readStream->readSint32LE();
+
+ if (isSpecial) {
+ unserializeSpecialTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+ } else {
+ unserializeLiteralTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+}
+
+
+
+void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize) {
+ global_State *globalState = G(luaState);
+
+ block = (*globalState->frealloc)(globalState->ud, block, osize, nsize);
+ globalState->totalbytes = (globalState->totalbytes - osize) + nsize;
+
+ return block;
+}
+
+#define lua_malloc(luaState, nsize) lua_realloc(luaState, nullptr, 0, nsize)
+#define lua_reallocv(luaState, block, on, n, e) lua_realloc(luaState, block, (on) * (e), (n) * (e))
+#define lua_reallocvector(luaState, vec, oldn, n, T) ((vec) = (T *)(lua_reallocv(luaState, vec, oldn, n, sizeof(T))))
+#define lua_newVector(luaState, num, T) ((T *)lua_reallocv(luaState, nullptr, 0, num, sizeof(T)))
+#define lua_new(luaState,T) (T *)lua_malloc(luaState, sizeof(T))
+
+void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
+ global_State *globalState = G(luaState);
+
+ obj->gch.next = globalState->rootgc;
+ globalState->rootgc = obj;
+ obj->gch.marked = luaC_white(globalState);
+ obj->gch.tt = type;
+}
+
+#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
+
+Closure *newLClosure(lua_State *luaState, byte numUpValues, Table *env) {
+ Closure *newClosure = (Closure *)lua_malloc(luaState, sizeLclosure(numUpValues));
+
+ lua_linkObjToGC(luaState, obj2gco(newClosure), LUA_TFUNCTION);
+
+ newClosure->l.isC = 0;
+ newClosure->l.env = env;
+ newClosure->l.nupvalues = numUpValues;
+
+ while (numUpValues--) {
+ newClosure->l.upvals[numUpValues] = NULL;
+ }
+
+ return newClosure;
+}
+
+static void pushClosure(lua_State *luaState, Closure *closure) {
+ TValue obj;
+ setclvalue(luaState, &obj, closure);
+ pushObject(luaState, &obj);
+}
+
+Proto *createProto(lua_State *luaState) {
+ Proto *newProto = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_linkObjToGC(luaState, obj2gco(newProto), LUA_TPROTO);
+
+ newProto->k = NULL;
+ newProto->sizek = 0;
+ newProto->p = NULL;
+ newProto->sizep = 0;
+ newProto->code = NULL;
+ newProto->sizecode = 0;
+ newProto->sizelineinfo = 0;
+ newProto->sizeupvalues = 0;
+ newProto->nups = 0;
+ newProto->upvalues = NULL;
+ newProto->numparams = 0;
+ newProto->is_vararg = 0;
+ newProto->maxstacksize = 0;
+ newProto->lineinfo = NULL;
+ newProto->sizelocvars = 0;
+ newProto->locvars = NULL;
+ newProto->linedefined = 0;
+ newProto->lastlinedefined = 0;
+ newProto->source = NULL;
+
+ return newProto;
+}
+
+TString *createString(lua_State *luaState, const char *str, size_t len) {
+ TString *res;
+ lua_pushlstring(luaState, str, len);
+
+ res = rawtsvalue(luaState->top - 1);
+ lua_pop(luaState, 1);
+
+ return res;
+}
+
+static Proto *makeFakeProto(lua_State *L, lu_byte nups) {
+ Proto *p = createProto(L);
+
+ p->sizelineinfo = 1;
+ p->lineinfo = lua_newVector(L, 1, int);
+ p->lineinfo[0] = 1;
+ p->sizecode = 1;
+ p->code = lua_newVector(L, 1, Instruction);
+ p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ p->source = createString(L, "", 0);
+ p->maxstacksize = 2;
+ p->nups = nups;
+ p->sizek = 0;
+ p->sizep = 0;
+
+ return p;
+}
+
+static UpVal *createUpValue(lua_State *luaState, int stackpos) {
+ UpVal *upValue = (UpVal *)lua_malloc(luaState, sizeof(UpVal));
+ lua_linkObjToGC(luaState, (GCObject *)upValue, LUA_TUPVAL);
+ upValue->tt = LUA_TUPVAL;
+ upValue->v = &upValue->u.value;
+ upValue->u.l.prev = NULL;
+ upValue->u.l.next = NULL;
+
+ const TValue *o2 = (TValue *)getObject(luaState, stackpos);
+ upValue->v->value = o2->value; upValue->v->tt = o2->tt;
+ checkliveness(G(L), upValue->v);
+
+ return upValue;
+}
+
+static void unboxUpValue(lua_State *luaState) {
+ // >>>>> ...... func
+ LClosure *lcl;
+ UpVal *uv;
+
+ lcl = (LClosure *)clvalue(getObject(luaState, -1));
+ uv = lcl->upvals[0];
+
+ lua_pop(luaState, 1);
+ // >>>>> ......
+
+ pushUpValue(luaState, uv);
+ // >>>>> ...... upValue
+}
+
+void unserializeFunction(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ byte numUpValues = info->readStream->readByte();
+
+ LClosure *lclosure = (LClosure *)newLClosure(info->luaState, numUpValues, hvalue(&info->luaState->l_gt));
+ pushClosure(info->luaState, (Closure *)lclosure);
+ // >>>>> permTbl indexTbl ...... func
+
+ // Put *some* proto in the closure, before the GC can find it
+ lclosure->p = makeFakeProto(info->luaState, numUpValues);
+
+ //Also, we need to temporarily fill the upvalues
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... func nil
+
+ for(byte i = 0; i < numUpValues; ++i) {
+ lclosure->upvals[i] = createUpValue(info->luaState, -1);
+ }
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ // I can't see offhand how a function would ever get to be self-
+ // referential, but just in case let's register it early
+ registerObjectInIndexTable(info, index);
+
+ // Now that it's safe, we can get the real proto
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... func proto
+
+ lclosure->p = gco2p(getObject(info->luaState, -1)->value.gc);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ for(byte i = 0; i < numUpValues; ++i) {
+ // >>>>> permTbl indexTbl ...... func
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... func func2
+
+ unboxUpValue(info->luaState);
+ // >>>>> permTbl indexTbl ...... func upValue
+ lclosure->upvals[i] = gco2uv(getObject(info->luaState, -1)->value.gc);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // Finally, the fenv
+ unserializeObject(info);
+
+ // >>>>> permTbl indexTbl ...... func ?fenv/nil?
+ if(!lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... func fenv
+ lua_setfenv(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... func
+ } else {
+ // >>>>> permTbl indexTbl ...... func nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // >>>>> permTbl indexTbl ...... func
+}
+
+static void correctStack(lua_State *L, TValue *oldstack) {
+ CallInfo *ci;
+ GCObject *up;
+ L->top = (L->top - oldstack) + L->stack;
+ for (up = L->openupval; up != NULL; up = up->gch.next)
+ gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
+ for (ci = L->base_ci; ci <= L->ci; ci++) {
+ ci->top = (ci->top - oldstack) + L->stack;
+ ci->base = (ci->base - oldstack) + L->stack;
+ ci->func = (ci->func - oldstack) + L->stack;
+ }
+ L->base = (L->base - oldstack) + L->stack;
+}
+
+void lua_reallocstack(lua_State *L, int newsize) {
+ TValue *oldstack = L->stack;
+ int realsize = newsize + 1 + EXTRA_STACK;
+
+ lua_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
+ L->stacksize = realsize;
+ L->stack_last = L->stack + newsize;
+ correctStack(L, oldstack);
+}
+
+void lua_growstack(lua_State *L, int n) {
+ // Double size is enough?
+ if (n <= L->stacksize) {
+ lua_reallocstack(L, 2 * L->stacksize);
+ } else {
+ lua_reallocstack(L, L->stacksize + n);
+ }
+}
+
+void lua_reallocCallInfo(lua_State *lauState, int newsize) {
+ CallInfo *oldci = lauState->base_ci;
+ lua_reallocvector(lauState, lauState->base_ci, lauState->size_ci, newsize, CallInfo);
+
+ lauState->size_ci = newsize;
+ lauState->ci = (lauState->ci - oldci) + lauState->base_ci;
+ lauState->end_ci = lauState->base_ci + lauState->size_ci - 1;
+}
+
+void unboxUpVal(lua_State *luaState) {
+ // >>>>> ... func
+ LClosure *lcl;
+ UpVal *uv;
+
+ lcl = (LClosure *)(&getObject(luaState, -1)->value.gc->cl);
+ uv = lcl->upvals[0];
+ lua_pop(luaState, 1);
+ // >>>>> ...
+ pushUpValue(luaState, uv);
+ // >>>>> ... upVal
+}
+
+/* Does basically the opposite of luaC_link().
+ * Right now this function is rather inefficient; it requires traversing the
+ * entire root GC set in order to find one object. If the GC list were doubly
+ * linked this would be much easier, but there's no reason for Lua to have
+ * that. */
+static void GCUnlink(lua_State *luaState, GCObject *gco) {
+ GCObject *prevslot;
+ if(G(luaState)->rootgc == gco) {
+ G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
+ return;
+ }
+
+ prevslot = G(luaState)->rootgc;
+ while(prevslot->gch.next != gco) {
+ prevslot = prevslot->gch.next;
+ }
+
+ prevslot->gch.next = prevslot->gch.next->gch.next;
+}
+
+void unserializeThread(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ lua_State *L2;
+ uint32 stacklimit = 0;
+
+ L2 = lua_newthread(info->luaState);
+ lua_checkstack(info->luaState, 3);
+
+ // L1: permTbl indexTbl ...... thread
+ // L2: (empty)
+ registerObjectInIndexTable(info, index);
+
+ // First, deserialize the object stack
+ uint32 stackSize = info->readStream->readUint32LE();
+ lua_growstack(info->luaState, (int)stackSize);
+
+ // Make sure that the first stack element (a nil, representing
+ // the imaginary top-level C function) is written to the very,
+ // very bottom of the stack
+ L2->top--;
+ for(uint32 i = 0; i < stackSize; ++i) {
+ unserializeObject(info);
+ // L1: permTbl indexTbl ...... thread obj*
+ }
+
+ lua_xmove(info->luaState, L2, stackSize);
+ // L1: permTbl indexTbl ...... thread
+ // L2: obj*
+
+ // Hereafter, stacks refer to L1
+
+
+ // Now, deserialize the CallInfo stack
+
+ uint32 numFrames = info->readStream->readUint32LE();
+
+ lua_reallocCallInfo(L2, numFrames*2);
+ for(uint32 i = 0; i < numFrames; ++i) {
+ CallInfo *ci = L2->base_ci + i;
+ uint32 stackbase = info->readStream->readUint32LE();
+ uint32 stackfunc = info->readStream->readUint32LE();
+ uint32 stacktop = info->readStream->readUint32LE();
+
+ ci->nresults = info->readStream->readSint32LE();
+
+ uint32 savedpc = info->readStream->readUint32LE();
+
+ if (stacklimit < stacktop) {
+ stacklimit = stacktop;
+ }
+
+ ci->base = L2->stack + stackbase;
+ ci->func = L2->stack + stackfunc;
+ ci->top = L2->stack + stacktop;
+ ci->savedpc = (ci != L2->base_ci) ? ci_func(ci)->l.p->code + savedpc : 0;
+ ci->tailcalls = 0;
+
+ // Update the pointer each time, to keep the GC happy
+ L2->ci = ci;
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+ // Deserialize the state's other parameters, with the exception of upval stuff
+
+ L2->savedpc = L2->ci->savedpc;
+ L2->status = info->readStream->readByte();
+ uint32 stackbase = info->readStream->readUint32LE();
+ uint32 stacktop = info->readStream->readUint32LE();
+
+
+ L2->errfunc = info->readStream->readUint32LE();
+
+ L2->base = L2->stack + stackbase;
+ L2->top = L2->stack + stacktop;
+
+ // Finally, "reopen" upvalues. See serializeUpVal() for why we do this
+ UpVal* uv;
+ GCObject **nextslot = &L2->openupval;
+ global_State *g = G(L2);
+
+ while (true) {
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... thread upVal/nil
+
+ // The list is terminated by a nil
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... thread nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+ break;
+ }
+
+ // >>>>> permTbl indexTbl ...... thread boxedUpVal
+ unboxUpVal(info->luaState);
+ // >>>>> permTbl indexTbl ...... thread boxedUpVal
+
+ uv = &(getObject(info->luaState, -1)->value.gc->uv);
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+
+ uint32 stackpos = info->readStream->readUint32LE();
+ uv->v = L2->stack + stackpos;
+
+ GCUnlink(info->luaState, (GCObject *)uv);
+
+ uv->marked = luaC_white(g);
+ *nextslot = (GCObject *)uv;
+ nextslot = &uv->next;
+ uv->u.l.prev = &G(L2)->uvhead;
+ uv->u.l.next = G(L2)->uvhead.u.l.next;
+ uv->u.l.next->u.l.prev = uv;
+ G(L2)->uvhead.u.l.next = uv;
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ }
+ *nextslot = NULL;
+
+ // The stack must be valid at least to the highest value among the CallInfos
+ // 'top' and the values up to there must be filled with 'nil'
+ lua_checkstack(L2, (int)stacklimit);
+ for (StkId o = L2->top; o <= L2->top + stacklimit; ++o) {
+ setnilvalue(o);
+ }
+}
+
+TString *lua_newlstr(lua_State *luaState, const char *str, size_t len) {
+ lua_pushlstring(luaState, str, len);
+ TString *luaStr = &(luaState->top - 1)->value.gc->ts;
+
+ lua_pop(luaState, 1);
+
+ return luaStr;
+}
+
+void lua_link(lua_State *luaState, GCObject *o, lu_byte tt) {
+ global_State *g = G(luaState);
+ o->gch.next = g->rootgc;
+ g->rootgc = o;
+ o->gch.marked = luaC_white(g);
+ o->gch.tt = tt;
+}
+
+Proto *lua_newproto(lua_State *luaState) {
+ Proto *f = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_link(luaState, obj2gco(f), LUA_TPROTO);
+ f->k = NULL;
+ f->sizek = 0;
+ f->p = NULL;
+ f->sizep = 0;
+ f->code = NULL;
+ f->sizecode = 0;
+ f->sizelineinfo = 0;
+ f->sizeupvalues = 0;
+ f->nups = 0;
+ f->upvalues = NULL;
+ f->numparams = 0;
+ f->is_vararg = 0;
+ f->maxstacksize = 0;
+ f->lineinfo = NULL;
+ f->sizelocvars = 0;
+ f->locvars = NULL;
+ f->linedefined = 0;
+ f->lastlinedefined = 0;
+ f->source = NULL;
+ return f;
+}
+
+void unserializeProto(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // We have to be careful. The GC expects a lot out of protos. In particular, we need
+ // to give the function a valid string for its source, and valid code, even before we
+ // actually read in the real code.
+ TString *source = lua_newlstr(info->luaState, "", 0);
+ Proto *p = lua_newproto(info->luaState);
+ p->source = source;
+ p->sizecode=1;
+ p->code = (Instruction *)lua_reallocv(info->luaState, NULL, 0, 1, sizeof(Instruction));
+ p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ p->maxstacksize = 2;
+ p->sizek = 0;
+ p->sizep = 0;
+
+ lua_checkstack(info->luaState, 2);
+
+ pushProto(info->luaState, p);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // We don't need to register early, since protos can never ever be
+ // involved in cyclic references
+
+ // Read in constant references
+ int sizek = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
+ for(int i = 0; i < sizek; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... proto k
+
+ setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
+ p->sizek++;
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in sub-proto references
+
+ int sizep = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
+ for(int i = 0; i < sizep; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... proto subproto
+
+ p->p[i] = (Proto *)getObject(info->luaState, -1)->value.gc;
+ p->sizep++;
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+
+ // Read in code
+ p->sizecode = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->code, 1, p->sizecode, Instruction);
+ info->readStream->read(p->code, sizeof(Instruction) * p->sizecode);
+
+
+ /* Read in upvalue names */
+ p->sizeupvalues = info->readStream->readSint32LE();
+ if (p->sizeupvalues) {
+ lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
+ for(int i = 0; i < p->sizeupvalues; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ p->upvalues[i] = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in local variable infos
+ p->sizelocvars = info->readStream->readSint32LE();
+ if (p->sizelocvars) {
+ lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
+ for(int i = 0; i < p->sizelocvars; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ p->locvars[i].varname = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ p->locvars[i].startpc = info->readStream->readSint32LE();
+ p->locvars[i].endpc = info->readStream->readSint32LE();
+ }
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in source string
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... proto sourceStr
+
+ p->source = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in line numbers
+ p->sizelineinfo = info->readStream->readSint32LE();
+ if (p->sizelineinfo) {
+ lua_reallocvector(info->luaState, p->lineinfo, 0, p->sizelineinfo, int);
+ info->readStream->read(p->lineinfo, sizeof(int) * p->sizelineinfo);
+ }
+
+
+ /* Read in linedefined and lastlinedefined */
+ p->linedefined = info->readStream->readSint32LE();
+ p->lastlinedefined = info->readStream->readSint32LE();
+
+ // Read in misc values
+ p->nups = info->readStream->readByte();
+ p->numparams = info->readStream->readByte();
+ p->is_vararg = info->readStream->readByte();
+ p->maxstacksize = info->readStream->readByte();
+}
+
+Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable) {
+ Closure *c = (Closure *)lua_malloc(luaState, sizeLclosure(numElements));
+ lua_link(luaState, obj2gco(c), LUA_TFUNCTION);
+ c->l.isC = 0;
+ c->l.env = elementTable;
+ c->l.nupvalues = cast_byte(numElements);
+
+ while (numElements--) {
+ c->l.upvals[numElements] = NULL;
+ }
+
+ return c;
+}
+
+static UpVal *makeUpVal(lua_State *luaState, int stackPos) {
+ UpVal *uv = lua_new(luaState, UpVal);
+ lua_link(luaState, (GCObject *)uv, LUA_TUPVAL);
+ uv->tt = LUA_TUPVAL;
+ uv->v = &uv->u.value;
+ uv->u.l.prev = NULL;
+ uv->u.l.next = NULL;
+
+ setobj(luaState, uv->v, getObject(luaState, stackPos));
+
+ return uv;
+}
+
+/**
+ * The GC is not fond of finding upvalues in tables. We get around this
+ * during persistence using a weakly keyed table, so that the GC doesn't
+ * bother to mark them. This won't work in unpersisting, however, since
+ * if we make the values weak they'll be collected (since nothing else
+ * references them). Our solution, during unpersisting, is to represent
+ * upvalues as dummy functions, each with one upvalue.
+ */
+static void boxupval_start(lua_State *luaState) {
+ LClosure *closure;
+ closure = (LClosure *)lua_newLclosure(luaState, 1, hvalue(&luaState->l_gt));
+ pushClosure(luaState, (Closure *)closure);
+ // >>>>> ...... func
+ closure->p = makeFakeProto(luaState, 1);
+
+ // Temporarily initialize the upvalue to nil
+ lua_pushnil(luaState);
+ closure->upvals[0] = makeUpVal(luaState, -1);
+ lua_pop(luaState, 1);
+}
+
+static void boxupval_finish(lua_State *luaState) {
+ // >>>>> ...... func obj
+ LClosure *lcl = (LClosure *)clvalue(getObject(luaState, -2));
+
+ lcl->upvals[0]->u.value = *getObject(luaState, -1);
+ lua_pop(luaState, 1);
+ // >>>>> ...... func
+}
+
+void unserializeUpValue(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+ lua_checkstack(upi->L, 2);
+
+ boxupval_start(upi->L);
+ // >>>>> permTbl indexTbl ...... func
+ registerObjectInIndexTable(info, index);
+
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... func obj
+
+ boxupval_finish(upi->L);
+ // >>>>> permTbl indexTbl ...... func
+}
+
+void unserializeUserData(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ int isspecial = info->readStream->readSint32LE();
+ if(isspecial) {
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... specialFunc
+
+ lua_call(info->luaState, 0, 1);
+ // >>>>> permTbl indexTbl ...... udata
+ } else {
+ uint32 length = info->readStream->readUint32LE();
+ lua_newuserdata(info->luaState, length);
+ // >>>>> permTbl indexTbl ...... udata
+ registerObjectInIndexTable(info, index);
+
+ info->readStream->read(lua_touserdata(upi->L, -1), length);
+
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... udata metaTable/nil
+
+ lua_setmetatable(upi->L, -2);
+ // >>>>> permTbl indexTbl ...... udata
+ }
+ // >>>>> permTbl indexTbl ...... udata
+}
+
+void unserializePermanent(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ unserializeObject(info);
+ // >>>>> permTbl indexTbl ...... permKey
+
+ lua_gettable(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... perm
+}
+
+} // End of namespace Lua
--
cgit v1.2.3
From 2c7a87a4e3181f228c43b92ffb15ae47401f64a7 Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Fri, 19 Dec 2014 14:51:00 -0600
Subject: SWORD25: Fix code formatting
... with AStyle
---
engines/sword25/util/lua_serialization_util.cpp | 10 +-
engines/sword25/util/lua_serializer.cpp | 62 ++++++------
engines/sword25/util/lua_unserializer.cpp | 127 ++++++++++++------------
3 files changed, 100 insertions(+), 99 deletions(-)
diff --git a/engines/sword25/util/lua_serialization_util.cpp b/engines/sword25/util/lua_serialization_util.cpp
index 80009aff60..80c5f86b20 100644
--- a/engines/sword25/util/lua_serialization_util.cpp
+++ b/engines/sword25/util/lua_serialization_util.cpp
@@ -65,12 +65,12 @@ void pushString(lua_State *luaState, TString *str) {
/* A simple reimplementation of the unfortunately static function luaA_index.
* Does not support the global table, registry, or upvalues. */
StkId getObject(lua_State *luaState, int stackpos) {
- if(stackpos > 0) {
- lua_assert(luaState->base+stackpos-1 < luaState->top);
- return luaState->base+stackpos-1;
+ if (stackpos > 0) {
+ lua_assert(luaState->base + stackpos - 1 < luaState->top);
+ return luaState->base + stackpos - 1;
} else {
- lua_assert(L->top-stackpos >= L->base);
- return luaState->top+stackpos;
+ lua_assert(L->top - stackpos >= L->base);
+ return luaState->top + stackpos;
}
}
diff --git a/engines/sword25/util/lua_serializer.cpp b/engines/sword25/util/lua_serializer.cpp
index 8c61383fba..c6c5f99342 100644
--- a/engines/sword25/util/lua_serializer.cpp
+++ b/engines/sword25/util/lua_serializer.cpp
@@ -81,7 +81,7 @@ void serializeLua(lua_State *luaState, Common::WriteStream *writeStream) {
// GC from visiting it and trying to mark things it doesn't want to
// mark in tables, e.g. upvalues. All objects in the table are
// a priori reachable, so it doesn't matter that we do this.
-
+
// Create the metatable
lua_newtable(luaState);
// >>>>> permTbl rootObj indexTbl metaTbl
@@ -253,22 +253,22 @@ static void serializeBoolean(SerializationInfo *info) {
static void serializeNumber(SerializationInfo *info) {
lua_Number value = lua_tonumber(info->luaState, -1);
-
-#if 1
- Util::SerializedDouble serializedValue(Util::encodeDouble(value));
-
- info->writeStream->writeUint32LE(serializedValue.significandOne);
- info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
- info->writeStream->writeSint16LE(serializedValue.exponent);
-#else
- // NOTE: We need to store a double. Unfortunately, we have to accommodate endianness.
- // Also, I don't know if we can assume all compilers use IEEE double
- // Therefore, I have chosen to store the double as a string.
- Common::String buffer = Common::String::format("%f", value);
-
- info->writeStream->write(buffer.c_str(), buffer.size());
-#endif
-
+
+ #if 1
+ Util::SerializedDouble serializedValue(Util::encodeDouble(value));
+
+ info->writeStream->writeUint32LE(serializedValue.significandOne);
+ info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
+ info->writeStream->writeSint16LE(serializedValue.exponent);
+ #else
+ // NOTE: We need to store a double. Unfortunately, we have to accommodate endianness.
+ // Also, I don't know if we can assume all compilers use IEEE double
+ // Therefore, I have chosen to store the double as a string.
+ Common::String buffer = Common::String::format("%f", value);
+
+ info->writeStream->write(buffer.c_str(), buffer.size());
+ #endif
+
}
static void serializeString(SerializationInfo *info) {
@@ -277,7 +277,7 @@ static void serializeString(SerializationInfo *info) {
uint32 length = static_cast(lua_strlen(info->luaState, -1));
info->writeStream->writeUint32LE(length);
- const char* str = lua_tostring(info->luaState, -1);
+ const char *str = lua_tostring(info->luaState, -1);
info->writeStream->write(str, length);
}
@@ -350,7 +350,7 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
lua_pushstring(info->luaState, "__persist not nil, boolean, or function");
lua_error(info->luaState);
}
-
+
// >>>>> permTbl indexTbl ...... obj metaTbl __persist
lua_pushvalue(info->luaState, -3);
// >>>>> permTbl indexTbl ...... obj metaTbl __persist obj
@@ -369,7 +369,7 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
// Serialize the function
serializeObject(info);
-
+
lua_pop(info->luaState, 2);
// >>>>> permTbl indexTbl ...... obj
@@ -396,11 +396,11 @@ static void serializeTable(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... tbl metaTbl/nil */
serializeObject(info);
-
+
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl
-
+
lua_pushnil(info->luaState);
// >>>>> permTbl indexTbl ...... tbl nil
@@ -456,14 +456,14 @@ static void serializeFunction(SerializationInfo *info) {
// Serialize the prototype
pushProto(info->luaState, cl->l.p);
// >>>>> permTbl indexTbl ...... func proto */
-
+
serializeObject(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
-
+
// Serialize upvalue values (not the upvalue objects themselves)
- for (byte i=0; il.p->nups; i++) {
+ for (byte i = 0; i < cl->l.p->nups; i++) {
// >>>>> permTbl indexTbl ...... func
pushUpValue(info->luaState, cl->l.upvals[i]);
// >>>>> permTbl indexTbl ...... func upval
@@ -536,7 +536,7 @@ static void serializeThread(SerializationInfo *info) {
}
// >>>>> permTbl indexTbl ...... thread
-
+
// Now, serialize the CallInfo stack
// Again, we *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
@@ -550,7 +550,7 @@ static void serializeThread(SerializationInfo *info) {
uint32 stackBase = static_cast(ci->base - threadState->stack);
uint32 stackFunc = static_cast(ci->func - threadState->stack);
uint32 stackTop = static_cast(ci->top - threadState->stack);
-
+
info->writeStream->writeUint32LE(stackBase);
info->writeStream->writeUint32LE(stackFunc);
info->writeStream->writeUint32LE(stackTop);
@@ -560,7 +560,7 @@ static void serializeThread(SerializationInfo *info) {
uint32 savedpc = (ci != threadState->base_ci) ? static_cast(ci->savedpc - ci_func(ci)->l.p->code) : 0u;
info->writeStream->writeUint32LE(savedpc);
}
-
+
// Serialize the state's other parameters, with the exception of upval stuff
@@ -671,9 +671,9 @@ static void serializeProto(SerializationInfo *info) {
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
}
-
- // Serialize local variable infos
+
+ // Serialize local variable infos
info->writeStream->writeSint32LE(proto->sizelocvars);
for (int i = 0; i < proto->sizelocvars; ++i) {
@@ -748,7 +748,7 @@ static void serializeUpValue(SerializationInfo *info) {
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 1);
- // We can't permit the upValue to linger around on the stack, as Lua
+ // We can't permit the upValue to linger around on the stack, as Lua
// will bail if its GC finds it.
lua_pop(info->luaState, 1);
diff --git a/engines/sword25/util/lua_unserializer.cpp b/engines/sword25/util/lua_unserializer.cpp
index c561a3d99f..69cb764dd2 100644
--- a/engines/sword25/util/lua_unserializer.cpp
+++ b/engines/sword25/util/lua_unserializer.cpp
@@ -79,7 +79,7 @@ void unserializeLua(lua_State *luaState, Common::ReadStream *readStream) {
// Re-start garbage collection
lua_gc(luaState, LUA_GCRESTART, 0);
-
+
// Remove the indexTbl
lua_replace(luaState, 2);
// >>>>> permTbl rootObj
@@ -106,17 +106,17 @@ static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
}
static void unserializeObject(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
+ // >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 2);
byte isARealValue = info->readStream->readByte();
- if(isARealValue) {
+ if (isARealValue) {
int index = info->readStream->readSint32LE();
int type = info->readStream->readSint32LE();
- switch(type) {
+ switch (type) {
case LUA_TBOOLEAN:
unserializeBoolean(info);
break;
@@ -156,9 +156,9 @@ static void unserializeObject(UnSerializationInfo *info) {
assert(0);
}
-
+
// >>>>> permTbl indexTbl ...... obj
- assert(lua_type(info->luaState, -1) == type ||
+ assert(lua_type(info->luaState, -1) == type ||
type == PERMANENT_TYPE ||
// Remember, upvalues get a special dispensation, as described in boxUpValue
(lua_type(info->luaState, -1) == LUA_TFUNCTION && type == LUA_TUPVAL));
@@ -168,7 +168,7 @@ static void unserializeObject(UnSerializationInfo *info) {
} else {
int index = info->readStream->readSint32LE();
- if(index == 0) {
+ if (index == 0) {
lua_pushnil(info->luaState);
// >>>>> permTbl indexTbl ...... nil
} else {
@@ -184,7 +184,7 @@ static void unserializeObject(UnSerializationInfo *info) {
}
// >>>>> permTbl indexTbl ...... obj/nil
}
-
+
// >>>>> permTbl indexTbl ...... obj/nil
}
@@ -201,8 +201,8 @@ static void unserializeBoolean(UnSerializationInfo *info) {
}
static void unserializeNumber(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
+ // >>>>> permTbl indexTbl ......
+
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 1);
@@ -220,7 +220,7 @@ static void unserializeNumber(UnSerializationInfo *info) {
static void unserializeString(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ......
-
+
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 1);
@@ -231,7 +231,7 @@ static void unserializeString(UnSerializationInfo *info) {
lua_pushlstring(info->luaState, string, length);
// >>>>> permTbl indexTbl ...... string
-
+
delete[] string;
}
@@ -264,7 +264,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
// Unserialize metatable
unserializeObject(info);
// >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
-
+
if (lua_istable(info->luaState, -1)) {
// >>>>> permTbl indexTbl ...... tbl metaTbl
lua_setmetatable(info->luaState, -2);
@@ -343,7 +343,7 @@ void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
obj->gch.tt = type;
}
-#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
+#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
Closure *newLClosure(lua_State *luaState, byte numUpValues, Table *env) {
Closure *newClosure = (Closure *)lua_malloc(luaState, sizeLclosure(numUpValues));
@@ -355,7 +355,7 @@ Closure *newLClosure(lua_State *luaState, byte numUpValues, Table *env) {
newClosure->l.nupvalues = numUpValues;
while (numUpValues--) {
- newClosure->l.upvals[numUpValues] = NULL;
+ newClosure->l.upvals[numUpValues] = NULL;
}
return newClosure;
@@ -431,7 +431,8 @@ static UpVal *createUpValue(lua_State *luaState, int stackpos) {
upValue->u.l.next = NULL;
const TValue *o2 = (TValue *)getObject(luaState, stackpos);
- upValue->v->value = o2->value; upValue->v->tt = o2->tt;
+ upValue->v->value = o2->value;
+ upValue->v->tt = o2->tt;
checkliveness(G(L), upValue->v);
return upValue;
@@ -471,7 +472,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
lua_pushnil(info->luaState);
// >>>>> permTbl indexTbl ...... func nil
- for(byte i = 0; i < numUpValues; ++i) {
+ for (byte i = 0; i < numUpValues; ++i) {
lclosure->upvals[i] = createUpValue(info->luaState, -1);
}
@@ -491,7 +492,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
- for(byte i = 0; i < numUpValues; ++i) {
+ for (byte i = 0; i < numUpValues; ++i) {
// >>>>> permTbl indexTbl ...... func
unserializeObject(info);
// >>>>> permTbl indexTbl ...... func func2
@@ -508,7 +509,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
unserializeObject(info);
// >>>>> permTbl indexTbl ...... func ?fenv/nil?
- if(!lua_isnil(info->luaState, -1)) {
+ if (!lua_isnil(info->luaState, -1)) {
// >>>>> permTbl indexTbl ...... func fenv
lua_setfenv(info->luaState, -2);
// >>>>> permTbl indexTbl ...... func
@@ -517,7 +518,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
}
-
+
// >>>>> permTbl indexTbl ...... func
}
@@ -547,7 +548,7 @@ void lua_reallocstack(lua_State *L, int newsize) {
void lua_growstack(lua_State *L, int n) {
// Double size is enough?
- if (n <= L->stacksize) {
+ if (n <= L->stacksize) {
lua_reallocstack(L, 2 * L->stacksize);
} else {
lua_reallocstack(L, L->stacksize + n);
@@ -583,13 +584,13 @@ void unboxUpVal(lua_State *luaState) {
* that. */
static void GCUnlink(lua_State *luaState, GCObject *gco) {
GCObject *prevslot;
- if(G(luaState)->rootgc == gco) {
+ if (G(luaState)->rootgc == gco) {
G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
return;
}
prevslot = G(luaState)->rootgc;
- while(prevslot->gch.next != gco) {
+ while (prevslot->gch.next != gco) {
prevslot = prevslot->gch.next;
}
@@ -604,7 +605,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
L2 = lua_newthread(info->luaState);
lua_checkstack(info->luaState, 3);
-
+
// L1: permTbl indexTbl ...... thread
// L2: (empty)
registerObjectInIndexTable(info, index);
@@ -612,14 +613,14 @@ void unserializeThread(UnSerializationInfo *info, int index) {
// First, deserialize the object stack
uint32 stackSize = info->readStream->readUint32LE();
lua_growstack(info->luaState, (int)stackSize);
-
+
// Make sure that the first stack element (a nil, representing
// the imaginary top-level C function) is written to the very,
// very bottom of the stack
L2->top--;
- for(uint32 i = 0; i < stackSize; ++i) {
+ for (uint32 i = 0; i < stackSize; ++i) {
unserializeObject(info);
- // L1: permTbl indexTbl ...... thread obj*
+ // L1: permTbl indexTbl ...... thread obj*
}
lua_xmove(info->luaState, L2, stackSize);
@@ -628,18 +629,18 @@ void unserializeThread(UnSerializationInfo *info, int index) {
// Hereafter, stacks refer to L1
-
+
// Now, deserialize the CallInfo stack
uint32 numFrames = info->readStream->readUint32LE();
- lua_reallocCallInfo(L2, numFrames*2);
- for(uint32 i = 0; i < numFrames; ++i) {
+ lua_reallocCallInfo(L2, numFrames * 2);
+ for (uint32 i = 0; i < numFrames; ++i) {
CallInfo *ci = L2->base_ci + i;
uint32 stackbase = info->readStream->readUint32LE();
uint32 stackfunc = info->readStream->readUint32LE();
uint32 stacktop = info->readStream->readUint32LE();
-
+
ci->nresults = info->readStream->readSint32LE();
uint32 savedpc = info->readStream->readUint32LE();
@@ -653,7 +654,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
ci->top = L2->stack + stacktop;
ci->savedpc = (ci != L2->base_ci) ? ci_func(ci)->l.p->code + savedpc : 0;
ci->tailcalls = 0;
-
+
// Update the pointer each time, to keep the GC happy
L2->ci = ci;
}
@@ -668,12 +669,12 @@ void unserializeThread(UnSerializationInfo *info, int index) {
L2->errfunc = info->readStream->readUint32LE();
-
+
L2->base = L2->stack + stackbase;
L2->top = L2->stack + stacktop;
- // Finally, "reopen" upvalues. See serializeUpVal() for why we do this
- UpVal* uv;
+ // Finally, "reopen" upvalues. See serializeUpVal() for why we do this
+ UpVal *uv;
GCObject **nextslot = &L2->openupval;
global_State *g = G(L2);
@@ -688,7 +689,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... thread
break;
}
-
+
// >>>>> permTbl indexTbl ...... thread boxedUpVal
unboxUpVal(info->luaState);
// >>>>> permTbl indexTbl ...... thread boxedUpVal
@@ -765,15 +766,15 @@ Proto *lua_newproto(lua_State *luaState) {
void unserializeProto(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
-
- // We have to be careful. The GC expects a lot out of protos. In particular, we need
- // to give the function a valid string for its source, and valid code, even before we
- // actually read in the real code.
+
+ // We have to be careful. The GC expects a lot out of protos. In particular, we need
+ // to give the function a valid string for its source, and valid code, even before we
+ // actually read in the real code.
TString *source = lua_newlstr(info->luaState, "", 0);
Proto *p = lua_newproto(info->luaState);
p->source = source;
- p->sizecode=1;
- p->code = (Instruction *)lua_reallocv(info->luaState, NULL, 0, 1, sizeof(Instruction));
+ p->sizecode = 1;
+ p->code = (Instruction *)lua_reallocv(info->luaState, NULL, 0, 1, sizeof(Instruction));
p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
p->maxstacksize = 2;
p->sizek = 0;
@@ -782,18 +783,18 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_checkstack(info->luaState, 2);
pushProto(info->luaState, p);
- // >>>>> permTbl indexTbl ...... proto
+ // >>>>> permTbl indexTbl ...... proto
// We don't need to register early, since protos can never ever be
- // involved in cyclic references
+ // involved in cyclic references
// Read in constant references
int sizek = info->readStream->readSint32LE();
lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
- for(int i = 0; i < sizek; ++i) {
- // >>>>> permTbl indexTbl ...... proto
+ for (int i = 0; i < sizek; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
unserializeObject(info);
- // >>>>> permTbl indexTbl ...... proto k
+ // >>>>> permTbl indexTbl ...... proto k
setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
p->sizek++;
@@ -807,8 +808,8 @@ void unserializeProto(UnSerializationInfo *info, int index) {
int sizep = info->readStream->readSint32LE();
lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
- for(int i = 0; i < sizep; ++i) {
- // >>>>> permTbl indexTbl ...... proto
+ for (int i = 0; i < sizep; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
unserializeObject(info);
// >>>>> permTbl indexTbl ...... proto subproto
@@ -816,22 +817,22 @@ void unserializeProto(UnSerializationInfo *info, int index) {
p->sizep++;
lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
+ // >>>>> permTbl indexTbl ...... proto
}
- // >>>>> permTbl indexTbl ...... proto
+ // >>>>> permTbl indexTbl ...... proto
// Read in code
p->sizecode = info->readStream->readSint32LE();
lua_reallocvector(info->luaState, p->code, 1, p->sizecode, Instruction);
info->readStream->read(p->code, sizeof(Instruction) * p->sizecode);
-
+
/* Read in upvalue names */
p->sizeupvalues = info->readStream->readSint32LE();
if (p->sizeupvalues) {
lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
- for(int i = 0; i < p->sizeupvalues; ++i) {
+ for (int i = 0; i < p->sizeupvalues; ++i) {
// >>>>> permTbl indexTbl ...... proto
unserializeObject(info);
// >>>>> permTbl indexTbl ...... proto str
@@ -847,7 +848,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
p->sizelocvars = info->readStream->readSint32LE();
if (p->sizelocvars) {
lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
- for(int i = 0; i < p->sizelocvars; ++i) {
+ for (int i = 0; i < p->sizelocvars; ++i) {
// >>>>> permTbl indexTbl ...... proto
unserializeObject(info);
// >>>>> permTbl indexTbl ...... proto str
@@ -876,7 +877,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->lineinfo, 0, p->sizelineinfo, int);
info->readStream->read(p->lineinfo, sizeof(int) * p->sizelineinfo);
}
-
+
/* Read in linedefined and lastlinedefined */
p->linedefined = info->readStream->readSint32LE();
@@ -895,7 +896,7 @@ Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTab
c->l.isC = 0;
c->l.env = elementTable;
c->l.nupvalues = cast_byte(numElements);
-
+
while (numElements--) {
c->l.upvals[numElements] = NULL;
}
@@ -916,13 +917,13 @@ static UpVal *makeUpVal(lua_State *luaState, int stackPos) {
return uv;
}
-/**
+/**
* The GC is not fond of finding upvalues in tables. We get around this
* during persistence using a weakly keyed table, so that the GC doesn't
* bother to mark them. This won't work in unpersisting, however, since
* if we make the values weak they'll be collected (since nothing else
* references them). Our solution, during unpersisting, is to represent
- * upvalues as dummy functions, each with one upvalue.
+ * upvalues as dummy functions, each with one upvalue.
*/
static void boxupval_start(lua_State *luaState) {
LClosure *closure;
@@ -931,7 +932,7 @@ static void boxupval_start(lua_State *luaState) {
// >>>>> ...... func
closure->p = makeFakeProto(luaState, 1);
- // Temporarily initialize the upvalue to nil
+ // Temporarily initialize the upvalue to nil
lua_pushnil(luaState);
closure->upvals[0] = makeUpVal(luaState, -1);
lua_pop(luaState, 1);
@@ -947,7 +948,7 @@ static void boxupval_finish(lua_State *luaState) {
}
void unserializeUpValue(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
+ // >>>>> permTbl indexTbl ......
lua_checkstack(upi->L, 2);
boxupval_start(upi->L);
@@ -966,9 +967,9 @@ void unserializeUserData(UnSerializationInfo *info, int index) {
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 2);
-
+
int isspecial = info->readStream->readSint32LE();
- if(isspecial) {
+ if (isspecial) {
unserializeObject(info);
// >>>>> permTbl indexTbl ...... specialFunc
@@ -996,7 +997,7 @@ void unserializePermanent(UnSerializationInfo *info, int index) {
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 2);
-
+
unserializeObject(info);
// >>>>> permTbl indexTbl ...... permKey
--
cgit v1.2.3
From b41b3e1a89d7646561697b1bc3636345230a9f12 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 20 Dec 2014 13:26:32 +0200
Subject: ZVISION: Fix code formatting
---
engines/zvision/file/search_manager.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/file/search_manager.cpp b/engines/zvision/file/search_manager.cpp
index 30c269c290..d0d4e43d12 100644
--- a/engines/zvision/file/search_manager.cpp
+++ b/engines/zvision/file/search_manager.cpp
@@ -265,7 +265,7 @@ void SearchManager::addDir(const Common::String &name) {
void SearchManager::listDirRecursive(Common::List &_list, const Common::FSNode &fsNode, int depth) {
Common::FSList fsList;
- if ( fsNode.getChildren(fsList) ) {
+ if (fsNode.getChildren(fsList)) {
_list.push_back(fsNode.getPath());
--
cgit v1.2.3
From 0f590561bd0fe7238fcfd5fcee0d8a4dc11b9979 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 20 Dec 2014 13:27:16 +0200
Subject: ZVISION: Simplify check
Thanks to DrMcCoy for spotting this
---
engines/zvision/sound/zork_raw.cpp | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
index 8688039325..b2c88b34df 100644
--- a/engines/zvision/sound/zork_raw.cpp
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -73,10 +73,7 @@ RawChunkStream::RawChunk RawChunkStream::readNextChunk(Common::SeekableReadStrea
tmp.size = 0;
tmp.data = NULL;
- if (!stream)
- return tmp;
-
- if (stream && (stream->size() == 0 || stream->eos()))
+ if (!stream || stream->size() == 0 || stream->eos())
return tmp;
tmp.size = (stream->size() - stream->pos()) * 2;
--
cgit v1.2.3
From 200b05246c3e90e61fe6d2e21507b0b936d0ff2b Mon Sep 17 00:00:00 2001
From: Bastien Bouclet
Date: Sun, 14 Sep 2014 15:07:50 +0200
Subject: AUDIO: Wrap around in the Timestamp constructor
The "making of" video in the Xbox version of Myst III is
unusually long. VideoDecoder::FixedRateVideoTrack::getFrameTime
would trigger an overflow.
---
audio/timestamp.cpp | 6 ++----
test/audio/timestamp.h | 13 +++++++++++++
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/audio/timestamp.cpp b/audio/timestamp.cpp
index 1ce971631c..63752812e1 100644
--- a/audio/timestamp.cpp
+++ b/audio/timestamp.cpp
@@ -39,12 +39,10 @@ Timestamp::Timestamp(uint ms, uint fr) {
Timestamp::Timestamp(uint s, uint frames, uint fr) {
assert(fr > 0);
- _secs = s;
+ _secs = s + (frames / fr);
_framerateFactor = 1000 / Common::gcd(1000, fr);
_framerate = fr * _framerateFactor;
- _numFrames = frames * _framerateFactor;
-
- normalize();
+ _numFrames = (frames % fr) * _framerateFactor;
}
Timestamp Timestamp::convertToFramerate(uint newFramerate) const {
diff --git a/test/audio/timestamp.h b/test/audio/timestamp.h
index ca56e34a4d..ec42a55ec4 100644
--- a/test/audio/timestamp.h
+++ b/test/audio/timestamp.h
@@ -2,6 +2,8 @@
#include "audio/timestamp.h"
+#include
+
class TimestampTestSuite : public CxxTest::TestSuite
{
public:
@@ -238,4 +240,15 @@ class TimestampTestSuite : public CxxTest::TestSuite
TS_ASSERT_EQUALS(c.numberOfFrames(), 11025);
TS_ASSERT_EQUALS(c.totalNumberOfFrames(), 33075);
}
+
+ void test_no_overflow() {
+ // The constructor should not overflow and give incoherent values
+ const Audio::Timestamp a = Audio::Timestamp(0, UINT_MAX, 1000);
+
+ int secs = UINT_MAX / 1000;
+ int frames = UINT_MAX % 1000;
+
+ TS_ASSERT_EQUALS(a.secs(), secs);
+ TS_ASSERT_EQUALS(a.numberOfFrames(), frames);
+ }
};
--
cgit v1.2.3
From d497b45b1c8e13a67946522927dcbbcbc795af9a Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Sun, 21 Dec 2014 03:58:19 -0600
Subject: COMMON: Fix typo that caused uint64 reads to return a uint32
---
common/stream.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/common/stream.h b/common/stream.h
index 5655f0fcb4..251995001c 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -266,7 +266,7 @@ public:
* if a read error occurred (for which client code can check by
* calling err() and eos() ).
*/
- uint32 readUint64LE() {
+ uint64 readUint64LE() {
uint64 val;
read(&val, 8);
return FROM_LE_64(val);
@@ -305,7 +305,7 @@ public:
* if a read error occurred (for which client code can check by
* calling err() and eos() ).
*/
- uint32 readUint64BE() {
+ uint64 readUint64BE() {
uint64 val;
read(&val, 8);
return FROM_BE_64(val);
--
cgit v1.2.3
From 93167fabb55741a9606efa0088cf348c8ff2019e Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Sun, 21 Dec 2014 04:12:43 -0600
Subject: TEST: Create test cases for reading uint64 from a stream
---
test/common/memoryreadstream.h | 16 ++++++++++------
test/common/memoryreadstreamendian.h | 32 ++++++++++++++++++++------------
2 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/test/common/memoryreadstream.h b/test/common/memoryreadstream.h
index adef861a5e..79c4079e9b 100644
--- a/test/common/memoryreadstream.h
+++ b/test/common/memoryreadstream.h
@@ -60,28 +60,32 @@ class MemoryReadStreamTestSuite : public CxxTest::TestSuite {
}
void test_seek_read_le() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStream ms(contents, sizeof(contents));
TS_ASSERT_EQUALS(ms.readUint16LE(), 0x0201UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32LE(), 0x06050403UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_be() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStream ms(contents, sizeof(contents));
TS_ASSERT_EQUALS(ms.readUint16BE(), 0x0102UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
diff --git a/test/common/memoryreadstreamendian.h b/test/common/memoryreadstreamendian.h
index 35e804c70b..515128ea2a 100644
--- a/test/common/memoryreadstreamendian.h
+++ b/test/common/memoryreadstreamendian.h
@@ -60,54 +60,62 @@ class MemoryReadStreamEndianTestSuite : public CxxTest::TestSuite {
}
void test_seek_read_le() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
TS_ASSERT_EQUALS(ms.readUint16LE(), 0x0201UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32LE(), 0x06050403UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_be() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
TS_ASSERT_EQUALS(ms.readUint16BE(), 0x0102UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_le2() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
TS_ASSERT_EQUALS(ms.readUint16(), 0x0201UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32(), 0x06050403UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_be2() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), true);
TS_ASSERT_EQUALS(ms.readUint16(), 0x0102UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
};
--
cgit v1.2.3
From 0433eda4dec8b6ac660aacec2ae3866461214ce3 Mon Sep 17 00:00:00 2001
From: Thierry Crozat
Date: Sun, 21 Dec 2014 18:25:57 +0000
Subject: CGE2: Add detection for new English freeware version
---
engines/cge2/detection.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 6e1b93d0b8..4acdea3fde 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -80,6 +80,16 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
},
+
+ {
+ "sfinx", "Freeware v1.1",
+ {
+ {"vol.cat", 0, "f158e469dccbebc5a632eb848df89779", 129024},
+ {"vol.dat", 0, "d40a6b4ae173d6930be54ba56bee15d5", 34182773},
+ AD_LISTEND
+ },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+ },
AD_TABLE_END_MARKER
};
--
cgit v1.2.3
From bb1df52da8be0322d5f04ddd371dc3c68eb3812a Mon Sep 17 00:00:00 2001
From: Thierry Crozat
Date: Sun, 21 Dec 2014 18:26:40 +0000
Subject: CREDITS: Add credits for Sfinx translation to English
---
AUTHORS | 6 ++++++
devtools/credits.pl | 6 ++++++
gui/credits.h | 12 ++++++++++++
3 files changed, 24 insertions(+)
diff --git a/AUTHORS b/AUTHORS
index 9470217230..8e90a625c9 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -524,6 +524,12 @@ Other contributions
Victor Gonzalez - Soltys Spanish translation
Alejandro Gomez de la Munoza - Soltys Spanish translation
+ CGE2:
+ Arnaud Boutonne - Sfinx English translation
+ Thierry Crozat - Sfinx English translation
+ Peter Bozso - Sfinx English translation editor
+ Ryan Clark - Sfinx English translation editor
+
Drascula:
Thierry Crozat - Improve French translation
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 1c2ece80ed..e919c0b8ba 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -1092,6 +1092,12 @@ begin_credits("Credits");
add_person("Víctor González", "IlDucci", "Soltys Spanish translation");
add_person("Alejandro Gómez de la Muñoza", "TheFireRed", "Soltys Spanish translation");
end_section();
+ begin_section("CGE2");
+ add_person("Arnaud Boutonné", "Strangerke", "Sfinx English translation");
+ add_person("Thierry Crozat", "criezy", "Sfinx English translation");
+ add_person("Peter Bozsó", "uruk", "Sfinx English translation editor");
+ add_person("Ryan Clark", "", "Sfinx English translation editor");
+ end_section();
begin_section("Drascula");
add_person("Thierry Crozat", "criezy", "Improve French translation");
end_section();
diff --git a/gui/credits.h b/gui/credits.h
index 5b33797a63..0610609983 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -630,6 +630,18 @@ static const char *credits[] = {
"C0""Alejandro G\363mez de la Mu\361oza",
"C2""Soltys Spanish translation",
"",
+"C1""CGE2",
+"A0""Arnaud Boutonne",
+"C0""Arnaud Boutonn\351",
+"C2""Sfinx English translation",
+"C0""Thierry Crozat",
+"C2""Sfinx English translation",
+"A0""Peter Bozso",
+"C0""Peter Bozs\363",
+"C2""Sfinx English translation editor",
+"C0""Ryan Clark",
+"C2""Sfinx English translation editor",
+"",
"C1""Drascula",
"C0""Thierry Crozat",
"C2""Improve French translation",
--
cgit v1.2.3
From e34b5be8e3d4842e273f08821b6a7bd7ba65e843 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sun, 21 Dec 2014 22:13:28 +0200
Subject: MT32: Update to munt 1.5.0
This syncs with munt commit 4041a16a5d
---
NEWS | 3 +
audio/softsynth/mt32/Analog.cpp | 348 ++++++++++++++++++++++++
audio/softsynth/mt32/Analog.h | 57 ++++
audio/softsynth/mt32/BReverbModel.cpp | 10 +-
audio/softsynth/mt32/BReverbModel.h | 2 +-
audio/softsynth/mt32/LA32FloatWaveGenerator.cpp | 2 +-
audio/softsynth/mt32/LA32Ramp.cpp | 2 +-
audio/softsynth/mt32/LA32WaveGenerator.cpp | 10 +-
audio/softsynth/mt32/MemoryRegion.h | 124 +++++++++
audio/softsynth/mt32/MidiEventQueue.h | 67 +++++
audio/softsynth/mt32/Part.cpp | 1 +
audio/softsynth/mt32/Partial.cpp | 5 +-
audio/softsynth/mt32/PartialManager.cpp | 1 +
audio/softsynth/mt32/Poly.cpp | 1 +
audio/softsynth/mt32/Poly.h | 1 +
audio/softsynth/mt32/ROMInfo.cpp | 15 +-
audio/softsynth/mt32/ROMInfo.h | 4 +-
audio/softsynth/mt32/Structures.h | 47 ++--
audio/softsynth/mt32/Synth.cpp | 248 +++++++++++------
audio/softsynth/mt32/Synth.h | 347 +++++++++--------------
audio/softsynth/mt32/TVA.cpp | 1 +
audio/softsynth/mt32/TVF.cpp | 1 +
audio/softsynth/mt32/TVP.cpp | 1 +
audio/softsynth/mt32/Tables.cpp | 5 +-
audio/softsynth/mt32/Tables.h | 15 +-
audio/softsynth/mt32/Types.h | 40 +++
audio/softsynth/mt32/internals.h | 83 ++++++
audio/softsynth/mt32/module.mk | 1 +
audio/softsynth/mt32/mt32emu.h | 67 +----
29 files changed, 1086 insertions(+), 423 deletions(-)
create mode 100644 audio/softsynth/mt32/Analog.cpp
create mode 100644 audio/softsynth/mt32/Analog.h
create mode 100644 audio/softsynth/mt32/MemoryRegion.h
create mode 100644 audio/softsynth/mt32/MidiEventQueue.h
create mode 100644 audio/softsynth/mt32/Types.h
create mode 100644 audio/softsynth/mt32/internals.h
diff --git a/NEWS b/NEWS
index 762af70962..470ddc01bd 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ For a more comprehensive changelog of the latest experimental code, see:
New Games:
- Added support for Sfinx.
+ General:
+ - Updated Munt MT-32 emulation code to version 1.5.0.
+
Broken Sword 1:
- Fix speech endianness detection on big endian systems for the mac
version (bug #6720).
diff --git a/audio/softsynth/mt32/Analog.cpp b/audio/softsynth/mt32/Analog.cpp
new file mode 100644
index 0000000000..8ac28e401a
--- /dev/null
+++ b/audio/softsynth/mt32/Analog.cpp
@@ -0,0 +1,348 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+//#include
+#include "Analog.h"
+
+namespace MT32Emu {
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+
+/* FIR approximation of the overall impulse response of the cascade composed of the sample & hold circuit and the low pass filter
+ * of the MT-32 first generation.
+ * The coefficients below are found by windowing the inverse DFT of the 1024 pin frequency response converted to the minimum phase.
+ * The frequency response of the LPF is computed directly, the effect of the S&H is approximated by multiplying the LPF frequency
+ * response by the corresponding sinc. Although, the LPF has DC gain of 3.2, we ignore this in the emulation and use normalised model.
+ * The peak gain of the normalised cascade appears about 1.7 near 11.8 kHz. Relative error doesn't exceed 1% for the frequencies
+ * below 12.5 kHz. In the higher frequency range, the relative error is below 8%. Peak error value is at 16 kHz.
+ */
+static const float COARSE_LPF_TAPS_MT32[] = {
+ 1.272473681f, -0.220267785f, -0.158039905f, 0.179603785f, -0.111484097f, 0.054137498f, -0.023518029f, 0.010997169f, -0.006935698f
+};
+
+// Similar approximation for new MT-32 and CM-32L/LAPC-I LPF. As the voltage controlled amplifier was introduced, LPF has unity DC gain.
+// The peak gain value shifted towards higher frequencies and a bit higher about 1.83 near 13 kHz.
+static const float COARSE_LPF_TAPS_CM32L[] = {
+ 1.340615635f, -0.403331694f, 0.036005517f, 0.066156844f, -0.069672532f, 0.049563806f, -0.031113416f, 0.019169774f, -0.012421368f
+};
+
+#else
+
+static const unsigned int COARSE_LPF_FRACTION_BITS = 14;
+
+// Integer versions of the FIRs above multiplied by (1 << 14) and rounded.
+static const SampleEx COARSE_LPF_TAPS_MT32[] = {
+ 20848, -3609, -2589, 2943, -1827, 887, -385, 180, -114
+};
+
+static const SampleEx COARSE_LPF_TAPS_CM32L[] = {
+ 21965, -6608, 590, 1084, -1142, 812, -510, 314, -204
+};
+
+#endif
+
+/* Combined FIR that both approximates the impulse response of the analogue circuits of sample & hold and the low pass filter
+ * in the audible frequency range (below 20 kHz) and attenuates unwanted mirror spectra above 28 kHz as well. It is a polyphase
+ * filter intended for resampling the signal to 48 kHz yet for applying high frequency boost.
+ * As with the filter above, the analogue LPF frequency response is obtained for 1536 pin grid for range up to 96 kHz and multiplied
+ * by the corresponding sinc. The result is further squared, windowed and passed to generalised Parks-McClellan routine as a desired response.
+ * Finally, the minimum phase factor is found that's essentially the coefficients below.
+ * Relative error in the audible frequency range doesn't exceed 0.0006%, attenuation in the stopband is better than 100 dB.
+ * This level of performance makes it nearly bit-accurate for standard 16-bit sample resolution.
+ */
+
+// FIR version for MT-32 first generation.
+static const float ACCURATE_LPF_TAPS_MT32[] = {
+ 0.003429281f, 0.025929869f, 0.096587777f, 0.228884848f, 0.372413431f, 0.412386503f, 0.263980018f,
+ -0.014504962f, -0.237394528f, -0.257043496f, -0.103436603f, 0.063996095f, 0.124562333f, 0.083703206f,
+ 0.013921662f, -0.033475018f, -0.046239712f, -0.029310921f, 0.00126585f, 0.021060961f, 0.017925605f,
+ 0.003559874f, -0.005105248f, -0.005647917f, -0.004157918f, -0.002065664f, 0.00158747f, 0.003762585f,
+ 0.001867137f, -0.001090028f, -0.001433979f, -0.00022367f, 4.34308E-05f, -0.000247827f, 0.000157087f,
+ 0.000605823f, 0.000197317f, -0.000370511f, -0.000261202f, 9.96069E-05f, 9.85073E-05f, -5.28754E-05f,
+ -1.00912E-05f, 7.69943E-05f, 2.03162E-05f, -5.67967E-05f, -3.30637E-05f, 1.61958E-05f, 1.73041E-05f
+};
+
+// FIR version for new MT-32 and CM-32L/LAPC-I.
+static const float ACCURATE_LPF_TAPS_CM32L[] = {
+ 0.003917452f, 0.030693861f, 0.116424199f, 0.275101674f, 0.43217361f, 0.431247894f, 0.183255659f,
+ -0.174955671f, -0.354240244f, -0.212401714f, 0.072259178f, 0.204655344f, 0.108336211f, -0.039099027f,
+ -0.075138174f, -0.026261906f, 0.00582663f, 0.003052193f, 0.00613657f, 0.017017951f, 0.008732535f,
+ -0.011027427f, -0.012933664f, 0.001158097f, 0.006765958f, 0.00046778f, -0.002191106f, 0.001561017f,
+ 0.001842871f, -0.001996876f, -0.002315836f, 0.000980965f, 0.001817454f, -0.000243272f, -0.000972848f,
+ 0.000149941f, 0.000498886f, -0.000204436f, -0.000347415f, 0.000142386f, 0.000249137f, -4.32946E-05f,
+ -0.000131231f, 3.88575E-07f, 4.48813E-05f, -1.31906E-06f, -1.03499E-05f, 7.71971E-06f, 2.86721E-06f
+};
+
+// According to the CM-64 PCB schematic, there is a difference in the values of the LPF entrance resistors for the reverb and non-reverb channels.
+// This effectively results in non-unity LPF DC gain for the reverb channel of 0.68 while the LPF has unity DC gain for the LA32 output channels.
+// In emulation, the reverb output gain is multiplied by this factor to compensate for the LPF gain difference.
+static const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f;
+
+static const unsigned int OUTPUT_GAIN_FRACTION_BITS = 8;
+static const float OUTPUT_GAIN_MULTIPLIER = float(1 << OUTPUT_GAIN_FRACTION_BITS);
+
+static const unsigned int COARSE_LPF_DELAY_LINE_LENGTH = 8; // Must be a power of 2
+static const unsigned int ACCURATE_LPF_DELAY_LINE_LENGTH = 16; // Must be a power of 2
+static const unsigned int ACCURATE_LPF_NUMBER_OF_PHASES = 3; // Upsampling factor
+static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_REGULAR = 2; // Downsampling factor
+static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED = 1; // No downsampling
+static const Bit32u ACCURATE_LPF_DELTAS_REGULAR[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 1, 0 }, { 1, 2, 1 } };
+static const Bit32u ACCURATE_LPF_DELTAS_OVERSAMPLED[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 } };
+
+class AbstractLowPassFilter {
+public:
+ static AbstractLowPassFilter &createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF);
+ static void muteRingBuffer(SampleEx *ringBuffer, unsigned int length);
+
+ virtual ~AbstractLowPassFilter() {}
+ virtual SampleEx process(SampleEx sample) = 0;
+ virtual bool hasNextSample() const;
+ virtual unsigned int getOutputSampleRate() const;
+ virtual unsigned int estimateInSampleCount(unsigned int outSamples) const;
+ virtual void addPositionIncrement(unsigned int) {}
+};
+
+class NullLowPassFilter : public AbstractLowPassFilter {
+public:
+ SampleEx process(SampleEx sample);
+};
+
+class CoarseLowPassFilter : public AbstractLowPassFilter {
+private:
+ const SampleEx * const LPF_TAPS;
+ SampleEx ringBuffer[COARSE_LPF_DELAY_LINE_LENGTH];
+ unsigned int ringBufferPosition;
+
+public:
+ CoarseLowPassFilter(bool oldMT32AnalogLPF);
+ SampleEx process(SampleEx sample);
+};
+
+class AccurateLowPassFilter : public AbstractLowPassFilter {
+private:
+ const float * const LPF_TAPS;
+ const Bit32u (* const deltas)[ACCURATE_LPF_NUMBER_OF_PHASES];
+ const unsigned int phaseIncrement;
+ const unsigned int outputSampleRate;
+
+ SampleEx ringBuffer[ACCURATE_LPF_DELAY_LINE_LENGTH];
+ unsigned int ringBufferPosition;
+ unsigned int phase;
+
+public:
+ AccurateLowPassFilter(bool oldMT32AnalogLPF, bool oversample);
+ SampleEx process(SampleEx sample);
+ bool hasNextSample() const;
+ unsigned int getOutputSampleRate() const;
+ unsigned int estimateInSampleCount(unsigned int outSamples) const;
+ void addPositionIncrement(unsigned int positionIncrement);
+};
+
+Analog::Analog(const AnalogOutputMode mode, const ControlROMFeatureSet *controlROMFeatures) :
+ leftChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, controlROMFeatures->isOldMT32AnalogLPF())),
+ rightChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, controlROMFeatures->isOldMT32AnalogLPF())),
+ synthGain(0),
+ reverbGain(0)
+{}
+
+Analog::~Analog() {
+ delete &leftChannelLPF;
+ delete &rightChannelLPF;
+}
+
+void Analog::process(Sample **outStream, const Sample *nonReverbLeft, const Sample *nonReverbRight, const Sample *reverbDryLeft, const Sample *reverbDryRight, const Sample *reverbWetLeft, const Sample *reverbWetRight, Bit32u outLength) {
+ if (outStream == NULL) {
+ leftChannelLPF.addPositionIncrement(outLength);
+ rightChannelLPF.addPositionIncrement(outLength);
+ return;
+ }
+
+ while (0 < (outLength--)) {
+ SampleEx outSampleL;
+ SampleEx outSampleR;
+
+ if (leftChannelLPF.hasNextSample()) {
+ outSampleL = leftChannelLPF.process(0);
+ outSampleR = rightChannelLPF.process(0);
+ } else {
+ SampleEx inSampleL = ((SampleEx)*(nonReverbLeft++) + (SampleEx)*(reverbDryLeft++)) * synthGain + (SampleEx)*(reverbWetLeft++) * reverbGain;
+ SampleEx inSampleR = ((SampleEx)*(nonReverbRight++) + (SampleEx)*(reverbDryRight++)) * synthGain + (SampleEx)*(reverbWetRight++) * reverbGain;
+
+#if !MT32EMU_USE_FLOAT_SAMPLES
+ inSampleL >>= OUTPUT_GAIN_FRACTION_BITS;
+ inSampleR >>= OUTPUT_GAIN_FRACTION_BITS;
+#endif
+
+ outSampleL = leftChannelLPF.process(inSampleL);
+ outSampleR = rightChannelLPF.process(inSampleR);
+ }
+
+ *((*outStream)++) = Synth::clipSampleEx(outSampleL);
+ *((*outStream)++) = Synth::clipSampleEx(outSampleR);
+ }
+}
+
+unsigned int Analog::getOutputSampleRate() const {
+ return leftChannelLPF.getOutputSampleRate();
+}
+
+Bit32u Analog::getDACStreamsLength(Bit32u outputLength) const {
+ return leftChannelLPF.estimateInSampleCount(outputLength);
+}
+
+void Analog::setSynthOutputGain(float useSynthGain) {
+#if MT32EMU_USE_FLOAT_SAMPLES
+ synthGain = useSynthGain;
+#else
+ if (OUTPUT_GAIN_MULTIPLIER < useSynthGain) useSynthGain = OUTPUT_GAIN_MULTIPLIER;
+ synthGain = SampleEx(useSynthGain * OUTPUT_GAIN_MULTIPLIER);
+#endif
+}
+
+void Analog::setReverbOutputGain(float useReverbGain, bool mt32ReverbCompatibilityMode) {
+ if (!mt32ReverbCompatibilityMode) useReverbGain *= CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ reverbGain = useReverbGain;
+#else
+ if (OUTPUT_GAIN_MULTIPLIER < useReverbGain) useReverbGain = OUTPUT_GAIN_MULTIPLIER;
+ reverbGain = SampleEx(useReverbGain * OUTPUT_GAIN_MULTIPLIER);
+#endif
+}
+
+AbstractLowPassFilter &AbstractLowPassFilter::createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF) {
+ switch (mode) {
+ case AnalogOutputMode_COARSE:
+ return *new CoarseLowPassFilter(oldMT32AnalogLPF);
+ case AnalogOutputMode_ACCURATE:
+ return *new AccurateLowPassFilter(oldMT32AnalogLPF, false);
+ case AnalogOutputMode_OVERSAMPLED:
+ return *new AccurateLowPassFilter(oldMT32AnalogLPF, true);
+ default:
+ return *new NullLowPassFilter;
+ }
+}
+
+void AbstractLowPassFilter::muteRingBuffer(SampleEx *ringBuffer, unsigned int length) {
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+
+ SampleEx *p = ringBuffer;
+ while (length--) {
+ *(p++) = 0.0f;
+ }
+
+#else
+
+ memset(ringBuffer, 0, length * sizeof(SampleEx));
+
+#endif
+
+}
+
+bool AbstractLowPassFilter::hasNextSample() const {
+ return false;
+}
+
+unsigned int AbstractLowPassFilter::getOutputSampleRate() const {
+ return SAMPLE_RATE;
+}
+
+unsigned int AbstractLowPassFilter::estimateInSampleCount(unsigned int outSamples) const {
+ return outSamples;
+}
+
+SampleEx NullLowPassFilter::process(const SampleEx inSample) {
+ return inSample;
+}
+
+CoarseLowPassFilter::CoarseLowPassFilter(bool oldMT32AnalogLPF) :
+ LPF_TAPS(oldMT32AnalogLPF ? COARSE_LPF_TAPS_MT32 : COARSE_LPF_TAPS_CM32L),
+ ringBufferPosition(0)
+{
+ muteRingBuffer(ringBuffer, COARSE_LPF_DELAY_LINE_LENGTH);
+}
+
+SampleEx CoarseLowPassFilter::process(const SampleEx inSample) {
+ static const unsigned int DELAY_LINE_MASK = COARSE_LPF_DELAY_LINE_LENGTH - 1;
+
+ SampleEx sample = LPF_TAPS[COARSE_LPF_DELAY_LINE_LENGTH] * ringBuffer[ringBufferPosition];
+ ringBuffer[ringBufferPosition] = Synth::clipSampleEx(inSample);
+
+ for (unsigned int i = 0; i < COARSE_LPF_DELAY_LINE_LENGTH; i++) {
+ sample += LPF_TAPS[i] * ringBuffer[(i + ringBufferPosition) & DELAY_LINE_MASK];
+ }
+
+ ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK;
+
+#if !MT32EMU_USE_FLOAT_SAMPLES
+ sample >>= COARSE_LPF_FRACTION_BITS;
+#endif
+
+ return sample;
+}
+
+AccurateLowPassFilter::AccurateLowPassFilter(const bool oldMT32AnalogLPF, const bool oversample) :
+ LPF_TAPS(oldMT32AnalogLPF ? ACCURATE_LPF_TAPS_MT32 : ACCURATE_LPF_TAPS_CM32L),
+ deltas(oversample ? ACCURATE_LPF_DELTAS_OVERSAMPLED : ACCURATE_LPF_DELTAS_REGULAR),
+ phaseIncrement(oversample ? ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED : ACCURATE_LPF_PHASE_INCREMENT_REGULAR),
+ outputSampleRate(SAMPLE_RATE * ACCURATE_LPF_NUMBER_OF_PHASES / phaseIncrement),
+ ringBufferPosition(0),
+ phase(0)
+{
+ muteRingBuffer(ringBuffer, ACCURATE_LPF_DELAY_LINE_LENGTH);
+}
+
+SampleEx AccurateLowPassFilter::process(const SampleEx inSample) {
+ static const unsigned int DELAY_LINE_MASK = ACCURATE_LPF_DELAY_LINE_LENGTH - 1;
+
+ float sample = (phase == 0) ? LPF_TAPS[ACCURATE_LPF_DELAY_LINE_LENGTH * ACCURATE_LPF_NUMBER_OF_PHASES] * ringBuffer[ringBufferPosition] : 0.0f;
+ if (!hasNextSample()) {
+ ringBuffer[ringBufferPosition] = inSample;
+ }
+
+ for (unsigned int tapIx = phase, delaySampleIx = 0; delaySampleIx < ACCURATE_LPF_DELAY_LINE_LENGTH; delaySampleIx++, tapIx += ACCURATE_LPF_NUMBER_OF_PHASES) {
+ sample += LPF_TAPS[tapIx] * ringBuffer[(delaySampleIx + ringBufferPosition) & DELAY_LINE_MASK];
+ }
+
+ phase += phaseIncrement;
+ if (ACCURATE_LPF_NUMBER_OF_PHASES <= phase) {
+ phase -= ACCURATE_LPF_NUMBER_OF_PHASES;
+ ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK;
+ }
+
+ return SampleEx(ACCURATE_LPF_NUMBER_OF_PHASES * sample);
+}
+
+bool AccurateLowPassFilter::hasNextSample() const {
+ return phaseIncrement <= phase;
+}
+
+unsigned int AccurateLowPassFilter::getOutputSampleRate() const {
+ return outputSampleRate;
+}
+
+unsigned int AccurateLowPassFilter::estimateInSampleCount(unsigned int outSamples) const {
+ Bit32u cycleCount = outSamples / ACCURATE_LPF_NUMBER_OF_PHASES;
+ Bit32u remainder = outSamples - cycleCount * ACCURATE_LPF_NUMBER_OF_PHASES;
+ return cycleCount * phaseIncrement + deltas[remainder][phase];
+}
+
+void AccurateLowPassFilter::addPositionIncrement(const unsigned int positionIncrement) {
+ phase = (phase + positionIncrement * phaseIncrement) % ACCURATE_LPF_NUMBER_OF_PHASES;
+}
+
+}
diff --git a/audio/softsynth/mt32/Analog.h b/audio/softsynth/mt32/Analog.h
new file mode 100644
index 0000000000..a48db72485
--- /dev/null
+++ b/audio/softsynth/mt32/Analog.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef MT32EMU_ANALOG_H
+#define MT32EMU_ANALOG_H
+
+#include "mt32emu.h"
+
+namespace MT32Emu {
+
+class AbstractLowPassFilter;
+
+/* Analog class is dedicated to perform fair emulation of analogue circuitry of hardware units that is responsible
+ * for processing output signal after the DAC. It appears that the analogue circuit labeled "LPF" on the schematic
+ * also applies audible changes to the signal spectra. There is a significant boost of higher frequencies observed
+ * aside from quite poor attenuation of the mirror spectra above 16 kHz which is due to a relatively low filter order.
+ *
+ * As the final mixing of multiplexed output signal is performed after the DAC, this function is migrated here from Synth.
+ * Saying precisely, mixing is performed within the LPF as the entrance resistors are actually components of a LPF
+ * designed using the multiple feedback topology. Nevertheless, the schematic separates them.
+ */
+class Analog {
+public:
+ Analog(AnalogOutputMode mode, const ControlROMFeatureSet *controlROMFeatures);
+ ~Analog();
+ void process(Sample **outStream, const Sample *nonReverbLeft, const Sample *nonReverbRight, const Sample *reverbDryLeft, const Sample *reverbDryRight, const Sample *reverbWetLeft, const Sample *reverbWetRight, const Bit32u outLength);
+ unsigned int getOutputSampleRate() const;
+ Bit32u getDACStreamsLength(Bit32u outputLength) const;
+ void setSynthOutputGain(float synthGain);
+ void setReverbOutputGain(float reverbGain, bool mt32ReverbCompatibilityMode);
+
+private:
+ AbstractLowPassFilter &leftChannelLPF;
+ AbstractLowPassFilter &rightChannelLPF;
+ SampleEx synthGain;
+ SampleEx reverbGain;
+
+ Analog(Analog &);
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/BReverbModel.cpp b/audio/softsynth/mt32/BReverbModel.cpp
index 37b3e9670d..5e02db8f99 100644
--- a/audio/softsynth/mt32/BReverbModel.cpp
+++ b/audio/softsynth/mt32/BReverbModel.cpp
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-//#include
+//#include
#include "mt32emu.h"
#include "BReverbModel.h"
@@ -501,9 +501,9 @@ void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *
* Analysing of the algorithm suggests that the overflow is most probable when the combs output is added below.
* So, despite this isn't actually accurate, we only add the check here for performance reasons.
*/
- Sample outSample = Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s((Bit32s)outL1 + Bit32s(outL1 >> 1)) + (Bit32s)outL2) + Bit32s(outL2 >> 1)) + (Bit32s)outL3);
+ Sample outSample = Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx((SampleEx)outL1 + SampleEx(outL1 >> 1)) + (SampleEx)outL2) + SampleEx(outL2 >> 1)) + (SampleEx)outL3);
#else
- Sample outSample = Synth::clipBit16s((Bit32s)outL1 + Bit32s(outL1 >> 1) + (Bit32s)outL2 + Bit32s(outL2 >> 1) + (Bit32s)outL3);
+ Sample outSample = Synth::clipSampleEx((SampleEx)outL1 + SampleEx(outL1 >> 1) + (SampleEx)outL2 + SampleEx(outL2 >> 1) + (SampleEx)outL3);
#endif
*(outLeft++) = weirdMul(outSample, wetLevel, 0xFF);
}
@@ -515,9 +515,9 @@ void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *
Sample outSample = 1.5f * (outR1 + outR2) + outR3;
#elif MT32EMU_BOSS_REVERB_PRECISE_MODE
// See the note above for the left channel output.
- Sample outSample = Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s((Bit32s)outR1 + Bit32s(outR1 >> 1)) + (Bit32s)outR2) + Bit32s(outR2 >> 1)) + (Bit32s)outR3);
+ Sample outSample = Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx((SampleEx)outR1 + SampleEx(outR1 >> 1)) + (SampleEx)outR2) + SampleEx(outR2 >> 1)) + (SampleEx)outR3);
#else
- Sample outSample = Synth::clipBit16s((Bit32s)outR1 + Bit32s(outR1 >> 1) + (Bit32s)outR2 + Bit32s(outR2 >> 1) + (Bit32s)outR3);
+ Sample outSample = Synth::clipSampleEx((SampleEx)outR1 + SampleEx(outR1 >> 1) + (SampleEx)outR2 + SampleEx(outR2 >> 1) + (SampleEx)outR3);
#endif
*(outRight++) = weirdMul(outSample, wetLevel, 0xFF);
}
diff --git a/audio/softsynth/mt32/BReverbModel.h b/audio/softsynth/mt32/BReverbModel.h
index 9b840900c3..764daf1a9e 100644
--- a/audio/softsynth/mt32/BReverbModel.h
+++ b/audio/softsynth/mt32/BReverbModel.h
@@ -95,7 +95,6 @@ class BReverbModel {
const bool tapDelayMode;
Bit32u dryAmp;
Bit32u wetLevel;
- void mute();
static const BReverbSettings &getCM32L_LAPCSettings(const ReverbMode mode);
static const BReverbSettings &getMT32Settings(const ReverbMode mode);
@@ -107,6 +106,7 @@ public:
void open();
// May be called multiple times without an open() in between.
void close();
+ void mute();
void setParameters(Bit8u time, Bit8u level);
void process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples);
bool isActive() const;
diff --git a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
index 9265d80c88..42d820ebad 100644
--- a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
@@ -18,7 +18,7 @@
//#include
#include "mt32emu.h"
#include "mmath.h"
-#include "LA32FloatWaveGenerator.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/LA32Ramp.cpp b/audio/softsynth/mt32/LA32Ramp.cpp
index 454612c842..2b31a330d2 100644
--- a/audio/softsynth/mt32/LA32Ramp.cpp
+++ b/audio/softsynth/mt32/LA32Ramp.cpp
@@ -50,8 +50,8 @@ We haven't fully explored:
//#include
#include "mt32emu.h"
-#include "LA32Ramp.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.cpp b/audio/softsynth/mt32/LA32WaveGenerator.cpp
index 7ac7cc6aaa..765f75fa61 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32WaveGenerator.cpp
@@ -15,15 +15,15 @@
* along with this program. If not, see .
*/
-//#include
-#include "mt32emu.h"
-#include "mmath.h"
-#include "LA32WaveGenerator.h"
-
#if MT32EMU_USE_FLOAT_SAMPLES
#include "LA32FloatWaveGenerator.cpp"
#else
+//#include
+#include "mt32emu.h"
+#include "mmath.h"
+#include "internals.h"
+
namespace MT32Emu {
static const Bit32u SINE_SEGMENT_RELATIVE_LENGTH = 1 << 18;
diff --git a/audio/softsynth/mt32/MemoryRegion.h b/audio/softsynth/mt32/MemoryRegion.h
new file mode 100644
index 0000000000..c0cb041e11
--- /dev/null
+++ b/audio/softsynth/mt32/MemoryRegion.h
@@ -0,0 +1,124 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef MT32EMU_MEMORY_REGION_H
+#define MT32EMU_MEMORY_REGION_H
+
+namespace MT32Emu {
+
+enum MemoryRegionType {
+ MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset
+};
+
+class MemoryRegion {
+private:
+ Synth *synth;
+ Bit8u *realMemory;
+ Bit8u *maxTable;
+public:
+ MemoryRegionType type;
+ Bit32u startAddr, entrySize, entries;
+
+ MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) {
+ synth = useSynth;
+ realMemory = useRealMemory;
+ maxTable = useMaxTable;
+ type = useType;
+ startAddr = useStartAddr;
+ entrySize = useEntrySize;
+ entries = useEntries;
+ }
+ int lastTouched(Bit32u addr, Bit32u len) const {
+ return (offset(addr) + len - 1) / entrySize;
+ }
+ int firstTouchedOffset(Bit32u addr) const {
+ return offset(addr) % entrySize;
+ }
+ int firstTouched(Bit32u addr) const {
+ return offset(addr) / entrySize;
+ }
+ Bit32u regionEnd() const {
+ return startAddr + entrySize * entries;
+ }
+ bool contains(Bit32u addr) const {
+ return addr >= startAddr && addr < regionEnd();
+ }
+ int offset(Bit32u addr) const {
+ return addr - startAddr;
+ }
+ Bit32u getClampedLen(Bit32u addr, Bit32u len) const {
+ if (addr + len > regionEnd())
+ return regionEnd() - addr;
+ return len;
+ }
+ Bit32u next(Bit32u addr, Bit32u len) const {
+ if (addr + len > regionEnd()) {
+ return regionEnd() - addr;
+ }
+ return 0;
+ }
+ Bit8u getMaxValue(int off) const {
+ if (maxTable == NULL)
+ return 0xFF;
+ return maxTable[off % entrySize];
+ }
+ Bit8u *getRealMemory() const {
+ return realMemory;
+ }
+ bool isReadable() const {
+ return getRealMemory() != NULL;
+ }
+ void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const;
+ void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const;
+};
+
+class PatchTempMemoryRegion : public MemoryRegion {
+public:
+ PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {}
+};
+class RhythmTempMemoryRegion : public MemoryRegion {
+public:
+ RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {}
+};
+class TimbreTempMemoryRegion : public MemoryRegion {
+public:
+ TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {}
+};
+class PatchesMemoryRegion : public MemoryRegion {
+public:
+ PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {}
+};
+class TimbresMemoryRegion : public MemoryRegion {
+public:
+ TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {}
+};
+class SystemMemoryRegion : public MemoryRegion {
+public:
+ SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {}
+};
+class DisplayMemoryRegion : public MemoryRegion {
+public:
+ DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), MAX_SYSEX_SIZE - 1, 1) {}
+};
+class ResetMemoryRegion : public MemoryRegion {
+public:
+ ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {}
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/MidiEventQueue.h b/audio/softsynth/mt32/MidiEventQueue.h
new file mode 100644
index 0000000000..b1948c5f8e
--- /dev/null
+++ b/audio/softsynth/mt32/MidiEventQueue.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef MT32EMU_MIDI_EVENT_QUEUE_H
+#define MT32EMU_MIDI_EVENT_QUEUE_H
+
+namespace MT32Emu {
+
+/**
+ * Used to safely store timestamped MIDI events in a local queue.
+ */
+struct MidiEvent {
+ Bit32u shortMessageData;
+ const Bit8u *sysexData;
+ Bit32u sysexLength;
+ Bit32u timestamp;
+
+ ~MidiEvent();
+ void setShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+};
+
+/**
+ * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it.
+ * It is intended to:
+ * - get rid of prerenderer while retaining graceful partial abortion
+ * - add fair emulation of the MIDI interface delays
+ * - extend the synth interface with the default implementation of a typical rendering loop.
+ * THREAD SAFETY:
+ * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading
+ * and one performs only writing. More complicated usage requires external synchronisation.
+ */
+class MidiEventQueue {
+private:
+ MidiEvent * const ringBuffer;
+ const Bit32u ringBufferMask;
+ volatile Bit32u startPosition;
+ volatile Bit32u endPosition;
+
+public:
+ MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE); // Must be a power of 2
+ ~MidiEventQueue();
+ void reset();
+ bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+ const MidiEvent *peekMidiEvent();
+ void dropMidiEvent();
+ bool isFull() const;
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp
index d92473b5db..cffc3ed744 100644
--- a/audio/softsynth/mt32/Part.cpp
+++ b/audio/softsynth/mt32/Part.cpp
@@ -19,6 +19,7 @@
//#include
#include "mt32emu.h"
+#include "internals.h"
#include "PartialManager.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp
index 7dcc6e945a..7348087509 100644
--- a/audio/softsynth/mt32/Partial.cpp
+++ b/audio/softsynth/mt32/Partial.cpp
@@ -21,6 +21,7 @@
#include "mt32emu.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
@@ -312,8 +313,8 @@ bool Partial::produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long len
// Though, it is unknown whether this overflow is exploited somewhere.
Sample leftOut = Sample((sample * leftPanValue) >> 8);
Sample rightOut = Sample((sample * rightPanValue) >> 8);
- *leftBuf = Synth::clipBit16s((Bit32s)*leftBuf + (Bit32s)leftOut);
- *rightBuf = Synth::clipBit16s((Bit32s)*rightBuf + (Bit32s)rightOut);
+ *leftBuf = Synth::clipSampleEx((SampleEx)*leftBuf + (SampleEx)leftOut);
+ *rightBuf = Synth::clipSampleEx((SampleEx)*rightBuf + (SampleEx)rightOut);
leftBuf++;
rightBuf++;
#endif
diff --git a/audio/softsynth/mt32/PartialManager.cpp b/audio/softsynth/mt32/PartialManager.cpp
index fe73087581..8ca6e4e3d7 100644
--- a/audio/softsynth/mt32/PartialManager.cpp
+++ b/audio/softsynth/mt32/PartialManager.cpp
@@ -18,6 +18,7 @@
//#include
#include "mt32emu.h"
+#include "internals.h"
#include "PartialManager.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Poly.cpp b/audio/softsynth/mt32/Poly.cpp
index e07ceb4231..badcd8fb96 100644
--- a/audio/softsynth/mt32/Poly.cpp
+++ b/audio/softsynth/mt32/Poly.cpp
@@ -16,6 +16,7 @@
*/
#include "mt32emu.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Poly.h b/audio/softsynth/mt32/Poly.h
index 9c6431ce36..e2614369bb 100644
--- a/audio/softsynth/mt32/Poly.h
+++ b/audio/softsynth/mt32/Poly.h
@@ -21,6 +21,7 @@
namespace MT32Emu {
class Part;
+class Partial;
enum PolyState {
POLY_Playing,
diff --git a/audio/softsynth/mt32/ROMInfo.cpp b/audio/softsynth/mt32/ROMInfo.cpp
index eb9622620f..7c0127078b 100644
--- a/audio/softsynth/mt32/ROMInfo.cpp
+++ b/audio/softsynth/mt32/ROMInfo.cpp
@@ -21,8 +21,8 @@
namespace MT32Emu {
static const ROMInfo *getKnownROMInfoFromList(unsigned int index) {
- static const ControlROMFeatureSet MT32_COMPATIBLE(true);
- static const ControlROMFeatureSet CM32L_COMPATIBLE(false);
+ static const ControlROMFeatureSet MT32_COMPATIBLE(true, true);
+ static const ControlROMFeatureSet CM32L_COMPATIBLE(false, false);
// Known ROMs
static const ROMInfo CTRL_MT32_V1_04 = {65536, "5a5cb5a77d7d55ee69657c2f870416daed52dea7", ROMInfo::Control, "ctrl_mt32_1_04", "MT-32 Control v1.04", ROMInfo::Full, NULL, &MT32_COMPATIBLE};
@@ -106,7 +106,6 @@ void ROMImage::freeROMImage(const ROMImage *romImage) {
delete romImage;
}
-
Common::File* ROMImage::getFile() const {
return file;
}
@@ -115,11 +114,17 @@ const ROMInfo* ROMImage::getROMInfo() const {
return romInfo;
}
-ControlROMFeatureSet::ControlROMFeatureSet(bool useDefaultReverbMT32Compatible) : defaultReverbMT32Compatible(useDefaultReverbMT32Compatible) {
-}
+ControlROMFeatureSet::ControlROMFeatureSet(bool useDefaultReverbMT32Compatible, bool useOldMT32AnalogLPF) :
+ defaultReverbMT32Compatible(useDefaultReverbMT32Compatible),
+ oldMT32AnalogLPF(useOldMT32AnalogLPF)
+{}
bool ControlROMFeatureSet::isDefaultReverbMT32Compatible() const {
return defaultReverbMT32Compatible;
}
+bool ControlROMFeatureSet::isOldMT32AnalogLPF() const {
+ return oldMT32AnalogLPF;
+}
+
}
diff --git a/audio/softsynth/mt32/ROMInfo.h b/audio/softsynth/mt32/ROMInfo.h
index cecbb6054f..4682620a15 100644
--- a/audio/softsynth/mt32/ROMInfo.h
+++ b/audio/softsynth/mt32/ROMInfo.h
@@ -77,10 +77,12 @@ public:
struct ControlROMFeatureSet {
private:
unsigned int defaultReverbMT32Compatible : 1;
+ unsigned int oldMT32AnalogLPF : 1;
public:
- ControlROMFeatureSet(bool defaultReverbMT32Compatible);
+ ControlROMFeatureSet(bool defaultReverbMT32Compatible, bool oldMT32AnalogLPF);
bool isDefaultReverbMT32Compatible() const;
+ bool isOldMT32AnalogLPF() const;
};
}
diff --git a/audio/softsynth/mt32/Structures.h b/audio/softsynth/mt32/Structures.h
index 35dcee90d6..4dada3a847 100644
--- a/audio/softsynth/mt32/Structures.h
+++ b/audio/softsynth/mt32/Structures.h
@@ -31,19 +31,6 @@ namespace MT32Emu {
#define MT32EMU_ALIGN_PACKED __attribute__((packed))
#endif
-typedef unsigned int Bit32u;
-typedef signed int Bit32s;
-typedef unsigned short int Bit16u;
-typedef signed short int Bit16s;
-typedef unsigned char Bit8u;
-typedef signed char Bit8s;
-
-#if MT32EMU_USE_FLOAT_SAMPLES
-typedef float Sample;
-#else
-typedef Bit16s Sample;
-#endif
-
// The following structures represent the MT-32's memory
// Since sysex allows this memory to be written to in blocks of bytes,
// we keep this packed so that we can copy data into the various
@@ -184,7 +171,37 @@ struct MemParams {
#pragma pack()
#endif
-struct ControlROMPCMStruct;
+struct ControlROMMap {
+ Bit16u idPos;
+ Bit16u idLen;
+ const char *idBytes;
+ Bit16u pcmTable; // 4 * pcmCount bytes
+ Bit16u pcmCount;
+ Bit16u timbreAMap; // 128 bytes
+ Bit16u timbreAOffset;
+ bool timbreACompressed;
+ Bit16u timbreBMap; // 128 bytes
+ Bit16u timbreBOffset;
+ bool timbreBCompressed;
+ Bit16u timbreRMap; // 2 * timbreRCount bytes
+ Bit16u timbreRCount;
+ Bit16u rhythmSettings; // 4 * rhythmSettingsCount bytes
+ Bit16u rhythmSettingsCount;
+ Bit16u reserveSettings; // 9 bytes
+ Bit16u panSettings; // 8 bytes
+ Bit16u programSettings; // 8 bytes
+ Bit16u rhythmMaxTable; // 4 bytes
+ Bit16u patchMaxTable; // 16 bytes
+ Bit16u systemMaxTable; // 23 bytes
+ Bit16u timbreMaxTable; // 72 bytes
+};
+
+struct ControlROMPCMStruct {
+ Bit8u pos;
+ Bit8u len;
+ Bit8u pitchLSB;
+ Bit8u pitchMSB;
+};
struct PCMWaveEntry {
Bit32u addr;
@@ -216,8 +233,6 @@ struct PatchCache {
const TimbreParam::PartialParam *partialParam;
};
-class Partial; // Forward reference for class defined in partial.h
-
}
#endif
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index 3bff429875..6df7eb9e31 100644
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -22,12 +22,19 @@
#include "mt32emu.h"
#include "mmath.h"
-#include "PartialManager.h"
+#include "internals.h"
+
+#include "Analog.h"
#include "BReverbModel.h"
-#include "common/debug.h"
+#include "MemoryRegion.h"
+#include "MidiEventQueue.h"
+#include "PartialManager.h"
namespace MT32Emu {
+// MIDI interface data transfer rate in samples. Used to simulate the transfer delay.
+static const double MIDI_DATA_TRANSFER_RATE = (double)SAMPLE_RATE / 31250.0 * 8.0;
+
static const ControlROMMap ControlROMMaps[7] = {
// ID IDc IDbytes PCMmap PCMc tmbrA tmbrAO, tmbrAC tmbrB tmbrBO, tmbrBC tmbrR trC rhythm rhyC rsrv panpot prog rhyMax patMax sysMax timMax
{0x4014, 22, "\000 ver1.04 14 July 87 ", 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A},
@@ -46,18 +53,15 @@ static inline void advanceStreamPosition(Sample *&stream, Bit32u posDelta) {
}
}
-Bit8u Synth::calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum) {
+Bit8u Synth::calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum) {
+ unsigned int checksum = -initChecksum;
for (unsigned int i = 0; i < len; i++) {
- checksum = checksum + data[i];
+ checksum -= data[i];
}
- checksum = checksum & 0x7f;
- if (checksum) {
- checksum = 0x80 - checksum;
- }
- return checksum;
+ return Bit8u(checksum & 0x7f);
}
-Synth::Synth(ReportHandler *useReportHandler) {
+Synth::Synth(ReportHandler *useReportHandler) : mt32ram(*new MemParams()), mt32default(*new MemParams()) {
isOpen = false;
reverbOverridden = false;
partialCount = DEFAULT_MAX_PARTIALS;
@@ -75,6 +79,7 @@ Synth::Synth(ReportHandler *useReportHandler) {
reverbModels[i] = NULL;
}
reverbModel = NULL;
+ analog = NULL;
setDACInputMode(DACInputMode_NICE);
setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY);
setOutputGain(1.0f);
@@ -92,6 +97,8 @@ Synth::~Synth() {
if (isDefaultReportHandler) {
delete reportHandler;
}
+ delete &mt32ram;
+ delete &mt32default;
}
void ReportHandler::showLCDMessage(const char *data) {
@@ -126,7 +133,7 @@ void Synth::printDebug(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
#if MT32EMU_DEBUG_SAMPLESTAMPS > 0
- reportHandler->printDebug("[%u] ", renderedSampleCount);
+ reportHandler->printDebug("[%u] ", (char *)&renderedSampleCount);
#endif
reportHandler->printDebug(fmt, ap);
va_end(ap);
@@ -211,10 +218,7 @@ MIDIDelayMode Synth::getMIDIDelayMode() const {
void Synth::setOutputGain(float newOutputGain) {
if (newOutputGain < 0.0f) newOutputGain = -newOutputGain;
outputGain = newOutputGain;
-#if !MT32EMU_USE_FLOAT_SAMPLES
- if (256.0f < newOutputGain) newOutputGain = 256.0f;
- effectiveOutputGain = int(newOutputGain * 256.0f);
-#endif
+ if (analog != NULL) analog->setSynthOutputGain(newOutputGain);
}
float Synth::getOutputGain() const {
@@ -224,13 +228,7 @@ float Synth::getOutputGain() const {
void Synth::setReverbOutputGain(float newReverbOutputGain) {
if (newReverbOutputGain < 0.0f) newReverbOutputGain = -newReverbOutputGain;
reverbOutputGain = newReverbOutputGain;
- if (!isMT32ReverbCompatibilityMode()) newReverbOutputGain *= CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR;
-#if MT32EMU_USE_FLOAT_SAMPLES
- effectiveReverbOutputGain = newReverbOutputGain;
-#else
- if (256.0f < newReverbOutputGain) newReverbOutputGain = 256.0f;
- effectiveReverbOutputGain = int(newReverbOutputGain * 256.0f);
-#endif
+ if (analog != NULL) analog->setReverbOutputGain(newReverbOutputGain, isMT32ReverbCompatibilityMode());
}
float Synth::getReverbOutputGain() const {
@@ -393,7 +391,11 @@ bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int count, int startTi
return true;
}
-bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount) {
+bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode) {
+ return open(controlROMImage, pcmROMImage, DEFAULT_MAX_PARTIALS, analogOutputMode);
+}
+
+bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount, AnalogOutputMode analogOutputMode) {
if (isOpen) {
return false;
}
@@ -548,6 +550,10 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, u
midiQueue = new MidiEventQueue();
+ analog = new Analog(analogOutputMode, controlROMFeatures);
+ setOutputGain(outputGain);
+ setReverbOutputGain(reverbOutputGain);
+
isOpen = true;
isEnabled = false;
@@ -565,6 +571,9 @@ void Synth::close(bool forced) {
delete midiQueue;
midiQueue = NULL;
+ delete analog;
+ analog = NULL;
+
delete partialManager;
partialManager = NULL;
@@ -603,16 +612,37 @@ void Synth::flushMIDIQueue() {
}
}
-void Synth::setMIDIEventQueueSize(Bit32u useSize) {
- if (midiQueue != NULL) {
- flushMIDIQueue();
- delete midiQueue;
- midiQueue = new MidiEventQueue(useSize);
+Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) {
+ static const Bit32u MAX_QUEUE_SIZE = (1 << 24); // This results in about 256 Mb - much greater than any reasonable value
+
+ if (midiQueue == NULL) return 0;
+ flushMIDIQueue();
+
+ // Find a power of 2 that is >= useSize
+ Bit32u binarySize = 1;
+ if (useSize < MAX_QUEUE_SIZE) {
+ // Using simple linear search as this isn't time critical
+ while (binarySize < useSize) binarySize <<= 1;
+ } else {
+ binarySize = MAX_QUEUE_SIZE;
}
+ delete midiQueue;
+ midiQueue = new MidiEventQueue(binarySize);
+ return binarySize;
}
Bit32u Synth::getShortMessageLength(Bit32u msg) {
- if ((msg & 0xF0) == 0xF0) return 1;
+ if ((msg & 0xF0) == 0xF0) {
+ switch (msg & 0xFF) {
+ case 0xF1:
+ case 0xF3:
+ return 2;
+ case 0xF2:
+ return 3;
+ default:
+ return 1;
+ }
+ }
// NOTE: This calculation isn't quite correct
// as it doesn't consider the running status byte
return ((msg & 0xE0) == 0xC0) ? 2 : 3;
@@ -638,6 +668,7 @@ bool Synth::playMsg(Bit32u msg, Bit32u timestamp) {
if (midiDelayMode != MIDIDelayMode_IMMEDIATE) {
timestamp = addMIDIInterfaceDelay(getShortMessageLength(msg), timestamp);
}
+ if (!isEnabled) isEnabled = true;
return midiQueue->pushShortMessage(msg, timestamp);
}
@@ -650,16 +681,19 @@ bool Synth::playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp) {
if (midiDelayMode == MIDIDelayMode_DELAY_ALL) {
timestamp = addMIDIInterfaceDelay(len, timestamp);
}
+ if (!isEnabled) isEnabled = true;
return midiQueue->pushSysex(sysex, len, timestamp);
}
void Synth::playMsgNow(Bit32u msg) {
- // FIXME: Implement active sensing
+ // NOTE: Active sense IS implemented in real hardware. However, realtime processing is clearly out of the library scope.
+ // It is assumed that realtime consumers of the library respond to these MIDI events as appropriate.
+
unsigned char code = (unsigned char)((msg & 0x0000F0) >> 4);
unsigned char chan = (unsigned char)(msg & 0x00000F);
unsigned char note = (unsigned char)((msg & 0x007F00) >> 8);
unsigned char velocity = (unsigned char)((msg & 0x7F0000) >> 16);
- isEnabled = true;
+ if (!isEnabled) isEnabled = true;
//printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note);
@@ -831,7 +865,7 @@ void Synth::playSysexWithoutHeader(unsigned char device, unsigned char command,
printDebug("playSysexWithoutHeader: Message is too short (%d bytes)!", len);
return;
}
- unsigned char checksum = calcSysexChecksum(sysex, len - 1, 0);
+ Bit8u checksum = calcSysexChecksum(sysex, len - 1);
if (checksum != sysex[len - 1]) {
printDebug("playSysexWithoutHeader: Message checksum is incorrect (provided: %02x, expected: %02x)!", sysex[len - 1], checksum);
return;
@@ -1410,9 +1444,8 @@ void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32
memcpy(dstSysexData, useSysexData, sysexLength);
}
-MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBufferSize(useRingBufferSize) {
- ringBuffer = new MidiEvent[ringBufferSize];
- memset(ringBuffer, 0, ringBufferSize * sizeof(MidiEvent));
+MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1) {
+ memset(ringBuffer, 0, useRingBufferSize * sizeof(MidiEvent));
reset();
}
@@ -1426,7 +1459,7 @@ void MidiEventQueue::reset() {
}
bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) {
- unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ Bit32u newEndPosition = (endPosition + 1) & ringBufferMask;
// Is ring buffer full?
if (startPosition == newEndPosition) return false;
ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp);
@@ -1435,7 +1468,7 @@ bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp)
}
bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) {
- unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ Bit32u newEndPosition = (endPosition + 1) & ringBufferMask;
// Is ring buffer full?
if (startPosition == newEndPosition) return false;
ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp);
@@ -1450,31 +1483,36 @@ const MidiEvent *MidiEventQueue::peekMidiEvent() {
void MidiEventQueue::dropMidiEvent() {
// Is ring buffer empty?
if (startPosition != endPosition) {
- startPosition = (startPosition + 1) % ringBufferSize;
+ startPosition = (startPosition + 1) & ringBufferMask;
}
}
+bool MidiEventQueue::isFull() const {
+ return startPosition == ((endPosition + 1) & ringBufferMask);
+}
+
+unsigned int Synth::getStereoOutputSampleRate() const {
+ return (analog == NULL) ? SAMPLE_RATE : analog->getOutputSampleRate();
+}
+
void Synth::render(Sample *stream, Bit32u len) {
- Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN];
- Sample tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
+ if (!isEnabled) {
+ renderedSampleCount += analog->getDACStreamsLength(len);
+ analog->process(NULL, NULL, NULL, NULL, NULL, NULL, NULL, len);
+ muteSampleBuffer(stream, len << 1);
+ return;
+ }
+
+ // As in AnalogOutputMode_ACCURATE mode output is upsampled, buffer size MAX_SAMPLES_PER_RUN is more than enough.
+ Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN], tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
while (len > 0) {
- Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
- renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisLen);
- for (Bit32u i = 0; i < thisLen; i++) {
-#if MT32EMU_USE_FLOAT_SAMPLES
- *(stream++) = tmpNonReverbLeft[i] + tmpReverbDryLeft[i] + tmpReverbWetLeft[i];
- *(stream++) = tmpNonReverbRight[i] + tmpReverbDryRight[i] + tmpReverbWetRight[i];
-#else
- *(stream++) = clipBit16s((Bit32s)tmpNonReverbLeft[i] + (Bit32s)tmpReverbDryLeft[i] + (Bit32s)tmpReverbWetLeft[i]);
- *(stream++) = clipBit16s((Bit32s)tmpNonReverbRight[i] + (Bit32s)tmpReverbDryRight[i] + (Bit32s)tmpReverbWetRight[i]);
-#endif
- }
- len -= thisLen;
+ Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
+ renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, analog->getDACStreamsLength(thisPassLen));
+ analog->process(&stream, tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisPassLen);
+ len -= thisPassLen;
}
}
@@ -1518,7 +1556,10 @@ void Synth::renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample
// In GENERATION2 units, the output from LA32 goes to the Boss chip already bit-shifted.
// In NICE mode, it's also better to increase volume before the reverb processing to preserve accuracy.
void Synth::produceLA32Output(Sample *buffer, Bit32u len) {
-#if !MT32EMU_USE_FLOAT_SAMPLES
+#if MT32EMU_USE_FLOAT_SAMPLES
+ (void)buffer;
+ (void)len;
+#else
switch (dacInputMode) {
case DACInputMode_GENERATION2:
while (len--) {
@@ -1528,7 +1569,7 @@ void Synth::produceLA32Output(Sample *buffer, Bit32u len) {
break;
case DACInputMode_NICE:
while (len--) {
- *buffer = clipBit16s(Bit32s(*buffer) << 1);
+ *buffer = clipSampleEx(SampleEx(*buffer) << 1);
++buffer;
}
break;
@@ -1538,26 +1579,16 @@ void Synth::produceLA32Output(Sample *buffer, Bit32u len) {
#endif
}
-void Synth::convertSamplesToOutput(Sample *buffer, Bit32u len, bool reverb) {
- if (dacInputMode == DACInputMode_PURE) return;
-
+void Synth::convertSamplesToOutput(Sample *buffer, Bit32u len) {
#if MT32EMU_USE_FLOAT_SAMPLES
- float gain = reverb ? effectiveReverbOutputGain : outputGain;
- while (len--) {
- *(buffer++) *= gain;
- }
+ (void)buffer;
+ (void)len;
#else
- int gain = reverb ? effectiveReverbOutputGain : effectiveOutputGain;
if (dacInputMode == DACInputMode_GENERATION1) {
while (len--) {
- Bit32s target = Bit16s((*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE));
- *(buffer++) = clipBit16s((target * gain) >> 8);
+ *buffer = Sample((*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE));
+ ++buffer;
}
- return;
- }
- while (len--) {
- *buffer = clipBit16s((Bit32s(*buffer) * gain) >> 8);
- ++buffer;
}
#endif
}
@@ -1566,18 +1597,18 @@ void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sampl
// Even if LA32 output isn't desired, we proceed anyway with temp buffers
Sample tmpBufNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpBufNonReverbRight[MAX_SAMPLES_PER_RUN];
if (nonReverbLeft == NULL) nonReverbLeft = tmpBufNonReverbLeft;
- if (nonReverbLeft == NULL) nonReverbRight = tmpBufNonReverbRight;
+ if (nonReverbRight == NULL) nonReverbRight = tmpBufNonReverbRight;
Sample tmpBufReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpBufReverbDryRight[MAX_SAMPLES_PER_RUN];
if (reverbDryLeft == NULL) reverbDryLeft = tmpBufReverbDryLeft;
if (reverbDryRight == NULL) reverbDryRight = tmpBufReverbDryRight;
- muteSampleBuffer(nonReverbLeft, len);
- muteSampleBuffer(nonReverbRight, len);
- muteSampleBuffer(reverbDryLeft, len);
- muteSampleBuffer(reverbDryRight, len);
-
if (isEnabled) {
+ muteSampleBuffer(nonReverbLeft, len);
+ muteSampleBuffer(nonReverbRight, len);
+ muteSampleBuffer(reverbDryLeft, len);
+ muteSampleBuffer(reverbDryRight, len);
+
for (unsigned int i = 0; i < getPartialCount(); i++) {
if (partialManager->shouldReverb(i)) {
partialManager->produceOutput(i, reverbDryLeft, reverbDryRight, len);
@@ -1591,8 +1622,8 @@ void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sampl
if (isReverbEnabled()) {
reverbModel->process(reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, len);
- if (reverbWetLeft != NULL) convertSamplesToOutput(reverbWetLeft, len, true);
- if (reverbWetRight != NULL) convertSamplesToOutput(reverbWetRight, len, true);
+ if (reverbWetLeft != NULL) convertSamplesToOutput(reverbWetLeft, len);
+ if (reverbWetRight != NULL) convertSamplesToOutput(reverbWetRight, len);
} else {
muteSampleBuffer(reverbWetLeft, len);
muteSampleBuffer(reverbWetRight, len);
@@ -1601,15 +1632,20 @@ void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sampl
// Don't bother with conversion if the output is going to be unused
if (nonReverbLeft != tmpBufNonReverbLeft) {
produceLA32Output(nonReverbLeft, len);
- convertSamplesToOutput(nonReverbLeft, len, false);
+ convertSamplesToOutput(nonReverbLeft, len);
}
if (nonReverbRight != tmpBufNonReverbRight) {
produceLA32Output(nonReverbRight, len);
- convertSamplesToOutput(nonReverbRight, len, false);
+ convertSamplesToOutput(nonReverbRight, len);
}
- if (reverbDryLeft != tmpBufReverbDryLeft) convertSamplesToOutput(reverbDryLeft, len, false);
- if (reverbDryRight != tmpBufReverbDryRight) convertSamplesToOutput(reverbDryRight, len, false);
+ if (reverbDryLeft != tmpBufReverbDryLeft) convertSamplesToOutput(reverbDryLeft, len);
+ if (reverbDryRight != tmpBufReverbDryRight) convertSamplesToOutput(reverbDryRight, len);
} else {
+ // Avoid muting buffers that wasn't requested
+ if (nonReverbLeft != tmpBufNonReverbLeft) muteSampleBuffer(nonReverbLeft, len);
+ if (nonReverbRight != tmpBufNonReverbRight) muteSampleBuffer(nonReverbRight, len);
+ if (reverbDryLeft != tmpBufReverbDryLeft) muteSampleBuffer(reverbDryLeft, len);
+ if (reverbDryRight != tmpBufReverbDryRight) muteSampleBuffer(reverbDryRight, len);
muteSampleBuffer(reverbWetLeft, len);
muteSampleBuffer(reverbWetRight, len);
}
@@ -1651,14 +1687,48 @@ bool Synth::isActive() const {
return false;
}
-const Partial *Synth::getPartial(unsigned int partialNum) const {
- return partialManager->getPartial(partialNum);
-}
-
unsigned int Synth::getPartialCount() const {
return partialCount;
}
+void Synth::getPartStates(bool *partStates) const {
+ for (int partNumber = 0; partNumber < 9; partNumber++) {
+ const Part *part = parts[partNumber];
+ partStates[partNumber] = part->getActiveNonReleasingPartialCount() > 0;
+ }
+}
+
+void Synth::getPartialStates(PartialState *partialStates) const {
+ static const PartialState partialPhaseToState[8] = {
+ PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK,
+ PartialState_SUSTAIN, PartialState_SUSTAIN, PartialState_RELEASE, PartialState_INACTIVE
+ };
+
+ for (unsigned int partialNum = 0; partialNum < getPartialCount(); partialNum++) {
+ const Partial *partial = partialManager->getPartial(partialNum);
+ partialStates[partialNum] = partial->isActive() ? partialPhaseToState[partial->getTVA()->getPhase()] : PartialState_INACTIVE;
+ }
+}
+
+unsigned int Synth::getPlayingNotes(unsigned int partNumber, Bit8u *keys, Bit8u *velocities) const {
+ unsigned int playingNotes = 0;
+ if (isOpen && (partNumber < 9)) {
+ const Part *part = parts[partNumber];
+ const Poly *poly = part->getFirstActivePoly();
+ while (poly != NULL) {
+ keys[playingNotes] = (Bit8u)poly->getKey();
+ velocities[playingNotes] = (Bit8u)poly->getVelocity();
+ playingNotes++;
+ poly = poly->getNext();
+ }
+ }
+ return playingNotes;
+}
+
+const char *Synth::getPatchName(unsigned int partNumber) const {
+ return (!isOpen || partNumber > 8) ? NULL : parts[partNumber]->getCurrentInstr();
+}
+
const Part *Synth::getPart(unsigned int partNum) const {
if (partNum > 8) {
return NULL;
diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h
index 37fb7b280a..97d4644ee2 100644
--- a/audio/softsynth/mt32/Synth.h
+++ b/audio/softsynth/mt32/Synth.h
@@ -19,15 +19,31 @@
#define MT32EMU_SYNTH_H
//#include
+//#include
namespace MT32Emu {
-class TableInitialiser;
+class Analog;
+class BReverbModel;
+class MemoryRegion;
+class MidiEventQueue;
+class Part;
+class Poly;
class Partial;
class PartialManager;
-class Part;
-class ROMImage;
-class BReverbModel;
+
+class PatchTempMemoryRegion;
+class RhythmTempMemoryRegion;
+class TimbreTempMemoryRegion;
+class PatchesMemoryRegion;
+class TimbresMemoryRegion;
+class SystemMemoryRegion;
+class DisplayMemoryRegion;
+class ResetMemoryRegion;
+
+struct ControlROMMap;
+struct PCMWaveEntry;
+struct MemParams;
/**
* Methods for emulating the connection between the LA32 and the DAC, which involves
@@ -43,8 +59,7 @@ enum DACInputMode {
// Produces samples that exactly match the bits output from the emulated LA32.
// * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range)
// * Much less likely to overdrive than any other mode.
- // * Half the volume of any of the other modes, meaning its volume relative to the reverb
- // output when mixed together directly will sound wrong.
+ // * Half the volume of any of the other modes.
// * Output gain is ignored for both LA32 and reverb output.
// * Perfect for developers while debugging :)
DACInputMode_PURE,
@@ -60,6 +75,7 @@ enum DACInputMode {
DACInputMode_GENERATION2
};
+// Methods for emulating the effective delay of incoming MIDI messages introduced by a MIDI interface.
enum MIDIDelayMode {
// Process incoming MIDI events immediately.
MIDIDelayMode_IMMEDIATE,
@@ -72,6 +88,35 @@ enum MIDIDelayMode {
MIDIDelayMode_DELAY_ALL
};
+// Methods for emulating the effects of analogue circuits of real hardware units on the output signal.
+enum AnalogOutputMode {
+ // Only digital path is emulated. The output samples correspond to the digital signal at the DAC entrance.
+ AnalogOutputMode_DIGITAL_ONLY,
+ // Coarse emulation of LPF circuit. High frequencies are boosted, sample rate remains unchanged.
+ AnalogOutputMode_COARSE,
+ // Finer emulation of LPF circuit. Output signal is upsampled to 48 kHz to allow emulation of audible mirror spectra above 16 kHz,
+ // which is passed through the LPF circuit without significant attenuation.
+ AnalogOutputMode_ACCURATE,
+ // Same as AnalogOutputMode_ACCURATE mode but the output signal is 2x oversampled, i.e. the output sample rate is 96 kHz.
+ // This makes subsequent resampling easier. Besides, due to nonlinear passband of the LPF emulated, it takes fewer number of MACs
+ // compared to a regular LPF FIR implementations.
+ AnalogOutputMode_OVERSAMPLED
+};
+
+enum ReverbMode {
+ REVERB_MODE_ROOM,
+ REVERB_MODE_HALL,
+ REVERB_MODE_PLATE,
+ REVERB_MODE_TAP_DELAY
+};
+
+enum PartialState {
+ PartialState_INACTIVE,
+ PartialState_ATTACK,
+ PartialState_SUSTAIN,
+ PartialState_RELEASE
+};
+
const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41;
const Bit8u SYSEX_MDL_MT32 = 0x16;
@@ -87,148 +132,10 @@ const Bit8u SYSEX_CMD_EOD = 0x45; // End of data
const Bit8u SYSEX_CMD_ERR = 0x4E; // Communications error
const Bit8u SYSEX_CMD_RJC = 0x4F; // Rejection
-const int MAX_SYSEX_SIZE = 512;
+const int MAX_SYSEX_SIZE = 512; // FIXME: Does this correspond to a real MIDI buffer used in h/w devices?
const unsigned int CONTROL_ROM_SIZE = 64 * 1024;
-struct ControlROMPCMStruct {
- Bit8u pos;
- Bit8u len;
- Bit8u pitchLSB;
- Bit8u pitchMSB;
-};
-
-struct ControlROMMap {
- Bit16u idPos;
- Bit16u idLen;
- const char *idBytes;
- Bit16u pcmTable; // 4 * pcmCount bytes
- Bit16u pcmCount;
- Bit16u timbreAMap; // 128 bytes
- Bit16u timbreAOffset;
- bool timbreACompressed;
- Bit16u timbreBMap; // 128 bytes
- Bit16u timbreBOffset;
- bool timbreBCompressed;
- Bit16u timbreRMap; // 2 * timbreRCount bytes
- Bit16u timbreRCount;
- Bit16u rhythmSettings; // 4 * rhythmSettingsCount bytes
- Bit16u rhythmSettingsCount;
- Bit16u reserveSettings; // 9 bytes
- Bit16u panSettings; // 8 bytes
- Bit16u programSettings; // 8 bytes
- Bit16u rhythmMaxTable; // 4 bytes
- Bit16u patchMaxTable; // 16 bytes
- Bit16u systemMaxTable; // 23 bytes
- Bit16u timbreMaxTable; // 72 bytes
-};
-
-enum MemoryRegionType {
- MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset
-};
-
-enum ReverbMode {
- REVERB_MODE_ROOM,
- REVERB_MODE_HALL,
- REVERB_MODE_PLATE,
- REVERB_MODE_TAP_DELAY
-};
-
-class MemoryRegion {
-private:
- Synth *synth;
- Bit8u *realMemory;
- Bit8u *maxTable;
-public:
- MemoryRegionType type;
- Bit32u startAddr, entrySize, entries;
-
- MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) {
- synth = useSynth;
- realMemory = useRealMemory;
- maxTable = useMaxTable;
- type = useType;
- startAddr = useStartAddr;
- entrySize = useEntrySize;
- entries = useEntries;
- }
- int lastTouched(Bit32u addr, Bit32u len) const {
- return (offset(addr) + len - 1) / entrySize;
- }
- int firstTouchedOffset(Bit32u addr) const {
- return offset(addr) % entrySize;
- }
- int firstTouched(Bit32u addr) const {
- return offset(addr) / entrySize;
- }
- Bit32u regionEnd() const {
- return startAddr + entrySize * entries;
- }
- bool contains(Bit32u addr) const {
- return addr >= startAddr && addr < regionEnd();
- }
- int offset(Bit32u addr) const {
- return addr - startAddr;
- }
- Bit32u getClampedLen(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd())
- return regionEnd() - addr;
- return len;
- }
- Bit32u next(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd()) {
- return regionEnd() - addr;
- }
- return 0;
- }
- Bit8u getMaxValue(int off) const {
- if (maxTable == NULL)
- return 0xFF;
- return maxTable[off % entrySize];
- }
- Bit8u *getRealMemory() const {
- return realMemory;
- }
- bool isReadable() const {
- return getRealMemory() != NULL;
- }
- void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const;
- void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const;
-};
-
-class PatchTempMemoryRegion : public MemoryRegion {
-public:
- PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {}
-};
-class RhythmTempMemoryRegion : public MemoryRegion {
-public:
- RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {}
-};
-class TimbreTempMemoryRegion : public MemoryRegion {
-public:
- TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {}
-};
-class PatchesMemoryRegion : public MemoryRegion {
-public:
- PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {}
-};
-class TimbresMemoryRegion : public MemoryRegion {
-public:
- TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {}
-};
-class SystemMemoryRegion : public MemoryRegion {
-public:
- SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {}
-};
-class DisplayMemoryRegion : public MemoryRegion {
-public:
- DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), MAX_SYSEX_SIZE - 1, 1) {}
-};
-class ResetMemoryRegion : public MemoryRegion {
-public:
- ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {}
-};
-
class ReportHandler {
friend class Synth;
@@ -254,47 +161,6 @@ protected:
virtual void onProgramChanged(int /* partNum */, int /* bankNum */, const char * /* patchName */) {}
};
-/**
- * Used to safely store timestamped MIDI events in a local queue.
- */
-struct MidiEvent {
- Bit32u shortMessageData;
- const Bit8u *sysexData;
- Bit32u sysexLength;
- Bit32u timestamp;
-
- ~MidiEvent();
- void setShortMessage(Bit32u shortMessageData, Bit32u timestamp);
- void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
-};
-
-/**
- * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it.
- * It is intended to:
- * - get rid of prerenderer while retaining graceful partial abortion
- * - add fair emulation of the MIDI interface delays
- * - extend the synth interface with the default implementation of a typical rendering loop.
- * THREAD SAFETY:
- * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading
- * and one performs only writing. More complicated usage requires external synchronisation.
- */
-class MidiEventQueue {
-private:
- MidiEvent *ringBuffer;
- Bit32u ringBufferSize;
- volatile Bit32u startPosition;
- volatile Bit32u endPosition;
-
-public:
- MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE);
- ~MidiEventQueue();
- void reset();
- bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp);
- bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
- const MidiEvent *peekMidiEvent();
- void dropMidiEvent();
-};
-
class Synth {
friend class Part;
friend class RhythmPart;
@@ -335,7 +201,7 @@ private:
volatile Bit32u lastReceivedMIDIEventTimestamp;
volatile Bit32u renderedSampleCount;
- MemParams mt32ram, mt32default;
+ MemParams &mt32ram, &mt32default;
BReverbModel *reverbModels[4];
BReverbModel *reverbModel;
@@ -346,12 +212,6 @@ private:
float outputGain;
float reverbOutputGain;
-#if MT32EMU_USE_FLOAT_SAMPLES
- float effectiveReverbOutputGain;
-#else
- int effectiveOutputGain;
- int effectiveReverbOutputGain;
-#endif
bool reversedStereoEnabled;
@@ -368,11 +228,12 @@ private:
// We emulate this by delaying new MIDI events processing until abortion finishes.
Poly *abortingPoly;
- Bit32u getShortMessageLength(Bit32u msg);
+ Analog *analog;
+
Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp);
void produceLA32Output(Sample *buffer, Bit32u len);
- void convertSamplesToOutput(Sample *buffer, Bit32u len, bool reverb);
+ void convertSamplesToOutput(Sample *buffer, Bit32u len);
bool isAbortingPoly() const;
void doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
@@ -404,13 +265,20 @@ private:
void newTimbreSet(int partNum, Bit8u timbreGroup, const char patchName[]);
void printDebug(const char *fmt, ...);
+ // partNum should be 0..7 for Part 1..8, or 8 for Rhythm
+ const Part *getPart(unsigned int partNum) const;
+
public:
- static inline Bit16s clipBit16s(Bit32s sample) {
+ static inline Sample clipSampleEx(SampleEx sampleEx) {
+#if MT32EMU_USE_FLOAT_SAMPLES
+ return sampleEx;
+#else
// Clamp values above 32767 to 32767, and values below -32768 to -32768
// FIXME: Do we really need this stuff? I think these branches are very well predicted. Instead, this introduces a chain.
// The version below is actually a bit faster on my system...
- //return ((sample + 0x8000) & ~0xFFFF) ? (sample >> 31) ^ 0x7FFF : (Bit16s)sample;
- return ((-0x8000 <= sample) && (sample <= 0x7FFF)) ? (Bit16s)sample : (sample >> 31) ^ 0x7FFF;
+ //return ((sampleEx + 0x8000) & ~0xFFFF) ? (sampleEx >> 31) ^ 0x7FFF : (Sample)sampleEx;
+ return ((-0x8000 <= sampleEx) && (sampleEx <= 0x7FFF)) ? (Sample)sampleEx : (sampleEx >> 31) ^ 0x7FFF;
+#endif
}
static inline void muteSampleBuffer(Sample *buffer, Bit32u len) {
@@ -426,7 +294,8 @@ public:
#endif
}
- static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
+ static Bit32u getShortMessageLength(Bit32u msg);
+ static Bit8u calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum = 0);
// Optionally sets callbacks for reporting various errors, information and debug messages
Synth(ReportHandler *useReportHandler = NULL);
@@ -435,8 +304,12 @@ public:
// Used to initialise the MT-32. Must be called before any other function.
// Returns true if initialization was sucessful, otherwise returns false.
// controlROMImage and pcmROMImage represent Control and PCM ROM images for use by synth.
- // usePartialCount sets the maximum number of partials playing simultaneously for this session.
- bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount = DEFAULT_MAX_PARTIALS);
+ // usePartialCount sets the maximum number of partials playing simultaneously for this session (optional).
+ // analogOutputMode sets the mode for emulation of analogue circuitry of the hardware units (optional).
+ bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount = DEFAULT_MAX_PARTIALS, AnalogOutputMode analogOutputMode = AnalogOutputMode_COARSE);
+
+ // Overloaded method which opens the synth with default partial count.
+ bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode);
// Closes the MT-32 and deallocates any memory used by the synthesizer
void close(bool forced = false);
@@ -444,29 +317,34 @@ public:
// All the enqueued events are processed by the synth immediately.
void flushMIDIQueue();
- // Sets size of the internal MIDI event queue.
+ // Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified.
// The queue is flushed before reallocation.
- void setMIDIEventQueueSize(Bit32u);
+ // Returns the actual queue size being used.
+ Bit32u setMIDIEventQueueSize(Bit32u);
// Enqueues a MIDI event for subsequent playback.
- // The minimum delay involves the delay introduced while the event is transferred via MIDI interface
+ // The MIDI event will be processed not before the specified timestamp.
+ // The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz).
+ // The minimum delay involves emulation of the delay introduced while the event is transferred via MIDI interface
// and emulation of the MCU busy-loop while it frees partials for use by a new Poly.
- // Calls from multiple threads must be synchronised, although,
- // no synchronisation is required with the rendering thread.
+ // Calls from multiple threads must be synchronised, although, no synchronisation is required with the rendering thread.
+ // The methods return false if the MIDI event queue is full and the message cannot be enqueued.
- // The MIDI event will be processed not before the specified timestamp.
- // The timestamp is measured as the global rendered sample count since the synth was created.
+ // Enqueues a single short MIDI message. The message must contain a status byte.
bool playMsg(Bit32u msg, Bit32u timestamp);
+ // Enqueues a single well formed System Exclusive MIDI message.
bool playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp);
- // The MIDI event will be processed ASAP.
+
+ // Overloaded methods for the MIDI events to be processed ASAP.
bool playMsg(Bit32u msg);
bool playSysex(const Bit8u *sysex, Bit32u len);
// WARNING:
// The methods below don't ensure minimum 1-sample delay between sequential MIDI events,
// and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent.
+ // A thread that invokes these methods must be explicitly synchronised with the thread performing sample rendering.
- // Sends a 4-byte MIDI message to the MT-32 for immediate playback.
+ // Sends a short MIDI message to the synth for immediate playback. The message must contain a status byte.
void playMsgNow(Bit32u msg);
void playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity);
@@ -495,12 +373,17 @@ public:
void setMIDIDelayMode(MIDIDelayMode mode);
MIDIDelayMode getMIDIDelayMode() const;
- // Sets output gain factor. Applied to all output samples and unrelated with the synth's Master volume.
+ // Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume,
+ // it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with setReverbOutputGain()
+ // it offers to the user a capability to control the gain of reverb and non-reverb output channels independently.
// Ignored in DACInputMode_PURE
void setOutputGain(float);
float getOutputGain() const;
- // Sets output gain factor for the reverb wet output. setOutputGain() doesn't change reverb output gain.
+ // Sets output gain factor for the reverb wet output channels. It rather corresponds to the gain of the output
+ // analog circuitry of the hardware units. However, together with setOutputGain() it offers to the user a capability
+ // to control the gain of reverb and non-reverb output channels independently.
+ //
// Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely
// corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic,
// there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68
@@ -512,12 +395,21 @@ public:
void setReversedStereoEnabled(bool enabled);
bool isReversedStereoEnabled();
- // Renders samples to the specified output stream.
- // The length is in frames, not bytes (in 16-bit stereo,
- // one frame is 4 bytes).
+ // Returns actual sample rate used in emulation of stereo analog circuitry of hardware units.
+ // See comment for render() below.
+ unsigned int getStereoOutputSampleRate() const;
+
+ // Renders samples to the specified output stream as if they were sampled at the analog stereo output.
+ // When AnalogOutputMode is set to ACCURATE, the output signal is upsampled to 48 kHz in order
+ // to retain emulation accuracy in whole audible frequency spectra. Otherwise, native digital signal sample rate is retained.
+ // getStereoOutputSampleRate() can be used to query actual sample rate of the output signal.
+ // The length is in frames, not bytes (in 16-bit stereo, one frame is 4 bytes).
void render(Sample *stream, Bit32u len);
- // Renders samples to the specified output streams (any or all of which may be NULL).
+ // Renders samples to the specified output streams as if they appeared at the DAC entrance.
+ // No further processing performed in analog circuitry emulation is applied to the signal.
+ // NULL may be specified in place of any or all of the stream buffers.
+ // The length is in samples, not bytes.
void renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
// Returns true when there is at least one active partial, otherwise false.
@@ -526,15 +418,28 @@ public:
// Returns true if hasActivePartials() returns true, or reverb is (somewhat unreliably) detected as being active.
bool isActive() const;
- const Partial *getPartial(unsigned int partialNum) const;
-
// Returns the maximum number of partials playing simultaneously.
unsigned int getPartialCount() const;
- void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
+ // Fills in current states of all the parts into the array provided. The array must have at least 9 entries to fit values for all the parts.
+ // If the value returned for a part is true, there is at least one active non-releasing partial playing on this part.
+ // This info is useful in emulating behaviour of LCD display of the hardware units.
+ void getPartStates(bool *partStates) const;
- // partNum should be 0..7 for Part 1..8, or 8 for Rhythm
- const Part *getPart(unsigned int partNum) const;
+ // Fills in current states of all the partials into the array provided. The array must be large enough to accommodate states of all the partials.
+ void getPartialStates(PartialState *partialStates) const;
+
+ // Fills in information about currently playing notes on the specified part into the arrays provided. The arrays must be large enough
+ // to accommodate data for all the playing notes. The maximum number of simultaneously playing notes cannot exceed the number of partials.
+ // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm.
+ // Returns the number of currently playing notes on the specified part.
+ unsigned int getPlayingNotes(unsigned int partNumber, Bit8u *keys, Bit8u *velocities) const;
+
+ // Returns name of the patch set on the specified part.
+ // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm.
+ const char *getPatchName(unsigned int partNumber) const;
+
+ void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
};
}
diff --git a/audio/softsynth/mt32/TVA.cpp b/audio/softsynth/mt32/TVA.cpp
index 3fefb791f2..894e53f14a 100644
--- a/audio/softsynth/mt32/TVA.cpp
+++ b/audio/softsynth/mt32/TVA.cpp
@@ -23,6 +23,7 @@
#include "mt32emu.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/TVF.cpp b/audio/softsynth/mt32/TVF.cpp
index bf8d50a7c9..164cf2b4cb 100644
--- a/audio/softsynth/mt32/TVF.cpp
+++ b/audio/softsynth/mt32/TVF.cpp
@@ -19,6 +19,7 @@
#include "mt32emu.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/TVP.cpp b/audio/softsynth/mt32/TVP.cpp
index 374646e5f1..a8003d96dc 100644
--- a/audio/softsynth/mt32/TVP.cpp
+++ b/audio/softsynth/mt32/TVP.cpp
@@ -19,6 +19,7 @@
//#include
#include "mt32emu.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Tables.cpp b/audio/softsynth/mt32/Tables.cpp
index ae9f11fff0..7e165b5a7a 100644
--- a/audio/softsynth/mt32/Tables.cpp
+++ b/audio/softsynth/mt32/Tables.cpp
@@ -16,14 +16,15 @@
*/
//#include
-//#include
-//#include
#include "mt32emu.h"
#include "mmath.h"
+#include "Tables.h"
namespace MT32Emu {
+// UNUSED: const int MIDDLEC = 60;
+
const Tables &Tables::getInstance() {
static const Tables instance;
return instance;
diff --git a/audio/softsynth/mt32/Tables.h b/audio/softsynth/mt32/Tables.h
index e7b97af515..8865c7fac8 100644
--- a/audio/softsynth/mt32/Tables.h
+++ b/audio/softsynth/mt32/Tables.h
@@ -20,24 +20,11 @@
namespace MT32Emu {
-// Sample rate to use in mixing. With the progress of development, we've found way too many thing dependent.
-// In order to achieve further advance in emulation accuracy, sample rate made fixed throughout the emulator.
-// The output from the synth is supposed to be resampled to convert the sample rate.
-const unsigned int SAMPLE_RATE = 32000;
-
-// MIDI interface data transfer rate in samples. Used to simulate the transfer delay.
-const double MIDI_DATA_TRANSFER_RATE = (double)SAMPLE_RATE / 31250.0 * 8.0;
-
-const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f;
-
-const int MIDDLEC = 60;
-
-class Synth;
-
class Tables {
private:
Tables();
Tables(Tables &);
+ ~Tables() {}
public:
static const Tables &getInstance();
diff --git a/audio/softsynth/mt32/Types.h b/audio/softsynth/mt32/Types.h
new file mode 100644
index 0000000000..934b1a1173
--- /dev/null
+++ b/audio/softsynth/mt32/Types.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef MT32EMU_TYPES_H
+#define MT32EMU_TYPES_H
+
+namespace MT32Emu {
+
+typedef unsigned int Bit32u;
+typedef signed int Bit32s;
+typedef unsigned short int Bit16u;
+typedef signed short int Bit16s;
+typedef unsigned char Bit8u;
+typedef signed char Bit8s;
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+typedef float Sample;
+typedef float SampleEx;
+#else
+typedef Bit16s Sample;
+typedef Bit32s SampleEx;
+#endif
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/internals.h b/audio/softsynth/mt32/internals.h
new file mode 100644
index 0000000000..ef56819a42
--- /dev/null
+++ b/audio/softsynth/mt32/internals.h
@@ -0,0 +1,83 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef MT32EMU_INTERNALS_H
+#define MT32EMU_INTERNALS_H
+
+// Debugging
+
+// 0: Standard debug output is not stamped with the rendered sample count
+// 1: Standard debug output is stamped with the rendered sample count
+// NOTE: The "samplestamp" corresponds to the end of the last completed rendering run.
+// This is important to bear in mind for debug output that occurs during a run.
+#define MT32EMU_DEBUG_SAMPLESTAMPS 0
+
+// 0: No debug output for initialisation progress
+// 1: Debug output for initialisation progress
+#define MT32EMU_MONITOR_INIT 0
+
+// 0: No debug output for MIDI events
+// 1: Debug output for weird MIDI events
+#define MT32EMU_MONITOR_MIDI 0
+
+// 0: No debug output for note on/off
+// 1: Basic debug output for note on/off
+// 2: Comprehensive debug output for note on/off
+#define MT32EMU_MONITOR_INSTRUMENTS 0
+
+// 0: No debug output for partial allocations
+// 1: Show partial stats when an allocation fails
+// 2: Show partial stats with every new poly
+// 3: Show individual partial allocations/deactivations
+#define MT32EMU_MONITOR_PARTIALS 0
+
+// 0: No debug output for sysex
+// 1: Basic debug output for sysex
+#define MT32EMU_MONITOR_SYSEX 0
+
+// 0: No debug output for sysex writes to the timbre areas
+// 1: Debug output with the name and location of newly-written timbres
+// 2: Complete dump of timbre parameters for newly-written timbres
+#define MT32EMU_MONITOR_TIMBRES 0
+
+// 0: No TVA/TVF-related debug output.
+// 1: Shows changes to TVA/TVF target, increment and phase.
+#define MT32EMU_MONITOR_TVA 0
+#define MT32EMU_MONITOR_TVF 0
+
+// Configuration
+
+// If non-zero, deletes reverb buffers that are not in use to save memory.
+// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
+#define MT32EMU_REDUCE_REVERB_MEMORY 1
+
+// 0: Maximum speed at the cost of a bit lower emulation accuracy.
+// 1: Maximum achievable emulation accuracy.
+#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0
+
+#include "Structures.h"
+#include "Tables.h"
+#include "Poly.h"
+#include "LA32Ramp.h"
+#include "LA32WaveGenerator.h"
+#include "TVA.h"
+#include "TVP.h"
+#include "TVF.h"
+#include "Partial.h"
+#include "Part.h"
+
+#endif
diff --git a/audio/softsynth/mt32/module.mk b/audio/softsynth/mt32/module.mk
index 1c8aa125ab..f966da8d08 100644
--- a/audio/softsynth/mt32/module.mk
+++ b/audio/softsynth/mt32/module.mk
@@ -1,6 +1,7 @@
MODULE := audio/softsynth/mt32
MODULE_OBJS := \
+ Analog.o \
BReverbModel.o \
LA32Ramp.o \
LA32WaveGenerator.o \
diff --git a/audio/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h
index d738a5de35..1574c08f0d 100644
--- a/audio/softsynth/mt32/mt32emu.h
+++ b/audio/softsynth/mt32/mt32emu.h
@@ -18,63 +18,20 @@
#ifndef MT32EMU_MT32EMU_H
#define MT32EMU_MT32EMU_H
-// Debugging
-
-// 0: Standard debug output is not stamped with the rendered sample count
-// 1: Standard debug output is stamped with the rendered sample count
-// NOTE: The "samplestamp" corresponds to the end of the last completed rendering run.
-// This is important to bear in mind for debug output that occurs during a run.
-#define MT32EMU_DEBUG_SAMPLESTAMPS 0
-
-// 0: No debug output for initialisation progress
-// 1: Debug output for initialisation progress
-#define MT32EMU_MONITOR_INIT 0
-
-// 0: No debug output for MIDI events
-// 1: Debug output for weird MIDI events
-#define MT32EMU_MONITOR_MIDI 0
-
-// 0: No debug output for note on/off
-// 1: Basic debug output for note on/off
-// 2: Comprehensive debug output for note on/off
-#define MT32EMU_MONITOR_INSTRUMENTS 0
-
-// 0: No debug output for partial allocations
-// 1: Show partial stats when an allocation fails
-// 2: Show partial stats with every new poly
-// 3: Show individual partial allocations/deactivations
-#define MT32EMU_MONITOR_PARTIALS 0
-
-// 0: No debug output for sysex
-// 1: Basic debug output for sysex
-#define MT32EMU_MONITOR_SYSEX 0
-
-// 0: No debug output for sysex writes to the timbre areas
-// 1: Debug output with the name and location of newly-written timbres
-// 2: Complete dump of timbre parameters for newly-written timbres
-#define MT32EMU_MONITOR_TIMBRES 0
-
-// 0: No TVA/TVF-related debug output.
-// 1: Shows changes to TVA/TVF target, increment and phase.
-#define MT32EMU_MONITOR_TVA 0
-#define MT32EMU_MONITOR_TVF 0
-
// Configuration
-// If non-zero, deletes reverb buffers that are not in use to save memory.
-// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
-#define MT32EMU_REDUCE_REVERB_MEMORY 1
-
-// 0: Maximum speed at the cost of a bit lower emulation accuracy.
-// 1: Maximum achievable emulation accuracy.
-#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0
-
// 0: Use 16-bit signed samples and refined wave generator based on logarithmic fixed-point computations and LUTs. Maximum emulation accuracy and speed.
// 1: Use float samples in the wave generator and renderer. Maximum output quality and minimum noise.
#define MT32EMU_USE_FLOAT_SAMPLES 0
namespace MT32Emu
{
+// Sample rate to use in mixing. With the progress of development, we've found way too many thing dependent.
+// In order to achieve further advance in emulation accuracy, sample rate made fixed throughout the emulator,
+// except the emulation of analogue path.
+// The output from the synth is supposed to be resampled externally in order to convert to the desired sample rate.
+const unsigned int SAMPLE_RATE = 32000;
+
// The default value for the maximum number of partials playing simultaneously.
const unsigned int DEFAULT_MAX_PARTIALS = 32;
@@ -97,17 +54,7 @@ const unsigned int MAX_SAMPLES_PER_RUN = 4096;
const unsigned int DEFAULT_MIDI_EVENT_QUEUE_SIZE = 1024;
}
-#include "Structures.h"
-#include "common/file.h"
-#include "Tables.h"
-#include "Poly.h"
-#include "LA32Ramp.h"
-#include "LA32WaveGenerator.h"
-#include "TVA.h"
-#include "TVP.h"
-#include "TVF.h"
-#include "Partial.h"
-#include "Part.h"
+#include "Types.h"
#include "ROMInfo.h"
#include "Synth.h"
--
cgit v1.2.3
From 965dafe31b1c1f7c4684c0d2cbdb3461e3fddac8 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sun, 21 Dec 2014 23:33:01 +0200
Subject: ZVISION: Implement the "dumpallscripts" console command again
---
engines/zvision/core/console.cpp | 40 ++++++++++++++++++++++++++-------
engines/zvision/core/console.h | 1 +
engines/zvision/file/search_manager.cpp | 7 ++++++
engines/zvision/file/search_manager.h | 18 +++++++--------
4 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index 4dd10d6f40..0789f8d4fb 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -52,6 +52,7 @@ Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
registerCmd("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
registerCmd("location", WRAP_METHOD(Console, cmdLocation));
registerCmd("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
+ registerCmd("dumpallscripts", WRAP_METHOD(Console, cmdDumpAllScripts));
}
bool Console::cmdLoadVideo(int argc, const char **argv) {
@@ -205,6 +206,20 @@ bool Console::cmdLocation(int argc, const char **argv) {
return true;
}
+void dumpFile(Common::SeekableReadStream *s, const char *outName) {
+ byte *buffer = new byte[s->size()];
+ s->read(buffer, s->size());
+
+ Common::DumpFile dumpFile;
+ dumpFile.open(outName);
+
+ dumpFile.write(buffer, s->size());
+ dumpFile.flush();
+ dumpFile.close();
+
+ delete[] buffer;
+}
+
bool Console::cmdDumpFile(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Use %s to dump a file\n", argv[0]);
@@ -217,17 +232,26 @@ bool Console::cmdDumpFile(int argc, const char **argv) {
return true;
}
- byte *buffer = new byte[f.size()];
- f.read(buffer, f.size());
+ dumpFile(&f, argv[1]);
- Common::DumpFile dumpFile;
- dumpFile.open(argv[1]);
+ return true;
+}
- dumpFile.write(buffer, f.size());
- dumpFile.flush();
- dumpFile.close();
+bool Console::cmdDumpAllScripts(int argc, const char **argv) {
+ Common::String fileName;
+ Common::SeekableReadStream *in;
- delete[] buffer;
+ SearchManager::MatchList fileList;
+ _engine->getSearchManager()->listMembersWithExtension(fileList, "scr");
+
+ for (SearchManager::MatchList::iterator iter = fileList.begin(); iter != fileList.end(); ++iter) {
+ fileName = iter->_value.name;
+ debugPrintf("Dumping %s\n", fileName.c_str());
+
+ in = iter->_value.arch->createReadStreamForMember(iter->_value.name);
+ dumpFile(in, fileName.c_str());
+ delete in;
+ }
return true;
}
diff --git a/engines/zvision/core/console.h b/engines/zvision/core/console.h
index 299bd6127f..7e27fe8f26 100644
--- a/engines/zvision/core/console.h
+++ b/engines/zvision/core/console.h
@@ -46,6 +46,7 @@ private:
bool cmdSetPanoramaScale(int argc, const char **argv);
bool cmdLocation(int argc, const char **argv);
bool cmdDumpFile(int argc, const char **argv);
+ bool cmdDumpAllScripts(int argc, const char **argv);
};
} // End of namespace ZVision
diff --git a/engines/zvision/file/search_manager.cpp b/engines/zvision/file/search_manager.cpp
index d0d4e43d12..7a907df39c 100644
--- a/engines/zvision/file/search_manager.cpp
+++ b/engines/zvision/file/search_manager.cpp
@@ -275,4 +275,11 @@ void SearchManager::listDirRecursive(Common::List &_list, const
}
}
+void SearchManager::listMembersWithExtension(MatchList &fileList, Common::String extension) {
+ for (SearchManager::MatchList::iterator it = _files.begin(); it != _files.end(); ++it) {
+ if (it->_key.hasSuffix(extension))
+ fileList[it->_key] = it->_value;
+ }
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/file/search_manager.h b/engines/zvision/file/search_manager.h
index fdd70fd381..b9ed02ec13 100644
--- a/engines/zvision/file/search_manager.h
+++ b/engines/zvision/file/search_manager.h
@@ -47,25 +47,23 @@ public:
void loadZix(const Common::String &name);
-private:
-
- void listDirRecursive(Common::List &dirList, const Common::FSNode &fsNode, int depth);
-
struct Node {
Common::String name;
Common::Archive *arch;
};
- Common::List _dirList;
-
typedef Common::HashMap MatchList;
- Common::List _archList;
- MatchList _files;
-
- Common::String _root;
+ void listMembersWithExtension(MatchList &fileList, Common::String extension);
private:
+
+ void listDirRecursive(Common::List &dirList, const Common::FSNode &fsNode, int depth);
+
+ Common::List _dirList;
+ Common::List _archList;
+ Common::String _root;
+ MatchList _files;
};
}
--
cgit v1.2.3
From e5ecd500cfbf1c91da31dab0a5a71ff43ed82033 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sun, 21 Dec 2014 23:33:48 +0200
Subject: ZVISION: Document some controls that are only used in Zork: Nemesis
---
engines/zvision/scripting/controls/fist_control.h | 1 +
engines/zvision/scripting/controls/hotmov_control.h | 1 +
engines/zvision/scripting/controls/paint_control.h | 1 +
engines/zvision/scripting/controls/titler_control.h | 1 +
engines/zvision/scripting/scr_file_handling.cpp | 4 ++++
5 files changed, 8 insertions(+)
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
index 0a6b977ead..bad2daa6d5 100644
--- a/engines/zvision/scripting/controls/fist_control.h
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, it handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
class FistControl : public Control {
public:
FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/hotmov_control.h b/engines/zvision/scripting/controls/hotmov_control.h
index b18d44c7a6..640fab00c0 100644
--- a/engines/zvision/scripting/controls/hotmov_control.h
+++ b/engines/zvision/scripting/controls/hotmov_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, it handles movies where the player needs to click on something (mj7g, vw3g)
class HotMovControl : public Control {
public:
HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/paint_control.h b/engines/zvision/scripting/controls/paint_control.h
index 8097290ac2..0e5b59b821 100644
--- a/engines/zvision/scripting/controls/paint_control.h
+++ b/engines/zvision/scripting/controls/paint_control.h
@@ -32,6 +32,7 @@
namespace ZVision {
+// Only used in Zork Nemesis, it's the painting puzzle screen in Lucien's room in Irondune (ch4g)
class PaintControl : public Control {
public:
PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/titler_control.h b/engines/zvision/scripting/controls/titler_control.h
index 075e47c9e9..86bb398b3c 100644
--- a/engines/zvision/scripting/controls/titler_control.h
+++ b/engines/zvision/scripting/controls/titler_control.h
@@ -32,6 +32,7 @@
namespace ZVision {
+// Only used in Zork Nemesis - it's the death screen with the Restore/Exit buttons
class TitlerControl : public Control {
public:
TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index c117da5ec2..47b8b0aa39 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -358,12 +358,16 @@ Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadS
} else if (controlType.equalsIgnoreCase("safe")) {
return new SafeControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("hotmovie")) {
+ // Only used in Zork Nemesis, it handles movies where the player needs to click on something (mj7g, vw3g)
return new HotMovControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("fist")) {
+ // Only used in Zork Nemesis, it handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
return new FistControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("paint")) {
+ // Only used in Zork Nemesis, it's the painting puzzle screen in Lucien's room in Irondune (ch4g)
return new PaintControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("titler")) {
+ // Only used in Zork Nemesis - it's the death screen with the Restore/Exit buttons (cjde)
return new TitlerControl(_engine, key, stream);
}
return NULL;
--
cgit v1.2.3
From 24f0cce9c6b0da33d1558059c6fbdb966eb5fb4e Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 21 Dec 2014 22:28:25 +0100
Subject: ACCESS: Fix bug in setHorizontalCode()
---
engines/access/amazon/amazon_logic.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index e6a96b67d6..4a313e8880 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -1035,7 +1035,7 @@ void Guard::setHorizontalCode() {
if (_bottomRight.x < screen._orgX1)
_gCode2 |= 8;
- else if (_bottomRight.y > screen._orgX2)
+ else if (_bottomRight.x > screen._orgX2)
_gCode2 |= 2;
}
--
cgit v1.2.3
From 4a1ddd5d0c8760dbdee967d8152c8e0e650eb4df Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 21 Dec 2014 22:49:18 +0100
Subject: ACCESS: Remove unused variable
---
engines/access/access.cpp | 1 -
engines/access/access.h | 1 -
engines/access/amazon/amazon_game.cpp | 1 -
3 files changed, 3 deletions(-)
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 39e6c2b530..67255ff5ea 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -93,7 +93,6 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_vidX = _vidY = 0;
_cheatFl = false;
_restartFl = false;
- _et = 0;
_printEnd = 0;
}
diff --git a/engines/access/access.h b/engines/access/access.h
index a082b969c4..be007e0cb8 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -191,7 +191,6 @@ public:
bool _canSaveLoad;
Resource *_establish;
- int _et;
int _printEnd;
int _txtPages;
int _narateFile;
diff --git a/engines/access/amazon/amazon_game.cpp b/engines/access/amazon/amazon_game.cpp
index eb4fabdad9..d6b759b308 100644
--- a/engines/access/amazon/amazon_game.cpp
+++ b/engines/access/amazon/amazon_game.cpp
@@ -268,7 +268,6 @@ void AmazonEngine::doEstablish(int screenId, int estabIndex) {
_screen->_maxChars = 37;
_screen->_printOrg = _screen->_printStart = Common::Point(48, 35);
loadEstablish(estabIndex);
- _et = estabIndex;
uint16 msgOffset;
if (!isCD())
msgOffset = READ_LE_UINT16(_establish->data() + (estabIndex * 2));
--
cgit v1.2.3
From 8bc30d0dfbc538c3631692a807d37e9007958da9 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 21 Dec 2014 22:53:20 +0100
Subject: ACCESS: Initialize header in videoPlayer constructor
---
engines/access/video.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/engines/access/video.cpp b/engines/access/video.cpp
index 920c066898..edc0bcda27 100644
--- a/engines/access/video.cpp
+++ b/engines/access/video.cpp
@@ -29,6 +29,7 @@ VideoPlayer::VideoPlayer(AccessEngine *vm) : Manager(vm) {
_vidSurface = nullptr;
_videoData = nullptr;
_startCoord = nullptr;
+
_frameCount = 0;
_xCount = 0;
_scanCount = 0;
@@ -37,6 +38,10 @@ VideoPlayer::VideoPlayer(AccessEngine *vm) : Manager(vm) {
_soundFlag = false;
_soundFrame = 0;
_videoEnd = false;
+
+ _header._frameCount = 0;
+ _header._width = _header._height = 0;
+ _header._flags = 0;
}
VideoPlayer::~VideoPlayer() {
--
cgit v1.2.3
From 99087c7f454970665391004321c0fc510cdaf9bd Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 21 Dec 2014 22:55:24 +0100
Subject: ACCESS: Use enum instead of int to initialize video flag
---
engines/access/video.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/access/video.cpp b/engines/access/video.cpp
index edc0bcda27..63d0aa5c89 100644
--- a/engines/access/video.cpp
+++ b/engines/access/video.cpp
@@ -41,7 +41,7 @@ VideoPlayer::VideoPlayer(AccessEngine *vm) : Manager(vm) {
_header._frameCount = 0;
_header._width = _header._height = 0;
- _header._flags = 0;
+ _header._flags = VIDEOFLAG_NONE;
}
VideoPlayer::~VideoPlayer() {
--
cgit v1.2.3
From dfae161386a2ad9e6828f71e90dd19598ca52f36 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 00:26:53 +0200
Subject: ZVISION: Implement the Venus hint system in Zork: Nemesis
---
engines/zvision/core/events.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 6cf0ae5d0d..f0cf3f0789 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -145,6 +145,11 @@ void ZVision::cheatCodes(uint8 key) {
getBufferedKey(2),
getBufferedKey(1),
getBufferedKey(0), 0);
+
+ // Show the Venus screen when "?" or "/" is pressed while inside the temple world
+ if (_scriptManager->getStateValue(StateKey_VenusEnable) == 1)
+ if ((checkCode("?") || checkCode("/")) && _scriptManager->getStateValue(StateKey_World) == 't')
+ _scriptManager->changeLocation('g', 'j', 'h', 'e', 0);
}
void ZVision::processEvents() {
--
cgit v1.2.3
From 41dbbe346c4b46b4b48cdb38687216b1dd254fb4 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 00:29:19 +0200
Subject: ZVISION: Also allow the movement when the cursor is within screen
edges
This matches the behavior of the original in Zork: Nemesis. ZGI already
fills the screen horizontally
---
engines/zvision/core/events.cpp | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index f0cf3f0789..81ad28f29b 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -284,26 +284,30 @@ void ZVision::onMouseMove(const Common::Point &pos) {
// |
// ^
- if (_workingWindow.contains(pos)) {
- cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord);
+ // Clip the horizontal mouse position to the working window
+ Common::Point clippedPos = pos;
+ clippedPos.x = CLIP(pos.x, _workingWindow.left + 1, _workingWindow.right - 1);
+
+ if (_workingWindow.contains(clippedPos)) {
+ cursorWasChanged = _scriptManager->onMouseMove(clippedPos, imageCoord);
RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
if (renderState == RenderTable::PANORAMA) {
- if (pos.x >= _workingWindow.left && pos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
+ if (clippedPos.x >= _workingWindow.left && clippedPos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
if (mspeed <= 0)
mspeed = 400 >> 4;
- _mouseVelocity = (((pos.x - (ROTATION_SCREEN_EDGE_OFFSET + _workingWindow.left)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ _mouseVelocity = (((clippedPos.x - (ROTATION_SCREEN_EDGE_OFFSET + _workingWindow.left)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
_cursorManager->changeCursor(CursorIndex_Left);
cursorWasChanged = true;
- } else if (pos.x <= _workingWindow.right && pos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
+ } else if (clippedPos.x <= _workingWindow.right && clippedPos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
if (mspeed <= 0)
mspeed = 400 >> 4;
- _mouseVelocity = (((pos.x - (_workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ _mouseVelocity = (((clippedPos.x - (_workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
_cursorManager->changeCursor(CursorIndex_Right);
cursorWasChanged = true;
@@ -311,21 +315,21 @@ void ZVision::onMouseMove(const Common::Point &pos) {
_mouseVelocity = 0;
}
} else if (renderState == RenderTable::TILT) {
- if (pos.y >= _workingWindow.top && pos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
+ if (clippedPos.y >= _workingWindow.top && clippedPos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
if (mspeed <= 0)
mspeed = 400 >> 4;
- _mouseVelocity = (((pos.y - (_workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ _mouseVelocity = (((clippedPos.y - (_workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
_cursorManager->changeCursor(CursorIndex_UpArr);
cursorWasChanged = true;
- } else if (pos.y <= _workingWindow.bottom && pos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
+ } else if (clippedPos.y <= _workingWindow.bottom && clippedPos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
if (mspeed <= 0)
mspeed = 400 >> 4;
- _mouseVelocity = (((pos.y - (_workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ _mouseVelocity = (((clippedPos.y - (_workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
_cursorManager->changeCursor(CursorIndex_DownArr);
cursorWasChanged = true;
--
cgit v1.2.3
From b0e6c30ee288130d6b904a6f770044564b0490e6 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 00:45:34 +0200
Subject: ZVISION: Fix Venus key code handling in commit dfae161
---
engines/zvision/core/events.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 81ad28f29b..6e8cf1fe4f 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -148,7 +148,7 @@ void ZVision::cheatCodes(uint8 key) {
// Show the Venus screen when "?" or "/" is pressed while inside the temple world
if (_scriptManager->getStateValue(StateKey_VenusEnable) == 1)
- if ((checkCode("?") || checkCode("/")) && _scriptManager->getStateValue(StateKey_World) == 't')
+ if (getBufferedKey(0) == 0xBF && _scriptManager->getStateValue(StateKey_World) == 't')
_scriptManager->changeLocation('g', 'j', 'h', 'e', 0);
}
--
cgit v1.2.3
From 85644b887944dc4fc261827ae812a4e4684651bb Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 00:54:08 +0200
Subject: ZVISION: Prefix some class member variables with an underscore
---
engines/zvision/scripting/sidefx/ttytext_node.cpp | 6 +-
engines/zvision/text/text.cpp | 132 +++++++++++-----------
engines/zvision/text/text.h | 30 ++---
3 files changed, 84 insertions(+), 84 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/ttytext_node.cpp b/engines/zvision/scripting/sidefx/ttytext_node.cpp
index 9a7fa01649..2930118524 100644
--- a/engines/zvision/scripting/sidefx/ttytext_node.cpp
+++ b/engines/zvision/scripting/sidefx/ttytext_node.cpp
@@ -57,7 +57,7 @@ ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file
delete infile;
}
_img.create(_r.width(), _r.height(), _engine->_pixelFormat);
- _style.sharp = true;
+ _style._sharp = true;
_style.readAllStyle(_txtbuf);
_style.setFont(_fnt);
_engine->getScriptManager()->setStateValue(_key, 1);
@@ -96,7 +96,7 @@ bool ttyTextNode::process(uint32 deltaTimeInMillis) {
if (ret & TXT_RET_HASSTBOX) {
Common::String buf;
- buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_style.statebox));
+ buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_style._statebox));
for (uint8 j = 0; j < buf.size(); j++)
outchar(buf[j]);
@@ -158,7 +158,7 @@ void ttyTextNode::newline() {
}
void ttyTextNode::outchar(uint16 chr) {
- uint32 clr = _engine->_pixelFormat.RGBToColor(_style.red, _style.green, _style.blue);
+ uint32 clr = _engine->_pixelFormat.RGBToColor(_style._red, _style._green, _style._blue);
if (_dx + _fnt.getCharWidth(chr) > _r.width())
newline();
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index 406c36e5b0..08b57914c2 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -39,21 +39,21 @@
namespace ZVision {
cTxtStyle::cTxtStyle() {
- fontname = "Arial";
- blue = 255;
- green = 255;
- red = 255;
- bold = false;
- escapement = 0;
- italic = false;
- justify = TXT_JUSTIFY_LEFT;
- newline = false;
- size = 12;
- skipcolor = false;
- strikeout = false;
- underline = false;
- statebox = 0;
- sharp = false;
+ _fontname = "Arial";
+ _blue = 255;
+ _green = 255;
+ _red = 255;
+ _bold = false;
+ _escapement = 0;
+ _italic = false;
+ _justify = TXT_JUSTIFY_LEFT;
+ _newline = false;
+ _size = 12;
+ _skipcolor = false;
+ _strikeout = false;
+ _underline = false;
+ _statebox = 0;
+ _sharp = false;
}
txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
@@ -80,10 +80,10 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (_tmp.lastChar() == '"')
_tmp.deleteLastChar();
- fontname = _tmp;
+ _fontname = _tmp;
} else {
if (!tokenizer.empty())
- fontname = token;
+ _fontname = token;
}
retval |= TXT_RET_FNTCHG;
@@ -91,8 +91,8 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (blue != tmp) {
- blue = tmp;
+ if (_blue != tmp) {
+ _blue = tmp;
retval |= TXT_RET_FNTSTL;
}
}
@@ -100,8 +100,8 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (red != tmp) {
- red = tmp;
+ if (_red != tmp) {
+ _red = tmp;
retval |= TXT_RET_FNTSTL;
}
}
@@ -109,23 +109,23 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (green != tmp) {
- green = tmp;
+ if (_green != tmp) {
+ _green = tmp;
retval |= TXT_RET_FNTSTL;
}
}
} else if (token.matchString("newline", true)) {
if ((retval & TXT_RET_NEWLN) == 0)
- newline = 0;
+ _newline = 0;
- newline++;
+ _newline++;
retval |= TXT_RET_NEWLN;
} else if (token.matchString("point", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (size != tmp) {
- size = tmp;
+ if (_size != tmp) {
+ _size = tmp;
retval |= TXT_RET_FNTCHG;
}
}
@@ -133,19 +133,19 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- escapement = tmp;
+ _escapement = tmp;
}
} else if (token.matchString("italic", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (italic != true) {
- italic = true;
+ if (_italic != true) {
+ _italic = true;
retval |= TXT_RET_FNTSTL;
}
} else if (token.matchString("off", true)) {
- if (italic != false) {
- italic = false;
+ if (_italic != false) {
+ _italic = false;
retval |= TXT_RET_FNTSTL;
}
}
@@ -154,13 +154,13 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (underline != true) {
- underline = true;
+ if (_underline != true) {
+ _underline = true;
retval |= TXT_RET_FNTSTL;
}
} else if (token.matchString("off", true)) {
- if (underline != false) {
- underline = false;
+ if (_underline != false) {
+ _underline = false;
retval |= TXT_RET_FNTSTL;
}
}
@@ -169,13 +169,13 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (strikeout != true) {
- strikeout = true;
+ if (_strikeout != true) {
+ _strikeout = true;
retval |= TXT_RET_FNTSTL;
}
} else if (token.matchString("off", true)) {
- if (strikeout != false) {
- strikeout = false;
+ if (_strikeout != false) {
+ _strikeout = false;
retval |= TXT_RET_FNTSTL;
}
}
@@ -184,13 +184,13 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (bold != true) {
- bold = true;
+ if (_bold != true) {
+ _bold = true;
retval |= TXT_RET_FNTSTL;
}
} else if (token.matchString("off", true)) {
- if (bold != false) {
- bold = false;
+ if (_bold != false) {
+ _bold = false;
retval |= TXT_RET_FNTSTL;
}
}
@@ -199,9 +199,9 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- skipcolor = true;
+ _skipcolor = true;
} else if (token.matchString("off", true)) {
- skipcolor = false;
+ _skipcolor = false;
}
}
} else if (token.matchString("image", true)) {
@@ -209,18 +209,18 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
} else if (token.matchString("statebox", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
- statebox = atoi(token.c_str());
+ _statebox = atoi(token.c_str());
retval |= TXT_RET_HASSTBOX;
}
} else if (token.matchString("justify", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("center", true))
- justify = TXT_JUSTIFY_CENTER;
+ _justify = TXT_JUSTIFY_CENTER;
else if (token.matchString("left", true))
- justify = TXT_JUSTIFY_LEFT;
+ _justify = TXT_JUSTIFY_LEFT;
else if (token.matchString("right", true))
- justify = TXT_JUSTIFY_RIGHT;
+ _justify = TXT_JUSTIFY_RIGHT;
}
}
}
@@ -247,19 +247,19 @@ void cTxtStyle::readAllStyle(const Common::String &txt) {
void cTxtStyle::setFontStyle(StyledTTFont &font) {
uint tempStyle = 0;
- if (bold)
+ if (_bold)
tempStyle |= StyledTTFont::STTF_BOLD;
- if (italic)
+ if (_italic)
tempStyle |= StyledTTFont::STTF_ITALIC;
- if (underline)
+ if (_underline)
tempStyle |= StyledTTFont::STTF_UNDERLINE;
- if (strikeout)
+ if (_strikeout)
tempStyle |= StyledTTFont::STTF_STRIKEOUT;
- if (sharp)
+ if (_sharp)
tempStyle |= StyledTTFont::STTF_SHARP;
font.setStyle(tempStyle);
@@ -268,27 +268,27 @@ void cTxtStyle::setFontStyle(StyledTTFont &font) {
void cTxtStyle::setFont(StyledTTFont &font) {
uint tempStyle = 0;
- if (bold)
+ if (_bold)
tempStyle |= StyledTTFont::STTF_BOLD;
- if (italic)
+ if (_italic)
tempStyle |= StyledTTFont::STTF_ITALIC;
- if (underline)
+ if (_underline)
tempStyle |= StyledTTFont::STTF_UNDERLINE;
- if (strikeout)
+ if (_strikeout)
tempStyle |= StyledTTFont::STTF_STRIKEOUT;
- if (sharp)
+ if (_sharp)
tempStyle |= StyledTTFont::STTF_SHARP;
- font.loadFont(fontname, size, tempStyle);
+ font.loadFont(_fontname, _size, tempStyle);
}
Graphics::Surface *TextRenderer::render(StyledTTFont &fnt, const Common::String &txt, cTxtStyle &style) {
style.setFontStyle(fnt);
- uint32 clr = _engine->_pixelFormat.RGBToColor(style.red, style.green, style.blue);
+ uint32 clr = _engine->_pixelFormat.RGBToColor(style._red, style._green, style._blue);
return fnt.renderSolidText(txt, clr);
}
@@ -307,13 +307,13 @@ int32 TextRenderer::drawTxt(const Common::String &txt, cTxtStyle &fontStyle, Gra
dst.fillRect(Common::Rect(dst.w, dst.h), 0);
- uint32 clr = _engine->_pixelFormat.RGBToColor(fontStyle.red, fontStyle.green, fontStyle.blue);
+ uint32 clr = _engine->_pixelFormat.RGBToColor(fontStyle._red, fontStyle._green, fontStyle._blue);
int16 w;
w = font.getStringWidth(txt);
- drawTxtWithJustify(txt, font, clr, dst, 0, fontStyle.justify);
+ drawTxtWithJustify(txt, font, clr, dst, 0, fontStyle._justify);
return w;
}
@@ -352,7 +352,7 @@ void TextRenderer::drawTxtInOneLine(const Common::String &text, Graphics::Surfac
int16 prevbufspace = 0, prevtxtspace = 0;
while (i < stringlen) {
- TxtJustify[currentline] = style.justify;
+ TxtJustify[currentline] = style._justify;
if (text[i] == '<') {
int16 ret = 0;
@@ -396,7 +396,7 @@ void TextRenderer::drawTxtInOneLine(const Common::String &text, Graphics::Surfac
if (ret & TXT_RET_HASSTBOX) {
Common::String buf3;
- buf3 = Common::String::format("%d", _engine->getScriptManager()->getStateValue(style.statebox));
+ buf3 = Common::String::format("%d", _engine->getScriptManager()->getStateValue(style._statebox));
buf += buf3;
textPosition += buf3.size();
}
diff --git a/engines/zvision/text/text.h b/engines/zvision/text/text.h
index ecec3ccde6..c3c60f6b76 100644
--- a/engines/zvision/text/text.h
+++ b/engines/zvision/text/text.h
@@ -55,21 +55,21 @@ public:
void setFont(StyledTTFont &font);
public:
- Common::String fontname;
- txtJustify justify; // 0 - center, 1-left, 2-right
- int16 size;
- uint8 red; // 0-255
- uint8 green; // 0-255
- uint8 blue; // 0-255
- int8 newline;
- int8 escapement;
- bool italic;
- bool bold;
- bool underline;
- bool strikeout;
- bool skipcolor;
- int32 statebox;
- bool sharp;
+ Common::String _fontname;
+ txtJustify _justify; // 0 - center, 1-left, 2-right
+ int16 _size;
+ uint8 _red; // 0-255
+ uint8 _green; // 0-255
+ uint8 _blue; // 0-255
+ int8 _newline;
+ int8 _escapement;
+ bool _italic;
+ bool _bold;
+ bool _underline;
+ bool _strikeout;
+ bool _skipcolor;
+ int32 _statebox;
+ bool _sharp;
// char image ??
};
--
cgit v1.2.3
From c2d83d287faec2bdfd6fac7d665c156670c7b7f7 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 02:50:34 +0200
Subject: ZVISION: Allow dumping any file type via the new "dumpfiles" command
---
engines/zvision/core/console.cpp | 11 ++++++++---
engines/zvision/core/console.h | 2 +-
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index 0789f8d4fb..07d3114ec8 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -52,7 +52,7 @@ Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
registerCmd("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
registerCmd("location", WRAP_METHOD(Console, cmdLocation));
registerCmd("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
- registerCmd("dumpallscripts", WRAP_METHOD(Console, cmdDumpAllScripts));
+ registerCmd("dumpfiles", WRAP_METHOD(Console, cmdDumpFiles));
}
bool Console::cmdLoadVideo(int argc, const char **argv) {
@@ -237,12 +237,17 @@ bool Console::cmdDumpFile(int argc, const char **argv) {
return true;
}
-bool Console::cmdDumpAllScripts(int argc, const char **argv) {
+bool Console::cmdDumpFiles(int argc, const char **argv) {
Common::String fileName;
Common::SeekableReadStream *in;
+ if (argc != 2) {
+ debugPrintf("Use %s to dump all files with a specific extension\n", argv[0]);
+ return true;
+ }
+
SearchManager::MatchList fileList;
- _engine->getSearchManager()->listMembersWithExtension(fileList, "scr");
+ _engine->getSearchManager()->listMembersWithExtension(fileList, argv[1]);
for (SearchManager::MatchList::iterator iter = fileList.begin(); iter != fileList.end(); ++iter) {
fileName = iter->_value.name;
diff --git a/engines/zvision/core/console.h b/engines/zvision/core/console.h
index 7e27fe8f26..a7bd88ebc3 100644
--- a/engines/zvision/core/console.h
+++ b/engines/zvision/core/console.h
@@ -46,7 +46,7 @@ private:
bool cmdSetPanoramaScale(int argc, const char **argv);
bool cmdLocation(int argc, const char **argv);
bool cmdDumpFile(int argc, const char **argv);
- bool cmdDumpAllScripts(int argc, const char **argv);
+ bool cmdDumpFiles(int argc, const char **argv);
};
} // End of namespace ZVision
--
cgit v1.2.3
From f364756bcfa952e85c2111270ffda15c9809a4b8 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 02:52:55 +0200
Subject: ZVISION: Add support for GNU Freefont fonts. Also, cleanup font
loading
The Freefont fonts can just be dropped into the extras ScummVM folder,
to get the game working under non-Windows systems
---
engines/zvision/graphics/truetype_font.cpp | 145 +++++++++++------------------
1 file changed, 54 insertions(+), 91 deletions(-)
diff --git a/engines/zvision/graphics/truetype_font.cpp b/engines/zvision/graphics/truetype_font.cpp
index 2dbd7ca358..5c8aa03f6a 100644
--- a/engines/zvision/graphics/truetype_font.cpp
+++ b/engines/zvision/graphics/truetype_font.cpp
@@ -54,105 +54,68 @@ bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint st
}
bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
+ struct FontStyle {
+ const char *zorkFont;
+ const char *fontBase;
+ const char *freeFontBase;
+ const char *freeFontItalicName;
+ };
+
+ const FontStyle systemFonts[] = {
+ { "*times new roman*", "times", "FreeSerif", "Italic" },
+ { "*times*", "times", "FreeSerif", "Italic" },
+ { "*century schoolbook*", "censcbk", "FreeSerif", "Italic" },
+ { "*garamond*", "gara", "FreeSerif", "Italic" },
+ { "*courier new*", "cour", "FreeMono", "Oblique" },
+ { "*courier*", "cour", "FreeMono", "Oblique" },
+ { "*ZorkDeath*", "cour", "FreeMono", "Oblique" },
+ { "*arial*", "arial", "FreeSans", "Oblique" },
+ { "*ZorkNormal*", "arial", "FreeSans", "Oblique" },
+ };
+
Common::String newFontName;
- if (fontName.matchString("*times new roman*", true) || fontName.matchString("*times*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "timesbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "timesbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "timesi.ttf";
- else
- newFontName = "times.ttf";
-
- } else if (fontName.matchString("*courier new*", true) || fontName.matchString("*courier*", true) || fontName.matchString("*ZorkDeath*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "courbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "courbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "couri.ttf";
- else
- newFontName = "cour.ttf";
-
- } else if (fontName.matchString("*century schoolbook*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "censcbkbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "censcbkbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "censcbki.ttf";
- else
- newFontName = "censcbk.ttf";
-
- } else if (fontName.matchString("*garamond*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "garabi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "garabd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "garai.ttf";
- else
- newFontName = "gara.ttf";
-
- } else if (fontName.matchString("*arial*", true) || fontName.matchString("*ZorkNormal*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "arialbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "arialbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "ariali.ttf";
- else
- newFontName = "arial.ttf";
+ Common::String freeFontName;
+
+ for (int i = 0; i < ARRAYSIZE(systemFonts); i++) {
+ if (fontName.matchString(systemFonts[i].zorkFont, true)) {
+ newFontName = systemFonts[i].fontBase;
+ freeFontName = systemFonts[i].freeFontBase;
+
+ if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
+ newFontName += "bi";
+ freeFontName += "Bold";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ } else if (_style & STTF_BOLD) {
+ newFontName += "bd";
+ freeFontName += "Bold";
+ } else if (_style & STTF_ITALIC) {
+ newFontName += "i";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ }
- } else {
+ newFontName += ".ttf";
+ freeFontName += ".ttf";
+ break;
+ }
+ }
+
+ if (newFontName.empty()) {
debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
newFontName = "arial.ttf";
+ freeFontName = "FreeSans.ttf";
}
bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
- Common::File *file = _engine->getSearchManager()->openFile(newFontName);
-
- if (!file) {
- Common::SeekableReadStream *themeFile = nullptr;
- if (ConfMan.hasKey("themepath")) {
- Common::FSNode themePath(ConfMan.get("themepath"));
- if (themePath.exists()) {
- Common::FSNode scummModern = themePath.getChild("scummmodern.zip");
- if (scummModern.exists()) {
- themeFile = scummModern.createReadStream();
- }
- }
- }
- if (!themeFile) { // Fallback : Search for ScummModern.zip in SearchMan.
- themeFile = SearchMan.createReadStreamForMember("scummmodern.zip");
- }
- if (themeFile) {
- Common::Archive *themeArchive = Common::makeZipArchive(themeFile);
- if (themeArchive->hasFile("FreeSans.ttf")) {
- Common::SeekableReadStream *stream = nullptr;
- stream = themeArchive->createReadStreamForMember("FreeSans.ttf");
- Graphics::Font *_newFont = Graphics::loadTTFFont(*stream, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
- if (_newFont) {
- if (!_font)
- delete _font;
- _font = _newFont;
- }
- if (stream)
- delete stream;
- }
- delete themeArchive;
- themeArchive = nullptr;
- }
- } else {
- Graphics::Font *_newFont = Graphics::loadTTFFont(*file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
- if (_newFont) {
- if (!_font)
- delete _font;
- _font = _newFont;
- }
- delete file;
+ Common::File file;
+ if (!file.open(newFontName) && !file.open(freeFontName))
+ error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
+
+ Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
+ if (_newFont) {
+ if (!_font)
+ delete _font;
+ _font = _newFont;
}
_fntName = fontName;
--
cgit v1.2.3
From b51852c641cf4d558d035d7d1dd9309d6d238647 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 02:58:18 +0200
Subject: ZVISION: Error out when the game string file isn't found
---
engines/zvision/text/string_manager.cpp | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/engines/zvision/text/string_manager.cpp b/engines/zvision/text/string_manager.cpp
index ec10b6220c..6b870d0b8d 100644
--- a/engines/zvision/text/string_manager.cpp
+++ b/engines/zvision/text/string_manager.cpp
@@ -43,21 +43,18 @@ StringManager::~StringManager() {
}
void StringManager::initialize(ZVisionGameId gameId) {
- if (gameId == GID_NEMESIS) {
- // TODO: Check this hardcoded filename against all versions of Nemesis
+ if (gameId == GID_NEMESIS)
loadStrFile("nemesis.str");
- } else if (gameId == GID_GRANDINQUISITOR) {
- // TODO: Check this hardcoded filename against all versions of Grand Inquisitor
+ else if (gameId == GID_GRANDINQUISITOR)
loadStrFile("inquis.str");
- }
}
void StringManager::loadStrFile(const Common::String &fileName) {
Common::File file;
if (!_engine->getSearchManager()->openFile(file, fileName)) {
- warning("%s does not exist. String parsing failed", fileName.c_str());
- return;
+ error("%s does not exist. String parsing failed", fileName.c_str());
}
+
uint lineNumber = 0;
while (!file.eos()) {
_lines[lineNumber] = readWideLine(file);
--
cgit v1.2.3
From b0250e72d88dcb5ddda17aa8e32efc71a4f0e4af Mon Sep 17 00:00:00 2001
From: Fedor
Date: Mon, 22 Dec 2014 19:55:10 +0300
Subject: VIDEO: Mark TheoraDecoder as used by pegasus
---
video/theora_decoder.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/video/theora_decoder.h b/video/theora_decoder.h
index b85388426b..feb4c6b49e 100644
--- a/video/theora_decoder.h
+++ b/video/theora_decoder.h
@@ -50,6 +50,7 @@ namespace Video {
*
* Decoder for Theora videos.
* Video decoder used in engines:
+ * - pegasus
* - sword25
* - wintermute
*/
--
cgit v1.2.3
From 04bc635dc702606911b8777a443b9e1f6322a6bf Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 22 Dec 2014 19:05:56 +0100
Subject: ACCESS: Remove a couple of unused variables in CharManager
---
engines/access/char.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/engines/access/char.h b/engines/access/char.h
index e89cdae49f..6fb4934978 100644
--- a/engines/access/char.h
+++ b/engines/access/char.h
@@ -51,11 +51,8 @@ private:
void charMenu();
public:
Common::Array _charTable;
- int _converseMode;
int _charFlag;
- // Fields that are included in savegames
- int _conversation;
public:
CharManager(AccessEngine *vm);
--
cgit v1.2.3
From fc9595efdc22aecb77800dca29fbe23291855c48 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 22 Dec 2014 19:16:11 +0100
Subject: ACCESS: Remove an unused variable in Animation manager
---
engines/access/animation.cpp | 5 +----
engines/access/animation.h | 1 -
2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/engines/access/animation.cpp b/engines/access/animation.cpp
index cc699a27e3..14d7c0d4cc 100644
--- a/engines/access/animation.cpp
+++ b/engines/access/animation.cpp
@@ -63,7 +63,6 @@ Animation::Animation(AccessEngine *vm, Common::SeekableReadStream *stream) : Man
_countdownTicks = stream->readUint16LE();
_currentLoopCount = stream->readSint16LE();
stream->readUint16LE(); // unk
- _field10 = 0;
Common::Array frameOffsets;
uint16 ofs;
@@ -311,9 +310,7 @@ Animation *AnimationManager::setAnimation(int animId) {
anim->_countdownTicks = anim->_initialTicks;
anim->_frameNumber = 0;
- anim->_currentLoopCount = (anim->_type != 3 && anim->_type != 4) ? 0 :
- anim->_loopCount;
- anim->_field10 = 0;
+ anim->_currentLoopCount = (anim->_type != 3 && anim->_type != 4) ? 0 : anim->_loopCount;
return anim;
}
diff --git a/engines/access/animation.h b/engines/access/animation.h
index 722f5430ab..72621c4d11 100644
--- a/engines/access/animation.h
+++ b/engines/access/animation.h
@@ -106,7 +106,6 @@ public:
int _loopCount;
int _countdownTicks;
int _currentLoopCount;
- int _field10;
public:
Animation(AccessEngine *vm, Common::SeekableReadStream *stream);
~Animation();
--
cgit v1.2.3
From d1bc69426eac2458b46ab7fede31c6dd71314ccb Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 22 Dec 2014 19:41:40 +0100
Subject: ACCESS: Move variable from Room manager to local function
---
engines/access/room.cpp | 6 +++---
engines/access/room.h | 1 -
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index f7c2eabd0f..607259ec6f 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -370,9 +370,9 @@ void Room::loadPlayField(int fileNum, int subfile) {
screen.loadRawPalette(playData->_stream);
// Copy off the tile data
- _tileSize = (int)header[2] << 8;
- _tile = new byte[_tileSize];
- playData->_stream->read(_tile, _tileSize);
+ int tileSize = (int)header[2] << 8;
+ _tile = new byte[tileSize];
+ playData->_stream->read(_tile, tileSize);
// Copy off the playfield data
_matrixSize = header[0] * header[1];
diff --git a/engines/access/room.h b/engines/access/room.h
index 44279fa6b1..eec273e3f4 100644
--- a/engines/access/room.h
+++ b/engines/access/room.h
@@ -124,7 +124,6 @@ public:
int _playFieldWidth;
int _playFieldHeight;
byte *_tile;
- int _tileSize;
int _selectCommand;
bool _conFlag;
public:
--
cgit v1.2.3
From 58f7c12fa941265a79b453df9b32ec41c49d53c4 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 22:11:07 +0200
Subject: ZVISION: Remove dead code
---
engines/zvision/graphics/render_table.cpp | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/engines/zvision/graphics/render_table.cpp b/engines/zvision/graphics/render_table.cpp
index c30e0bd472..df73247344 100644
--- a/engines/zvision/graphics/render_table.cpp
+++ b/engines/zvision/graphics/render_table.cpp
@@ -81,27 +81,6 @@ const Common::Point RenderTable::convertWarpedCoordToFlatCoord(const Common::Poi
return newPoint;
}
-uint16 mixTwoRGB(uint16 colorOne, uint16 colorTwo, float percentColorOne) {
- assert(percentColorOne < 1.0f);
-
- float rOne = float((colorOne & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
- float rTwo = float((colorTwo & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
- float gOne = float((colorOne & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
- float gTwo = float((colorTwo & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
- float bOne = float((colorOne & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
- float bTwo = float((colorTwo & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
-
- float rFinal = rOne * percentColorOne + rTwo * (1.0f - percentColorOne);
- float gFinal = gOne * percentColorOne + gTwo * (1.0f - percentColorOne);
- float bFinal = bOne * percentColorOne + bTwo * (1.0f - percentColorOne);
-
- uint16 returnColor = (byte(rFinal + 0.5f) << Graphics::ColorMasks<555>::kRedShift) |
- (byte(gFinal + 0.5f) << Graphics::ColorMasks<555>::kGreenShift) |
- (byte(bFinal + 0.5f) << Graphics::ColorMasks<555>::kBlueShift);
-
- return returnColor;
-}
-
void RenderTable::mutateImage(uint16 *sourceBuffer, uint16 *destBuffer, uint32 destWidth, const Common::Rect &subRect) {
uint32 destOffset = 0;
--
cgit v1.2.3
From 4e60fa705fd22069565cdb17c907f91301a67dc5 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 22 Dec 2014 22:23:36 +0200
Subject: ZVISION: Fix regression from commit 3806aa4418
---
engines/zvision/scripting/sidefx/music_node.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/scripting/sidefx/music_node.cpp b/engines/zvision/scripting/sidefx/music_node.cpp
index 56598189f6..6be08b46dc 100644
--- a/engines/zvision/scripting/sidefx/music_node.cpp
+++ b/engines/zvision/scripting/sidefx/music_node.cpp
@@ -88,7 +88,7 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool
}
MusicNode::~MusicNode() {
- if (!_loaded)
+ if (_loaded)
_engine->_mixer->stopHandle(_handle);
if (_key != StateKey_NotSet)
_engine->getScriptManager()->setStateValue(_key, 2);
--
cgit v1.2.3
From 3f36cc94e45d32dc4784c16ec91b6fc44dbf0ff7 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 00:02:30 +0200
Subject: ZVISION: Limit the default engine delay for all animations
This fixes the lag between frames for all in-game animations
with a default frame delay
---
engines/zvision/scripting/actions.cpp | 7 +++----
engines/zvision/scripting/sidefx/animation_node.cpp | 18 +++++-------------
engines/zvision/scripting/sidefx/animation_node.h | 1 -
3 files changed, 8 insertions(+), 18 deletions(-)
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 0422a2c028..0ada2edf81 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -577,7 +577,7 @@ ActionPreloadAnimation::ActionPreloadAnimation(ZVision *engine, int32 slotkey, c
char fileName[25];
- // The two %*u are always 0 and dont seem to have a use
+ // The two %*u are usually 0 and dont seem to have a use
sscanf(line.c_str(), "%25s %*u %*u %d %d", fileName, &_mask, &_framerate);
if (_mask > 0) {
@@ -1030,9 +1030,8 @@ bool ActionSyncSound::execute() {
if (!(fx->getType() & SideFX::SIDEFX_ANIM))
return true;
- AnimationNode *animnode = (AnimationNode *)fx;
- if (animnode->getFrameDelay() > 200) // Hack for fix incorrect framedelay in some animpreload
- animnode->setNewFrameDelay(66); // ~15fps
+ if (((AnimationNode *)fx)->getFrameDelay() > 200)
+ warning("ActionSyncSound: animation frame delay is higher than 200");
_engine->getScriptManager()->addSideFX(new SyncSoundNode(_engine, _slotKey, _fileName, _syncto));
return true;
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 3a21227d1a..56f1fa3e49 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -42,6 +42,11 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S
_animation = engine->loadAnimation(fileName);
_frmDelay = 1000.0 / _animation->getDuration().framerate();
+ // WORKAROUND: We do not allow the engine to delay more than 66 msec
+ // per frame (15fps max)
+ if (_frmDelay > 66)
+ _frmDelay = 66;
+
if (frate > 0)
_frmDelay = 1000.0 / frate;
}
@@ -190,19 +195,6 @@ bool AnimationNode::stop() {
return false;
}
-void AnimationNode::setNewFrameDelay(int32 newDelay) {
- if (newDelay > 0) {
- PlayNodes::iterator it = _playList.begin();
- if (it != _playList.end()) {
- playnode *nod = &(*it);
- float percent = (float)nod->_delay / (float)_frmDelay;
- nod->_delay = percent * newDelay; // Scale to new max
- }
-
- _frmDelay = newDelay;
- }
-}
-
int32 AnimationNode::getFrameDelay() {
return _frmDelay;
}
diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/sidefx/animation_node.h
index 3adfd91f32..74941aa764 100644
--- a/engines/zvision/scripting/sidefx/animation_node.h
+++ b/engines/zvision/scripting/sidefx/animation_node.h
@@ -73,7 +73,6 @@ public:
bool stop();
- void setNewFrameDelay(int32 newDelay);
int32 getFrameDelay();
};
--
cgit v1.2.3
From fb924089fc5f6968f5c86fc780131f67268e8de6 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 00:07:17 +0200
Subject: ZVISION: Avoid using color masks for in-game animations
This fixes the transparency for some in-game animations. Since colors
can be truncated with color masks, and since accurate colors are
required for transparency, color masks can't be used. This fixes the
transparency of the in-game item examination interface in ZGI
---
engines/zvision/video/rlf_decoder.cpp | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index bdb5dc18bc..d51dee0c6a 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -30,8 +30,6 @@
#include "common/debug.h"
#include "common/endian.h"
-#include "graphics/colormasks.h"
-
namespace ZVision {
RLFDecoder::~RLFDecoder() {
@@ -62,7 +60,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
return;
}
- _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
+ _currentFrameBuffer.create(_width, _height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
_frameBufferByteSize = _width * _height * sizeof(uint16);
_frames = new Frame[_frameCount];
@@ -243,8 +241,10 @@ void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8
}
byte r, g, b;
- Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::RGBToColor >(r, g, b);
+ // NOTE: Color masks can't be used here, since accurate colors
+ // are required to handle transparency correctly
+ Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b);
+ uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b);
WRITE_UINT16(dest + destOffset, destColor);
sourceOffset += 2;
@@ -290,8 +290,10 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
}
byte r, g, b;
- Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::RGBToColor >(r, g, b);
+ // NOTE: Color masks can't be used here, since accurate colors
+ // are required to handle transparency correctly
+ Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b);
+ uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b);
WRITE_UINT16(dest + destOffset, destColor);
sourceOffset += 2;
@@ -307,8 +309,10 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
}
byte r, g, b;
- Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 sampleColor = Graphics::RGBToColor >(r, g, b);
+ // NOTE: Color masks can't be used here, since accurate colors
+ // are required to handle transparency correctly
+ Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b);
+ uint16 sampleColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b);
sourceOffset += 2;
numberOfCopy = numberOfSamples + 2;
--
cgit v1.2.3
From 9bc0686e6076bbe5ca481c6696f0f7d3c86cd570 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 00:09:18 +0200
Subject: ZVISION: Remove leftover warning
---
engines/zvision/scripting/actions.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 0ada2edf81..2a5046f146 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -1030,9 +1030,6 @@ bool ActionSyncSound::execute() {
if (!(fx->getType() & SideFX::SIDEFX_ANIM))
return true;
- if (((AnimationNode *)fx)->getFrameDelay() > 200)
- warning("ActionSyncSound: animation frame delay is higher than 200");
-
_engine->getScriptManager()->addSideFX(new SyncSoundNode(_engine, _slotKey, _fileName, _syncto));
return true;
}
--
cgit v1.2.3
From eb4645cda855b0ac919124fefc79c580883903d3 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 00:10:12 +0200
Subject: ZVISION: Spacing
---
engines/zvision/video/rlf_decoder.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index d51dee0c6a..b798093869 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -309,8 +309,8 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
}
byte r, g, b;
- // NOTE: Color masks can't be used here, since accurate colors
- // are required to handle transparency correctly
+ // NOTE: Color masks can't be used here, since accurate colors
+ // are required to handle transparency correctly
Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b);
uint16 sampleColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b);
sourceOffset += 2;
--
cgit v1.2.3
From cfd00ad6afc09ca6990ce905b1a8db4ea1ad1602 Mon Sep 17 00:00:00 2001
From: Pino Toscano
Date: Mon, 22 Dec 2014 22:39:05 +0100
Subject: AGI: use Common::String::format when possible
Use Common::String::format instead of a MAXPATHLEN-sized char[] buffer.
---
engines/agi/detection.cpp | 6 ++----
engines/agi/loader_v2.cpp | 8 ++++----
engines/agi/loader_v3.cpp | 3 +--
3 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index e7285d8112..3230b4e5d3 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -276,15 +276,13 @@ SaveStateList AgiMetaEngine::listSaves(const char *target) const {
int AgiMetaEngine::getMaximumSaveSlot() const { return 999; }
void AgiMetaEngine::removeSaveState(const char *target, int slot) const {
- char fileName[MAXPATHLEN];
- sprintf(fileName, "%s.%03d", target, slot);
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
g_system->getSavefileManager()->removeSavefile(fileName);
}
SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
const uint32 AGIflag = MKTAG('A','G','I',':');
- char fileName[MAXPATHLEN];
- sprintf(fileName, "%s.%03d", target, slot);
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
diff --git a/engines/agi/loader_v2.cpp b/engines/agi/loader_v2.cpp
index 787eeaa0c7..3f164b7fc0 100644
--- a/engines/agi/loader_v2.cpp
+++ b/engines/agi/loader_v2.cpp
@@ -135,13 +135,13 @@ int AgiLoader_v2::unloadResource(int t, int n) {
*/
uint8 *AgiLoader_v2::loadVolRes(struct AgiDir *agid) {
uint8 *data = NULL;
- char x[MAXPATHLEN], *path;
+ char x[MAXPATHLEN];
Common::File fp;
unsigned int sig;
+ Common::String path;
- sprintf(x, "vol.%i", agid->volume);
- path = x;
- debugC(3, kDebugLevelResources, "Vol res: path = %s", path);
+ path = Common::String::format("vol.%i", agid->volume);
+ debugC(3, kDebugLevelResources, "Vol res: path = %s", path.c_str());
if (agid->offset != _EMPTY && fp.open(path)) {
debugC(3, kDebugLevelResources, "loading resource at offset %d", agid->offset);
diff --git a/engines/agi/loader_v3.cpp b/engines/agi/loader_v3.cpp
index fa135e5476..b90c17a1f3 100644
--- a/engines/agi/loader_v3.cpp
+++ b/engines/agi/loader_v3.cpp
@@ -204,8 +204,7 @@ uint8 *AgiLoader_v3::loadVolRes(AgiDir *agid) {
Common::String path;
debugC(3, kDebugLevelResources, "(%p)", (void *)agid);
- sprintf(x, "vol.%i", agid->volume);
- path = Common::String(_vm->_game.name) + x;
+ path = Common::String::format("%svol.%i", _vm->_game.name, agid->volume);
if (agid->offset != _EMPTY && fp.open(path)) {
fp.seek(agid->offset, SEEK_SET);
--
cgit v1.2.3
From e8fd25e22f4bce6f6df1a49115ece58bc76bdda3 Mon Sep 17 00:00:00 2001
From: Pino Toscano
Date: Mon, 22 Dec 2014 22:43:46 +0100
Subject: DRASCULA: use Common::String::format when possible
Use Common::String::format instead of a MAXPATHLEN-sized char[] buffer.
---
engines/drascula/detection.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 833363669d..a84bd11cb1 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -382,8 +382,7 @@ SaveStateList DrasculaMetaEngine::listSaves(const char *target) const {
}
SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
- char fileName[MAXPATHLEN];
- sprintf(fileName, "%s.%03d", target, slot);
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
--
cgit v1.2.3
From f29b3658b0caa7af2a3972de09069b9ba80eb494 Mon Sep 17 00:00:00 2001
From: Pino Toscano
Date: Mon, 22 Dec 2014 22:46:52 +0100
Subject: AGI: use shorter sizes for buffers
Instead of allocate them with MAXPATHLEN as size, just give them the
size for the data that are going to be written on them.
---
engines/agi/loader_v2.cpp | 2 +-
engines/agi/loader_v3.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/engines/agi/loader_v2.cpp b/engines/agi/loader_v2.cpp
index 3f164b7fc0..693c53c2bf 100644
--- a/engines/agi/loader_v2.cpp
+++ b/engines/agi/loader_v2.cpp
@@ -135,7 +135,7 @@ int AgiLoader_v2::unloadResource(int t, int n) {
*/
uint8 *AgiLoader_v2::loadVolRes(struct AgiDir *agid) {
uint8 *data = NULL;
- char x[MAXPATHLEN];
+ char x[6];
Common::File fp;
unsigned int sig;
Common::String path;
diff --git a/engines/agi/loader_v3.cpp b/engines/agi/loader_v3.cpp
index b90c17a1f3..39759b4649 100644
--- a/engines/agi/loader_v3.cpp
+++ b/engines/agi/loader_v3.cpp
@@ -198,7 +198,7 @@ int AgiLoader_v3::unloadResource(int t, int n) {
* NULL is returned if unsucsessful.
*/
uint8 *AgiLoader_v3::loadVolRes(AgiDir *agid) {
- char x[MAXPATHLEN];
+ char x[8];
uint8 *data = NULL, *compBuffer;
Common::File fp;
Common::String path;
--
cgit v1.2.3
From 6a53c7cac10294d022e3eb5d47142ad46ef29bd9 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 01:45:44 +0200
Subject: ZVISION: Ignore the special 0xCCCC character in subtitles
This seems to be used as a newline character
---
engines/zvision/text/text.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index 08b57914c2..4ea40a1d55 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -495,7 +495,7 @@ Common::String readWideLine(Common::SeekableReadStream &stream) {
} else if (value >= 0x80 && value < 0x800) {
asciiString += (char)(0xC0 | ((value >> 6) & 0x1F));
asciiString += (char)(0x80 | (value & 0x3F));
- } else if (value >= 0x800 && value < 0x10000) {
+ } else if (value >= 0x800 && value < 0x10000 && value != 0xCCCC) {
asciiString += (char)(0xE0 | ((value >> 12) & 0xF));
asciiString += (char)(0x80 | ((value >> 6) & 0x3F));
asciiString += (char)(0x80 | (value & 0x3F));
--
cgit v1.2.3
From 15154641ac5ea674a4865d9478074cf1b1d8a36b Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 01:53:40 +0200
Subject: ZVISION: Move all of the text related code together
---
engines/zvision/graphics/render_manager.h | 2 +-
engines/zvision/graphics/subtitles.cpp | 108 ----------
engines/zvision/graphics/subtitles.h | 54 -----
engines/zvision/graphics/truetype_font.cpp | 228 ----------------------
engines/zvision/graphics/truetype_font.h | 84 --------
engines/zvision/module.mk | 4 +-
engines/zvision/scripting/sidefx/music_node.h | 2 +-
engines/zvision/scripting/sidefx/syncsound_node.h | 2 +-
engines/zvision/scripting/sidefx/ttytext_node.h | 2 +-
engines/zvision/text/string_manager.h | 2 +-
engines/zvision/text/subtitles.cpp | 108 ++++++++++
engines/zvision/text/subtitles.h | 54 +++++
engines/zvision/text/text.cpp | 2 +-
engines/zvision/text/text.h | 2 +-
engines/zvision/text/truetype_font.cpp | 228 ++++++++++++++++++++++
engines/zvision/text/truetype_font.h | 84 ++++++++
engines/zvision/video/video.cpp | 2 +-
engines/zvision/zvision.cpp | 2 +-
18 files changed, 485 insertions(+), 485 deletions(-)
delete mode 100644 engines/zvision/graphics/subtitles.cpp
delete mode 100644 engines/zvision/graphics/subtitles.h
delete mode 100644 engines/zvision/graphics/truetype_font.cpp
delete mode 100644 engines/zvision/graphics/truetype_font.h
create mode 100644 engines/zvision/text/subtitles.cpp
create mode 100644 engines/zvision/text/subtitles.h
create mode 100644 engines/zvision/text/truetype_font.cpp
create mode 100644 engines/zvision/text/truetype_font.h
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index 29bbd8f411..711c607c7b 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -24,7 +24,7 @@
#define ZVISION_RENDER_MANAGER_H
#include "zvision/graphics/render_table.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "common/rect.h"
#include "common/hashmap.h"
diff --git a/engines/zvision/graphics/subtitles.cpp b/engines/zvision/graphics/subtitles.cpp
deleted file mode 100644
index d2c56f0991..0000000000
--- a/engines/zvision/graphics/subtitles.cpp
+++ /dev/null
@@ -1,108 +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 "zvision/graphics/render_manager.h"
-#include "zvision/graphics/subtitles.h"
-#include "zvision/file/search_manager.h"
-#include "zvision/text/text.h"
-
-namespace ZVision {
-
-Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
- _engine(engine),
- _areaId(-1),
- _subId(-1) {
- Common::File file;
- if (_engine->getSearchManager()->openFile(file, subname)) {
- while (!file.eos()) {
- Common::String str = file.readLine();
- if (str.lastChar() == '~')
- str.deleteLastChar();
-
- if (str.matchString("*Initialization*", true)) {
- // Not used
- } else if (str.matchString("*Rectangle*", true)) {
- int32 x1, y1, x2, y2;
- sscanf(str.c_str(), "%*[^:]:%d %d %d %d", &x1, &y1, &x2, &y2);
- Common::Rect rct = Common::Rect(x1, y1, x2, y2);
- _areaId = _engine->getRenderManager()->createSubArea(rct);
- } else if (str.matchString("*TextFile*", true)) {
- char filename[64];
- sscanf(str.c_str(), "%*[^:]:%s", filename);
- Common::File txt;
- if (_engine->getSearchManager()->openFile(txt, filename)) {
- while (!txt.eos()) {
- Common::String txtline = readWideLine(txt);
- sub curSubtitle;
- curSubtitle.start = -1;
- curSubtitle.stop = -1;
- curSubtitle.subStr = txtline;
-
- _subs.push_back(curSubtitle);
- }
- txt.close();
- }
- } else {
- int32 st;
- int32 en;
- int32 sb;
- if (sscanf(str.c_str(), "%*[^:]:(%d,%d)=%d", &st, &en, &sb) == 3) {
- if (sb <= (int32)_subs.size()) {
- _subs[sb].start = st;
- _subs[sb].stop = en;
- }
- }
- }
- }
- }
-}
-
-Subtitle::~Subtitle() {
- if (_areaId != -1)
- _engine->getRenderManager()->deleteSubArea(_areaId);
-
- _subs.clear();
-}
-
-void Subtitle::process(int32 time) {
- int16 j = -1;
- for (uint16 i = 0; i < _subs.size(); i++)
- if (time >= _subs[i].start && time <= _subs[i].stop) {
- j = i;
- break;
- }
-
- if (j == -1 && _subId != -1) {
- if (_areaId != -1)
- _engine->getRenderManager()->updateSubArea(_areaId, "");
- _subId = -1;
- }
-
- if (j != -1 && j != _subId) {
- if (_subs[j].subStr.size())
- if (_areaId != -1)
- _engine->getRenderManager()->updateSubArea(_areaId, _subs[j].subStr);
- _subId = j;
- }
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/graphics/subtitles.h b/engines/zvision/graphics/subtitles.h
deleted file mode 100644
index c3da6583a4..0000000000
--- a/engines/zvision/graphics/subtitles.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_SUBTITLES_H
-#define ZVISION_SUBTITLES_H
-
-#include "zvision/zvision.h"
-
-namespace ZVision {
-
-class ZVision;
-
-class Subtitle {
-public:
- Subtitle(ZVision *engine, const Common::String &subname);
- ~Subtitle();
-
- void process(int32 time);
-private:
- ZVision *_engine;
- int32 _areaId;
- int16 _subId;
-
- struct sub {
- int start;
- int stop;
- Common::String subStr;
- };
-
- Common::Array _subs;
-};
-
-}
-
-#endif
diff --git a/engines/zvision/graphics/truetype_font.cpp b/engines/zvision/graphics/truetype_font.cpp
deleted file mode 100644
index 5c8aa03f6a..0000000000
--- a/engines/zvision/graphics/truetype_font.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-#include "common/config-manager.h"
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/system.h"
-#include "common/unzip.h"
-#include "graphics/font.h"
-#include "graphics/fonts/ttf.h"
-#include "graphics/surface.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/truetype_font.h"
-
-namespace ZVision {
-
-StyledTTFont::StyledTTFont(ZVision *engine) {
- _engine = engine;
- _style = 0;
- _font = NULL;
- _lineHeight = 0;
-}
-
-StyledTTFont::~StyledTTFont() {
- if (_font)
- delete _font;
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
- _style = style;
- return loadFont(fontName, point);
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
- struct FontStyle {
- const char *zorkFont;
- const char *fontBase;
- const char *freeFontBase;
- const char *freeFontItalicName;
- };
-
- const FontStyle systemFonts[] = {
- { "*times new roman*", "times", "FreeSerif", "Italic" },
- { "*times*", "times", "FreeSerif", "Italic" },
- { "*century schoolbook*", "censcbk", "FreeSerif", "Italic" },
- { "*garamond*", "gara", "FreeSerif", "Italic" },
- { "*courier new*", "cour", "FreeMono", "Oblique" },
- { "*courier*", "cour", "FreeMono", "Oblique" },
- { "*ZorkDeath*", "cour", "FreeMono", "Oblique" },
- { "*arial*", "arial", "FreeSans", "Oblique" },
- { "*ZorkNormal*", "arial", "FreeSans", "Oblique" },
- };
-
- Common::String newFontName;
- Common::String freeFontName;
-
- for (int i = 0; i < ARRAYSIZE(systemFonts); i++) {
- if (fontName.matchString(systemFonts[i].zorkFont, true)) {
- newFontName = systemFonts[i].fontBase;
- freeFontName = systemFonts[i].freeFontBase;
-
- if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
- newFontName += "bi";
- freeFontName += "Bold";
- freeFontName += systemFonts[i].freeFontItalicName;
- } else if (_style & STTF_BOLD) {
- newFontName += "bd";
- freeFontName += "Bold";
- } else if (_style & STTF_ITALIC) {
- newFontName += "i";
- freeFontName += systemFonts[i].freeFontItalicName;
- }
-
- newFontName += ".ttf";
- freeFontName += ".ttf";
- break;
- }
- }
-
- if (newFontName.empty()) {
- debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
- newFontName = "arial.ttf";
- freeFontName = "FreeSans.ttf";
- }
-
- bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
-
- Common::File file;
- if (!file.open(newFontName) && !file.open(freeFontName))
- error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
-
- Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
- if (_newFont) {
- if (!_font)
- delete _font;
- _font = _newFont;
- }
-
- _fntName = fontName;
- _lineHeight = point;
-
- if (_font)
- return true;
- return false;
-}
-
-void StyledTTFont::setStyle(uint newStyle) {
- if ((_style & (STTF_BOLD | STTF_ITALIC | STTF_SHARP)) != (newStyle & (STTF_BOLD | STTF_ITALIC | STTF_SHARP))) {
- _style = newStyle;
- loadFont(_fntName, _lineHeight);
- } else {
- _style = newStyle;
- }
-}
-
-int StyledTTFont::getFontHeight() {
- if (_font)
- return _font->getFontHeight();
- return 0;
-}
-
-int StyledTTFont::getMaxCharWidth() {
- if (_font)
- return _font->getMaxCharWidth();
- return 0;
-}
-
-int StyledTTFont::getCharWidth(byte chr) {
- if (_font)
- return _font->getCharWidth(chr);
- return 0;
-}
-
-int StyledTTFont::getKerningOffset(byte left, byte right) {
- if (_font)
- return _font->getKerningOffset(left, right);
- return 0;
-}
-
-void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
- if (_font) {
- _font->drawChar(dst, chr, x, y, color);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- }
-}
-
-void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
- if (_font) {
- _font->drawString(dst, str, x, y, w, color, align);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- }
-}
-
-int StyledTTFont::getStringWidth(const Common::String &str) {
- if (_font)
- return _font->getStringWidth(str);
- return 0;
-}
-
-Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
- Graphics::Surface *tmp = new Graphics::Surface;
- if (_font) {
- int16 w = _font->getStringWidth(str);
- if (w && w < 1024) {
- tmp->create(w, _font->getFontHeight(), _engine->_pixelFormat);
- drawString(tmp, str, 0, 0, w, color);
- }
- }
- return tmp;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/graphics/truetype_font.h b/engines/zvision/graphics/truetype_font.h
deleted file mode 100644
index b5fac4af8a..0000000000
--- a/engines/zvision/graphics/truetype_font.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// This file is based on engines/wintermute/base/fonts/base_font_truetype.h/.cpp
-
-#ifndef ZVISION_TRUETYPE_FONT_H
-#define ZVISION_TRUETYPE_FONT_H
-
-#include "graphics/font.h"
-#include "graphics/pixelformat.h"
-
-namespace Graphics {
-struct Surface;
-}
-
-namespace ZVision {
-
-class ZVision;
-
-// Styled TTF
-class StyledTTFont {
-public:
- StyledTTFont(ZVision *engine);
- ~StyledTTFont();
-
- enum {
- STTF_BOLD = 1,
- STTF_ITALIC = 2,
- STTF_UNDERLINE = 4,
- STTF_STRIKEOUT = 8,
- STTF_SHARP = 16
- };
-
-private:
- ZVision *_engine;
- Graphics::Font *_font;
- int _lineHeight;
- uint _style;
- Common::String _fntName;
-
-public:
- bool loadFont(const Common::String &fontName, int32 point);
- bool loadFont(const Common::String &fontName, int32 point, uint style);
- void setStyle(uint newStyle);
-
- int getFontHeight();
- int getMaxCharWidth();
- int getCharWidth(byte chr);
- int getKerningOffset(byte left, byte right);
-
- void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color);
-
- void drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align = Graphics::kTextAlignLeft);
- int getStringWidth(const Common::String &str);
-
- Graphics::Surface *renderSolidText(const Common::String &str, uint32 color);
-
- bool isLoaded() {
- return _font != NULL;
- };
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 00652f0824..3ea31abe1b 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -17,8 +17,6 @@ MODULE_OBJS := \
graphics/effects/wave.o \
graphics/render_manager.o \
graphics/render_table.o \
- graphics/subtitles.o \
- graphics/truetype_font.o \
scripting/actions.o \
scripting/control.o \
scripting/controls/fist_control.o \
@@ -44,7 +42,9 @@ MODULE_OBJS := \
sound/midi.o \
sound/zork_raw.o \
text/string_manager.o \
+ text/subtitles.o \
text/text.o \
+ text/truetype_font.o \
video/rlf_decoder.o \
video/video.o \
video/zork_avi_decoder.o \
diff --git a/engines/zvision/scripting/sidefx/music_node.h b/engines/zvision/scripting/sidefx/music_node.h
index 09bdc3707e..8f4a46f3fc 100644
--- a/engines/zvision/scripting/sidefx/music_node.h
+++ b/engines/zvision/scripting/sidefx/music_node.h
@@ -25,7 +25,7 @@
#include "audio/mixer.h"
#include "zvision/scripting/sidefx.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/text/subtitles.h"
namespace Common {
class String;
diff --git a/engines/zvision/scripting/sidefx/syncsound_node.h b/engines/zvision/scripting/sidefx/syncsound_node.h
index 7cd02a8aef..5961fccab9 100644
--- a/engines/zvision/scripting/sidefx/syncsound_node.h
+++ b/engines/zvision/scripting/sidefx/syncsound_node.h
@@ -25,7 +25,7 @@
#include "audio/mixer.h"
#include "zvision/scripting/sidefx.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/text/subtitles.h"
namespace Common {
class String;
diff --git a/engines/zvision/scripting/sidefx/ttytext_node.h b/engines/zvision/scripting/sidefx/ttytext_node.h
index b6cbed3e34..26d9be8e77 100644
--- a/engines/zvision/scripting/sidefx/ttytext_node.h
+++ b/engines/zvision/scripting/sidefx/ttytext_node.h
@@ -28,7 +28,7 @@
#include "zvision/scripting/sidefx.h"
#include "zvision/text/text.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
namespace Common {
class String;
diff --git a/engines/zvision/text/string_manager.h b/engines/zvision/text/string_manager.h
index b77ad65040..f4564ee1ec 100644
--- a/engines/zvision/text/string_manager.h
+++ b/engines/zvision/text/string_manager.h
@@ -24,7 +24,7 @@
#define ZVISION_STRING_MANAGER_H
#include "zvision/detection.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
namespace Graphics {
class FontManager;
diff --git a/engines/zvision/text/subtitles.cpp b/engines/zvision/text/subtitles.cpp
new file mode 100644
index 0000000000..acf4c37c2f
--- /dev/null
+++ b/engines/zvision/text/subtitles.cpp
@@ -0,0 +1,108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/subtitles.h"
+#include "zvision/file/search_manager.h"
+#include "zvision/text/text.h"
+
+namespace ZVision {
+
+Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
+ _engine(engine),
+ _areaId(-1),
+ _subId(-1) {
+ Common::File file;
+ if (_engine->getSearchManager()->openFile(file, subname)) {
+ while (!file.eos()) {
+ Common::String str = file.readLine();
+ if (str.lastChar() == '~')
+ str.deleteLastChar();
+
+ if (str.matchString("*Initialization*", true)) {
+ // Not used
+ } else if (str.matchString("*Rectangle*", true)) {
+ int32 x1, y1, x2, y2;
+ sscanf(str.c_str(), "%*[^:]:%d %d %d %d", &x1, &y1, &x2, &y2);
+ Common::Rect rct = Common::Rect(x1, y1, x2, y2);
+ _areaId = _engine->getRenderManager()->createSubArea(rct);
+ } else if (str.matchString("*TextFile*", true)) {
+ char filename[64];
+ sscanf(str.c_str(), "%*[^:]:%s", filename);
+ Common::File txt;
+ if (_engine->getSearchManager()->openFile(txt, filename)) {
+ while (!txt.eos()) {
+ Common::String txtline = readWideLine(txt);
+ sub curSubtitle;
+ curSubtitle.start = -1;
+ curSubtitle.stop = -1;
+ curSubtitle.subStr = txtline;
+
+ _subs.push_back(curSubtitle);
+ }
+ txt.close();
+ }
+ } else {
+ int32 st;
+ int32 en;
+ int32 sb;
+ if (sscanf(str.c_str(), "%*[^:]:(%d,%d)=%d", &st, &en, &sb) == 3) {
+ if (sb <= (int32)_subs.size()) {
+ _subs[sb].start = st;
+ _subs[sb].stop = en;
+ }
+ }
+ }
+ }
+ }
+}
+
+Subtitle::~Subtitle() {
+ if (_areaId != -1)
+ _engine->getRenderManager()->deleteSubArea(_areaId);
+
+ _subs.clear();
+}
+
+void Subtitle::process(int32 time) {
+ int16 j = -1;
+ for (uint16 i = 0; i < _subs.size(); i++)
+ if (time >= _subs[i].start && time <= _subs[i].stop) {
+ j = i;
+ break;
+ }
+
+ if (j == -1 && _subId != -1) {
+ if (_areaId != -1)
+ _engine->getRenderManager()->updateSubArea(_areaId, "");
+ _subId = -1;
+ }
+
+ if (j != -1 && j != _subId) {
+ if (_subs[j].subStr.size())
+ if (_areaId != -1)
+ _engine->getRenderManager()->updateSubArea(_areaId, _subs[j].subStr);
+ _subId = j;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/text/subtitles.h b/engines/zvision/text/subtitles.h
new file mode 100644
index 0000000000..c3da6583a4
--- /dev/null
+++ b/engines/zvision/text/subtitles.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_SUBTITLES_H
+#define ZVISION_SUBTITLES_H
+
+#include "zvision/zvision.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class Subtitle {
+public:
+ Subtitle(ZVision *engine, const Common::String &subname);
+ ~Subtitle();
+
+ void process(int32 time);
+private:
+ ZVision *_engine;
+ int32 _areaId;
+ int16 _subId;
+
+ struct sub {
+ int start;
+ int stop;
+ Common::String subStr;
+ };
+
+ Common::Array _subs;
+};
+
+}
+
+#endif
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index 4ea40a1d55..91a06883b6 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -33,7 +33,7 @@
#include "zvision/text/text.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "zvision/scripting/script_manager.h"
namespace ZVision {
diff --git a/engines/zvision/text/text.h b/engines/zvision/text/text.h
index c3c60f6b76..c278b011c7 100644
--- a/engines/zvision/text/text.h
+++ b/engines/zvision/text/text.h
@@ -25,7 +25,7 @@
#define ZVISION_TEXT_H
#include "zvision/detection.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "zvision/zvision.h"
namespace ZVision {
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
new file mode 100644
index 0000000000..f373afe437
--- /dev/null
+++ b/engines/zvision/text/truetype_font.cpp
@@ -0,0 +1,228 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "common/unzip.h"
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
+#include "graphics/surface.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/truetype_font.h"
+
+namespace ZVision {
+
+StyledTTFont::StyledTTFont(ZVision *engine) {
+ _engine = engine;
+ _style = 0;
+ _font = NULL;
+ _lineHeight = 0;
+}
+
+StyledTTFont::~StyledTTFont() {
+ if (_font)
+ delete _font;
+}
+
+bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
+ _style = style;
+ return loadFont(fontName, point);
+}
+
+bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
+ struct FontStyle {
+ const char *zorkFont;
+ const char *fontBase;
+ const char *freeFontBase;
+ const char *freeFontItalicName;
+ };
+
+ const FontStyle systemFonts[] = {
+ { "*times new roman*", "times", "FreeSerif", "Italic" },
+ { "*times*", "times", "FreeSerif", "Italic" },
+ { "*century schoolbook*", "censcbk", "FreeSerif", "Italic" },
+ { "*garamond*", "gara", "FreeSerif", "Italic" },
+ { "*courier new*", "cour", "FreeMono", "Oblique" },
+ { "*courier*", "cour", "FreeMono", "Oblique" },
+ { "*ZorkDeath*", "cour", "FreeMono", "Oblique" },
+ { "*arial*", "arial", "FreeSans", "Oblique" },
+ { "*ZorkNormal*", "arial", "FreeSans", "Oblique" },
+ };
+
+ Common::String newFontName;
+ Common::String freeFontName;
+
+ for (int i = 0; i < ARRAYSIZE(systemFonts); i++) {
+ if (fontName.matchString(systemFonts[i].zorkFont, true)) {
+ newFontName = systemFonts[i].fontBase;
+ freeFontName = systemFonts[i].freeFontBase;
+
+ if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
+ newFontName += "bi";
+ freeFontName += "Bold";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ } else if (_style & STTF_BOLD) {
+ newFontName += "bd";
+ freeFontName += "Bold";
+ } else if (_style & STTF_ITALIC) {
+ newFontName += "i";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ }
+
+ newFontName += ".ttf";
+ freeFontName += ".ttf";
+ break;
+ }
+ }
+
+ if (newFontName.empty()) {
+ debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
+ newFontName = "arial.ttf";
+ freeFontName = "FreeSans.ttf";
+ }
+
+ bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
+
+ Common::File file;
+ if (!file.open(newFontName) && !file.open(freeFontName))
+ error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
+
+ Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
+ if (_newFont) {
+ if (!_font)
+ delete _font;
+ _font = _newFont;
+ }
+
+ _fntName = fontName;
+ _lineHeight = point;
+
+ if (_font)
+ return true;
+ return false;
+}
+
+void StyledTTFont::setStyle(uint newStyle) {
+ if ((_style & (STTF_BOLD | STTF_ITALIC | STTF_SHARP)) != (newStyle & (STTF_BOLD | STTF_ITALIC | STTF_SHARP))) {
+ _style = newStyle;
+ loadFont(_fntName, _lineHeight);
+ } else {
+ _style = newStyle;
+ }
+}
+
+int StyledTTFont::getFontHeight() {
+ if (_font)
+ return _font->getFontHeight();
+ return 0;
+}
+
+int StyledTTFont::getMaxCharWidth() {
+ if (_font)
+ return _font->getMaxCharWidth();
+ return 0;
+}
+
+int StyledTTFont::getCharWidth(byte chr) {
+ if (_font)
+ return _font->getCharWidth(chr);
+ return 0;
+}
+
+int StyledTTFont::getKerningOffset(byte left, byte right) {
+ if (_font)
+ return _font->getKerningOffset(left, right);
+ return 0;
+}
+
+void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
+ if (_font) {
+ _font->drawChar(dst, chr, x, y, color);
+ if (_style & STTF_UNDERLINE) {
+ int16 pos = floor(_font->getFontHeight() * 0.87);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ if (_style & STTF_STRIKEOUT) {
+ int16 pos = floor(_font->getFontHeight() * 0.60);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ }
+}
+
+void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
+ if (_font) {
+ _font->drawString(dst, str, x, y, w, color, align);
+ if (_style & STTF_UNDERLINE) {
+ int16 pos = floor(_font->getFontHeight() * 0.87);
+ int16 wd = MIN(_font->getStringWidth(str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ if (_style & STTF_STRIKEOUT) {
+ int16 pos = floor(_font->getFontHeight() * 0.60);
+ int16 wd = MIN(_font->getStringWidth(str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ }
+}
+
+int StyledTTFont::getStringWidth(const Common::String &str) {
+ if (_font)
+ return _font->getStringWidth(str);
+ return 0;
+}
+
+Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
+ Graphics::Surface *tmp = new Graphics::Surface;
+ if (_font) {
+ int16 w = _font->getStringWidth(str);
+ if (w && w < 1024) {
+ tmp->create(w, _font->getFontHeight(), _engine->_pixelFormat);
+ drawString(tmp, str, 0, 0, w, color);
+ }
+ }
+ return tmp;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/text/truetype_font.h b/engines/zvision/text/truetype_font.h
new file mode 100644
index 0000000000..b5fac4af8a
--- /dev/null
+++ b/engines/zvision/text/truetype_font.h
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// This file is based on engines/wintermute/base/fonts/base_font_truetype.h/.cpp
+
+#ifndef ZVISION_TRUETYPE_FONT_H
+#define ZVISION_TRUETYPE_FONT_H
+
+#include "graphics/font.h"
+#include "graphics/pixelformat.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+// Styled TTF
+class StyledTTFont {
+public:
+ StyledTTFont(ZVision *engine);
+ ~StyledTTFont();
+
+ enum {
+ STTF_BOLD = 1,
+ STTF_ITALIC = 2,
+ STTF_UNDERLINE = 4,
+ STTF_STRIKEOUT = 8,
+ STTF_SHARP = 16
+ };
+
+private:
+ ZVision *_engine;
+ Graphics::Font *_font;
+ int _lineHeight;
+ uint _style;
+ Common::String _fntName;
+
+public:
+ bool loadFont(const Common::String &fontName, int32 point);
+ bool loadFont(const Common::String &fontName, int32 point, uint style);
+ void setStyle(uint newStyle);
+
+ int getFontHeight();
+ int getMaxCharWidth();
+ int getCharWidth(byte chr);
+ int getKerningOffset(byte left, byte right);
+
+ void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color);
+
+ void drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align = Graphics::kTextAlignLeft);
+ int getStringWidth(const Common::String &str);
+
+ Graphics::Surface *renderSolidText(const Common::String &str, uint32 color);
+
+ bool isLoaded() {
+ return _font != NULL;
+ };
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 189fb22194..97fbd8721c 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -29,7 +29,7 @@
#include "zvision/zvision.h"
#include "zvision/core/clock.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/text/subtitles.h"
#include "zvision/video/rlf_decoder.h"
#include "zvision/video/zork_avi_decoder.h"
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index c32cceb26e..cf7ed288d7 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -33,7 +33,7 @@
#include "zvision/core/menu.h"
#include "zvision/file/search_manager.h"
#include "zvision/text/text.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "zvision/sound/midi.h"
#include "zvision/file/zfs_archive.h"
--
cgit v1.2.3
From 7aeeeabba9de168e76ae4d82b7f033fc877d0671 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 01:57:37 +0200
Subject: ZVISION: Add a comment about the special 0xCCCC character
---
engines/zvision/text/text.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index 91a06883b6..d1dc784f3e 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -499,6 +499,8 @@ Common::String readWideLine(Common::SeekableReadStream &stream) {
asciiString += (char)(0xE0 | ((value >> 12) & 0xF));
asciiString += (char)(0x80 | ((value >> 6) & 0x3F));
asciiString += (char)(0x80 | (value & 0x3F));
+ } else if (value == 0xCCCC) {
+ // Ignore, this character is used as newline sometimes
} else if (value >= 0x10000 && value < 0x200000) {
asciiString += (char)(0xF0);
asciiString += (char)(0x80 | ((value >> 12) & 0x3F));
--
cgit v1.2.3
From 99073f9b57580570b5ecec4cb00f020867f02672 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 02:20:17 +0200
Subject: ZVISION: Fix some buffer overruns with the usage of sscanf()
---
engines/zvision/scripting/actions.cpp | 18 +++++++++---------
engines/zvision/scripting/controls/input_control.cpp | 2 +-
engines/zvision/scripting/controls/lever_control.cpp | 4 ++--
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 2a5046f146..5af847c61a 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -363,7 +363,7 @@ ActionInventory::ActionInventory(ZVision *engine, int32 slotkey, const Common::S
_key = 0;
char buf[25];
- sscanf(line.c_str(), "%25s %d", buf, &_key);
+ sscanf(line.c_str(), "%24s %d", buf, &_key);
if (strcmp(buf, "add") == 0) {
_type = 0;
@@ -414,7 +414,7 @@ ActionKill::ActionKill(ZVision *engine, int32 slotkey, const Common::String &lin
_key = 0;
_type = 0;
char keytype[25];
- sscanf(line.c_str(), "%25s", keytype);
+ sscanf(line.c_str(), "%24s", keytype);
if (keytype[0] == '"') {
if (!scumm_stricmp(keytype, "\"ANIM\""))
_type = SideFX::SIDEFX_ANIM;
@@ -475,7 +475,7 @@ ActionMusic::ActionMusic(ZVision *engine, int32 slotkey, const Common::String &l
uint loop = 0;
uint volume = 255;
- sscanf(line.c_str(), "%u %25s %u %u", &type, fileNameBuffer, &loop, &volume);
+ sscanf(line.c_str(), "%u %24s %u %u", &type, fileNameBuffer, &loop, &volume);
// type 4 are midi sound effect files
if (type == 4) {
@@ -578,7 +578,7 @@ ActionPreloadAnimation::ActionPreloadAnimation(ZVision *engine, int32 slotkey, c
char fileName[25];
// The two %*u are usually 0 and dont seem to have a use
- sscanf(line.c_str(), "%25s %*u %*u %d %d", fileName, &_mask, &_framerate);
+ sscanf(line.c_str(), "%24s %*u %*u %d %d", fileName, &_mask, &_framerate);
if (_mask > 0) {
byte r, g, b;
@@ -645,7 +645,7 @@ ActionPlayAnimation::ActionPlayAnimation(ZVision *engine, int32 slotkey, const C
// The two %*u are always 0 and dont seem to have a use
sscanf(line.c_str(),
- "%25s %u %u %u %u %u %u %d %*u %*u %d %d",
+ "%24s %u %u %u %u %u %u %d %*u %*u %d %d",
fileName, &_x, &_y, &_x2, &_y2, &_start, &_end, &_loopCount, &_mask, &_framerate);
if (_mask > 0) {
@@ -863,7 +863,7 @@ ActionSetPartialScreen::ActionSetPartialScreen(ZVision *engine, int32 slotkey, c
char fileName[25];
int color;
- sscanf(line.c_str(), "%u %u %25s %*u %d", &_x, &_y, fileName, &color);
+ sscanf(line.c_str(), "%u %u %24s %*u %d", &_x, &_y, fileName, &color);
_fileName = Common::String(fileName);
@@ -907,7 +907,7 @@ bool ActionSetPartialScreen::execute() {
ActionSetScreen::ActionSetScreen(ZVision *engine, int32 slotkey, const Common::String &line) :
ResultAction(engine, slotkey) {
char fileName[25];
- sscanf(line.c_str(), "%25s", fileName);
+ sscanf(line.c_str(), "%24s", fileName);
_fileName = Common::String(fileName);
}
@@ -966,7 +966,7 @@ ActionStreamVideo::ActionStreamVideo(ZVision *engine, int32 slotkey, const Commo
char fileName[25];
uint skipline = 0; //skipline - render video with skip every second line, not skippable.
- sscanf(line.c_str(), "%25s %u %u %u %u %u %u", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skipline);
+ sscanf(line.c_str(), "%24s %u %u %u %u %u %u", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skipline);
_fileName = Common::String(fileName);
_skippable = true;
@@ -1017,7 +1017,7 @@ ActionSyncSound::ActionSyncSound(ZVision *engine, int32 slotkey, const Common::S
char fileName[25];
int notUsed = 0;
- sscanf(line.c_str(), "%d %d %25s", &_syncto, ¬Used, fileName);
+ sscanf(line.c_str(), "%d %d %24s", &_syncto, ¬Used, fileName);
_fileName = Common::String(fileName);
}
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index e75cc15743..d7734f6d7a 100644
--- a/engines/zvision/scripting/controls/input_control.cpp
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -96,7 +96,7 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre
} else if (param.matchString("cursor_animation", true)) {
char fileName[25];
- sscanf(values.c_str(), "%25s %*u", fileName);
+ sscanf(values.c_str(), "%24s %*u", fileName);
_animation = _engine->loadAnimation(fileName);
_frame = -1;
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
index 8faa18357c..bef51f0e91 100644
--- a/engines/zvision/scripting/controls/lever_control.cpp
+++ b/engines/zvision/scripting/controls/lever_control.cpp
@@ -64,12 +64,12 @@ LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStre
while (!stream.eos() && !line.contains('}')) {
if (param.matchString("descfile", true)) {
char levFileName[25];
- sscanf(values.c_str(), "%25s", levFileName);
+ sscanf(values.c_str(), "%24s", levFileName);
parseLevFile(levFileName);
} else if (param.matchString("cursor", true)) {
char cursorName[25];
- sscanf(values.c_str(), "%25s", cursorName);
+ sscanf(values.c_str(), "%24s", cursorName);
_cursor = _engine->getCursorManager()->getCursorId(Common::String(cursorName));
}
--
cgit v1.2.3
From 11cb47e89772ea59fc55d2801685d1a3505235a0 Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Tue, 23 Dec 2014 00:25:42 -0600
Subject: ZVISION: Remove unnecessary math
---
engines/zvision/core/events.cpp | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 6e8cf1fe4f..72e7f33266 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -296,18 +296,20 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (clippedPos.x >= _workingWindow.left && clippedPos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
_mouseVelocity = (((clippedPos.x - (ROTATION_SCREEN_EDGE_OFFSET + _workingWindow.left)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
_cursorManager->changeCursor(CursorIndex_Left);
cursorWasChanged = true;
} else if (clippedPos.x <= _workingWindow.right && clippedPos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
_mouseVelocity = (((clippedPos.x - (_workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
_cursorManager->changeCursor(CursorIndex_Right);
cursorWasChanged = true;
@@ -318,18 +320,20 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (clippedPos.y >= _workingWindow.top && clippedPos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
_mouseVelocity = (((clippedPos.y - (_workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
_cursorManager->changeCursor(CursorIndex_UpArr);
cursorWasChanged = true;
} else if (clippedPos.y <= _workingWindow.bottom && clippedPos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
_mouseVelocity = (((clippedPos.y - (_workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
_cursorManager->changeCursor(CursorIndex_DownArr);
cursorWasChanged = true;
--
cgit v1.2.3
From 6548300a4182e1dc805b390678df800b05d07554 Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Tue, 23 Dec 2014 00:27:53 -0600
Subject: ZVISION: Use Common::Rational to simplify fixed point math
---
engines/zvision/core/events.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 72e7f33266..ccd7772975 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -296,20 +296,21 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (clippedPos.x >= _workingWindow.left && clippedPos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- _mouseVelocity = (((clippedPos.x - (ROTATION_SCREEN_EDGE_OFFSET + _workingWindow.left)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
if (mspeed <= 0) {
mspeed = 25;
}
+ _mouseVelocity = ((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.left)) - mspeed).toInt();
+
_cursorManager->changeCursor(CursorIndex_Left);
cursorWasChanged = true;
} else if (clippedPos.x <= _workingWindow.right && clippedPos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- _mouseVelocity = (((clippedPos.x - (_workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
if (mspeed <= 0) {
mspeed = 25;
}
+ _mouseVelocity = (Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET)).toInt();
_cursorManager->changeCursor(CursorIndex_Right);
cursorWasChanged = true;
@@ -320,20 +321,20 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (clippedPos.y >= _workingWindow.top && clippedPos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- _mouseVelocity = (((clippedPos.y - (_workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
if (mspeed <= 0) {
mspeed = 25;
}
+ _mouseVelocity = ((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - mspeed).toInt();
_cursorManager->changeCursor(CursorIndex_UpArr);
cursorWasChanged = true;
} else if (clippedPos.y <= _workingWindow.bottom && clippedPos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- _mouseVelocity = (((clippedPos.y - (_workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
if (mspeed <= 0) {
mspeed = 25;
}
+ _mouseVelocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET)).toInt();
_cursorManager->changeCursor(CursorIndex_DownArr);
cursorWasChanged = true;
--
cgit v1.2.3
From 40bd4c485f9ab24e667e66a047214eb7dcef73e8 Mon Sep 17 00:00:00 2001
From: Adrian Astley
Date: Tue, 23 Dec 2014 00:38:44 -0600
Subject: ZVISION: Clamp the rotation velocity to never be zero
Before, if we set the in-game preferences to have very low rotation speed,
the velocity ends up always being 0 - 0.99
Hence, when we convert back to an int, everything gets truncated to zero.
Therefore, we clamp, in order to ensure the user can always move, no matter
which setting they use.
---
engines/zvision/core/events.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index ccd7772975..1920ffd769 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -299,7 +299,7 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (mspeed <= 0) {
mspeed = 25;
}
- _mouseVelocity = ((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.left)) - mspeed).toInt();
+ _mouseVelocity = MIN(((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.left)) - mspeed).toInt(), -1);
_cursorManager->changeCursor(CursorIndex_Left);
@@ -310,7 +310,7 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (mspeed <= 0) {
mspeed = 25;
}
- _mouseVelocity = (Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET)).toInt();
+ _mouseVelocity = MAX((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET)).toInt(), 1);
_cursorManager->changeCursor(CursorIndex_Right);
cursorWasChanged = true;
@@ -324,7 +324,7 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (mspeed <= 0) {
mspeed = 25;
}
- _mouseVelocity = ((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - mspeed).toInt();
+ _mouseVelocity = MIN(((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - mspeed).toInt(), -1);
_cursorManager->changeCursor(CursorIndex_UpArr);
cursorWasChanged = true;
@@ -334,7 +334,7 @@ void ZVision::onMouseMove(const Common::Point &pos) {
if (mspeed <= 0) {
mspeed = 25;
}
- _mouseVelocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET)).toInt();
+ _mouseVelocity = MAX((Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET)).toInt(), 1);
_cursorManager->changeCursor(CursorIndex_DownArr);
cursorWasChanged = true;
--
cgit v1.2.3
From 9f1fd0dbff6e1702f49708c8ef4cc91f3b44ca4e Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 11:03:02 +0200
Subject: ZVISION: Disable unused code
---
engines/zvision/text/text.cpp | 8 +++++++-
engines/zvision/text/text.h | 2 ++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index d1dc784f3e..53fcafd027 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -44,10 +44,12 @@ cTxtStyle::cTxtStyle() {
_green = 255;
_red = 255;
_bold = false;
+#if 0
+ _newline = false;
_escapement = 0;
+#endif
_italic = false;
_justify = TXT_JUSTIFY_LEFT;
- _newline = false;
_size = 12;
_skipcolor = false;
_strikeout = false;
@@ -115,10 +117,12 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
}
}
} else if (token.matchString("newline", true)) {
+#if 0
if ((retval & TXT_RET_NEWLN) == 0)
_newline = 0;
_newline++;
+#endif
retval |= TXT_RET_NEWLN;
} else if (token.matchString("point", true)) {
if (!tokenizer.empty()) {
@@ -132,8 +136,10 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
} else if (token.matchString("escapement", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
+#if 0
int32 tmp = atoi(token.c_str());
_escapement = tmp;
+#endif
}
} else if (token.matchString("italic", true)) {
if (!tokenizer.empty()) {
diff --git a/engines/zvision/text/text.h b/engines/zvision/text/text.h
index c278b011c7..c044e91579 100644
--- a/engines/zvision/text/text.h
+++ b/engines/zvision/text/text.h
@@ -61,8 +61,10 @@ public:
uint8 _red; // 0-255
uint8 _green; // 0-255
uint8 _blue; // 0-255
+#if 0
int8 _newline;
int8 _escapement;
+#endif
bool _italic;
bool _bold;
bool _underline;
--
cgit v1.2.3
From 490382098eb122e25aa895dc8de7330c22b1fcf8 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 11:06:39 +0200
Subject: ZVISION: Disable more unused code
---
engines/zvision/text/text.cpp | 4 ++++
engines/zvision/text/text.h | 2 ++
2 files changed, 6 insertions(+)
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index 53fcafd027..8ddba3fbab 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -51,7 +51,9 @@ cTxtStyle::cTxtStyle() {
_italic = false;
_justify = TXT_JUSTIFY_LEFT;
_size = 12;
+#if 0
_skipcolor = false;
+#endif
_strikeout = false;
_underline = false;
_statebox = 0;
@@ -204,11 +206,13 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
} else if (token.matchString("skipcolor", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
+#if 0
if (token.matchString("on", true)) {
_skipcolor = true;
} else if (token.matchString("off", true)) {
_skipcolor = false;
}
+#endif
}
} else if (token.matchString("image", true)) {
// Not used
diff --git a/engines/zvision/text/text.h b/engines/zvision/text/text.h
index c044e91579..c942b8141a 100644
--- a/engines/zvision/text/text.h
+++ b/engines/zvision/text/text.h
@@ -69,7 +69,9 @@ public:
bool _bold;
bool _underline;
bool _strikeout;
+#if 0
bool _skipcolor;
+#endif
int32 _statebox;
bool _sharp;
// char image ??
--
cgit v1.2.3
From e8cc098cd4303a959e69769eae2d37dd949d27d3 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 11:54:39 +0200
Subject: ZVISION: Limit the engine delay, even when a custom frame rate is set
---
engines/zvision/scripting/sidefx/animation_node.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 56f1fa3e49..4f26f039cc 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -42,13 +42,13 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S
_animation = engine->loadAnimation(fileName);
_frmDelay = 1000.0 / _animation->getDuration().framerate();
+ if (frate > 0)
+ _frmDelay = 1000.0 / frate;
+
// WORKAROUND: We do not allow the engine to delay more than 66 msec
// per frame (15fps max)
if (_frmDelay > 66)
_frmDelay = 66;
-
- if (frate > 0)
- _frmDelay = 1000.0 / frate;
}
AnimationNode::~AnimationNode() {
--
cgit v1.2.3
From 78ba3e32466992ee7d01aabff493617a6401273e Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 21:46:20 +0200
Subject: ZVISION: Add error checking when loading in-game animations and
videos
---
engines/zvision/video/rlf_decoder.cpp | 14 +++++++-------
engines/zvision/video/video.cpp | 7 ++++++-
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index b798093869..76fd70cf35 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -39,9 +39,13 @@ RLFDecoder::~RLFDecoder() {
bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
- addTrack(new RLFVideoTrack(stream));
-
- return true;
+ // Check if the stream is valid
+ if (stream && !stream->err() && stream->readUint32BE() == MKTAG('F', 'E', 'L', 'R')) {
+ addTrack(new RLFVideoTrack(stream));
+ return true;
+ } else {
+ return false;
+ }
}
RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
@@ -81,10 +85,6 @@ RLFDecoder::RLFVideoTrack::~RLFVideoTrack() {
}
bool RLFDecoder::RLFVideoTrack::readHeader() {
- if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {
- return false;
- }
-
// Read the header
_readStream->readUint32LE(); // Size1
_readStream->readUint32LE(); // Unknown1
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 97fbd8721c..50a6fc136a 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -48,7 +48,12 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) {
error("Unknown suffix for animation %s", fileName.c_str());
Common::File *_file = getSearchManager()->openFile(tmpFileName);
- animation->loadStream(_file);
+ if (!_file)
+ error("Error opening %s", tmpFileName.c_str());
+
+ bool loaded = animation->loadStream(_file);
+ if (!loaded)
+ error("Error loading animation %s", tmpFileName.c_str());
return animation;
}
--
cgit v1.2.3
From 6edc16b6863c3957efa5ad23596e904d89f8627c Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 21:54:53 +0200
Subject: ZVISION: Spacing
---
engines/zvision/scripting/sidefx/animation_node.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 4f26f039cc..134ab1396f 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -111,7 +111,6 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
}
if (frame) {
-
uint32 dstw;
uint32 dsth;
if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) {
--
cgit v1.2.3
From 6afeec129504a16ee67c77b35cd27f0808d566d2 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 23 Dec 2014 21:55:42 +0200
Subject: ZVISION: Handle animation rewinding outside the RLF encoder
---
engines/zvision/video/rlf_decoder.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index 76fd70cf35..f1ac10bf88 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -200,9 +200,8 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
}
const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() {
- // When an animation ends, rewind
if (_curFrame == (int)_frameCount)
- seek(Audio::Timestamp(0, getFrameRate().toInt()));
+ return NULL;
applyFrameToCurrent(_curFrame);
--
cgit v1.2.3
From 9948d3ca16ceff79dd3ccf6dde5024de04470f08 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 06:13:49 +0200
Subject: ZVISION: Add a hack to set the correct frame delay for RLF videos
Also, use Common::Rational to avoid using floating point math
---
engines/zvision/scripting/sidefx/animation_node.cpp | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 134ab1396f..1f62b61310 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -39,8 +39,20 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S
_mask(mask),
_animation(NULL) {
- _animation = engine->loadAnimation(fileName);
- _frmDelay = 1000.0 / _animation->getDuration().framerate();
+ if (fileName.hasSuffix(".rlf")) {
+ // HACK: Read the frame delay directly
+ Common::File *tmp = engine->getSearchManager()->openFile(fileName);
+ if (tmp) {
+ tmp->seek(176, SEEK_SET);
+ _frmDelay = tmp->readUint32LE() / 10;
+ delete tmp;
+ }
+
+ _animation = engine->loadAnimation(fileName);
+ } else {
+ _animation = engine->loadAnimation(fileName);
+ _frmDelay = Common::Rational(1000, _animation->getDuration().framerate()).toInt();
+ }
if (frate > 0)
_frmDelay = 1000.0 / frate;
--
cgit v1.2.3
From c93776e1e05bd5a683459831d61542c134d7b856 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 13:55:49 +0200
Subject: ZVISION: Remove dead code
---
engines/zvision/graphics/cursors/cursor.cpp | 29 -----------------------------
engines/zvision/graphics/cursors/cursor.h | 1 -
2 files changed, 30 deletions(-)
diff --git a/engines/zvision/graphics/cursors/cursor.cpp b/engines/zvision/graphics/cursors/cursor.cpp
index 07323b45c4..515358fe59 100644
--- a/engines/zvision/graphics/cursors/cursor.cpp
+++ b/engines/zvision/graphics/cursors/cursor.cpp
@@ -36,35 +36,6 @@ ZorkCursor::ZorkCursor()
_hotspotY(0) {
}
-ZorkCursor::ZorkCursor(const Common::String &fileName)
- : _width(0),
- _height(0),
- _hotspotX(0),
- _hotspotY(0) {
- Common::File file;
- if (!file.open(fileName))
- return;
-
- uint32 magic = file.readUint32BE();
- if (magic != MKTAG('Z', 'C', 'R', '1')) {
- warning("%s is not a Zork Cursor file", fileName.c_str());
- return;
- }
-
- _hotspotX = file.readUint16LE();
- _hotspotY = file.readUint16LE();
- _width = file.readUint16LE();
- _height = file.readUint16LE();
-
- uint dataSize = _width * _height * sizeof(uint16);
- _surface.create(_width, _height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
- uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
- assert(bytesRead == dataSize);
-
- // Convert to RGB 565
- _surface.convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
-}
-
ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
: _width(0),
_height(0),
diff --git a/engines/zvision/graphics/cursors/cursor.h b/engines/zvision/graphics/cursors/cursor.h
index 0c1e99411f..6e0083520a 100644
--- a/engines/zvision/graphics/cursors/cursor.h
+++ b/engines/zvision/graphics/cursors/cursor.h
@@ -39,7 +39,6 @@ namespace ZVision {
class ZorkCursor {
public:
ZorkCursor();
- ZorkCursor(const Common::String &fileName);
ZorkCursor(ZVision *engine, const Common::String &fileName);
ZorkCursor(const ZorkCursor &other);
~ZorkCursor();
--
cgit v1.2.3
From 702adaf9f807f19cd8849af737168461169734d3 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 14:04:56 +0200
Subject: ZVISION: Remove duplicate code
---
engines/zvision/graphics/render_manager.cpp | 91 +----------------------------
1 file changed, 1 insertion(+), 90 deletions(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index b9305f5dcc..2f0d2a3a2c 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -162,97 +162,8 @@ void RenderManager::renderImageToBackground(const Common::String &fileName, int1
}
void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination) {
- Common::File file;
-
- if (!_engine->getSearchManager()->openFile(file, fileName)) {
- warning("Could not open file %s", fileName.c_str());
- return;
- }
-
- // Read the magic number
- // Some files are true TGA, while others are TGZ
- uint32 fileType = file.readUint32BE();
-
- uint32 imageWidth;
- uint32 imageHeight;
- Image::TGADecoder tga;
- uint16 *buffer;
bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA;
- // All ZVision images are in RGB 555
- Graphics::PixelFormat pixelFormat555 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
- destination.format = pixelFormat555;
-
- bool isTGZ;
-
- // Check for TGZ files
- if (fileType == MKTAG('T', 'G', 'Z', '\0')) {
- isTGZ = true;
-
- // TGZ files have a header and then Bitmap data that is compressed with LZSS
- uint32 decompressedSize = file.readSint32LE();
- imageWidth = file.readSint32LE();
- imageHeight = file.readSint32LE();
-
- LzssReadStream lzssStream(&file);
- buffer = (uint16 *)(new uint16[decompressedSize]);
- lzssStream.read(buffer, decompressedSize);
- } else {
- isTGZ = false;
-
- // Reset the cursor
- file.seek(0);
-
- // Decode
- if (!tga.loadStream(file)) {
- warning("Error while reading TGA image");
- return;
- }
-
- Graphics::Surface tgaSurface = *(tga.getSurface());
- imageWidth = tgaSurface.w;
- imageHeight = tgaSurface.h;
-
- buffer = (uint16 *)tgaSurface.getPixels();
- }
-
- // Flip the width and height if transposed
- if (isTransposed) {
- uint16 temp = imageHeight;
- imageHeight = imageWidth;
- imageWidth = temp;
- }
-
- // If the destination internal buffer is the same size as what we're copying into it,
- // there is no need to free() and re-create
- if (imageWidth != destination.w || imageHeight != destination.h) {
- destination.create(imageWidth, imageHeight, pixelFormat555);
- }
-
- // If transposed, 'un-transpose' the data while copying it to the destination
- // Otherwise, just do a simple copy
- if (isTransposed) {
- uint16 *dest = (uint16 *)destination.getPixels();
-
- for (uint32 y = 0; y < imageHeight; ++y) {
- uint32 columnIndex = y * imageWidth;
-
- for (uint32 x = 0; x < imageWidth; ++x) {
- dest[columnIndex + x] = buffer[x * imageHeight + y];
- }
- }
- } else {
- memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * _pixelFormat.bytesPerPixel);
- }
-
- // Cleanup
- if (isTGZ) {
- delete[] buffer;
- } else {
- tga.destroy();
- }
-
- // Convert in place to RGB 565 from RGB 555
- destination.convertToInPlace(_pixelFormat);
+ readImageToSurface(fileName, destination, isTransposed);
}
void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed) {
--
cgit v1.2.3
From bed532587b4235a3cb9f2596bf7e65afdf33568a Mon Sep 17 00:00:00 2001
From: Matthew Hoops
Date: Wed, 24 Dec 2014 10:35:13 -0500
Subject: VIDEO: Fix check to see if the frame rate is a whole number
Thanks to Marisa-Chan for spotting
---
video/video_decoder.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index dce96aae03..a4bc5b81a2 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -530,7 +530,9 @@ Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getFrameTime(uint frame) con
// (which Audio::Timestamp doesn't support).
Common::Rational frameRate = getFrameRate();
- if (frameRate == frameRate.toInt()) // The nice case (a whole number)
+ // Try to keep it in terms of the frame rate, if the frame rate is a whole
+ // number.
+ if (frameRate.getDenominator() == 1)
return Audio::Timestamp(0, frame, frameRate.toInt());
// Convert as best as possible
--
cgit v1.2.3
From 59cd015fc90fcbb92c365ae33fe767cdf7ae863f Mon Sep 17 00:00:00 2001
From: Matthew Hoops
Date: Wed, 24 Dec 2014 10:36:55 -0500
Subject: SCI: Silence a gcc warning
---
engines/sci/graphics/screen.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 8b0e76332f..2f95bf7751 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -238,6 +238,8 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
_vectorPutPixelPtr = &GfxScreen::putPixelDisplayUpscaled;
_putPixelPtr = &GfxScreen::putPixelDisplayUpscaled;
break;
+ case GFX_SCREEN_UPSCALED_DISABLED:
+ break;
}
}
--
cgit v1.2.3
From 970116bc3821b38c9b4882178c6a34082e73698d Mon Sep 17 00:00:00 2001
From: Martin Kiewitz
Date: Wed, 24 Dec 2014 20:15:57 +0100
Subject: SCI: added LSL3/German 5 1/4" floppy version
---
engines/sci/detection_tables.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index d6bdef946b..7c9f54aedf 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -2069,6 +2069,20 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Larry 3 - German DOS (German+English, 5 1/4" floppies)
+ // SCI interpreter version S.old.124 (executable), VERSION is "1.056"
+ {"lsl3", "", {
+ {"resource.map", 0, "2468da5d664bb6ca3df866074a05e43c", 8910},
+ {"resource.001", 0, "3827a9b17b926e12dcc336860f50612a", 163326},
+ {"resource.002", 0, "3827a9b17b926e12dcc336860f50612a", 312436},
+ {"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 347307},
+ {"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 332369},
+ {"resource.005", 0, "3827a9b17b926e12dcc336860f50612a", 347654},
+ {"resource.006", 0, "3827a9b17b926e12dcc336860f50612a", 326011},
+ {"resource.007", 0, "3827a9b17b926e12dcc336860f50612a", 309553},
+ AD_LISTEND},
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Larry 3 - French DOS (provided by richiefs in bug report #2670691, also includes english language)
// Executable scanning reports "S.old.123"
// SCI interpreter version 0.000.572 (just a guess)
--
cgit v1.2.3
From 11d3227796a5d58a6e0f362e7982e27bf6d8fcd8 Mon Sep 17 00:00:00 2001
From: Martin Kiewitz
Date: Wed, 24 Dec 2014 20:20:39 +0100
Subject: SCI: fix typo in comment for LSL3/German
---
engines/sci/detection_tables.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 7c9f54aedf..32d1a58765 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -2070,7 +2070,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - German DOS (German+English, 5 1/4" floppies)
- // SCI interpreter version S.old.124 (executable), VERSION is "1.056"
+ // SCI interpreter version S.old.114 (executable), VERSION is "1.056"
{"lsl3", "", {
{"resource.map", 0, "2468da5d664bb6ca3df866074a05e43c", 8910},
{"resource.001", 0, "3827a9b17b926e12dcc336860f50612a", 163326},
--
cgit v1.2.3
From 16e208318cf75dbe290060663119d1c533f4dd7b Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 22:07:42 +0200
Subject: ZVISION: Plug a memory leak
---
engines/zvision/scripting/sidefx/animation_node.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 1f62b61310..bf3509f545 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -161,6 +161,7 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
_engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
else
_engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top);
+ transposed->free();
delete transposed;
} else {
if (_mask > 0)
--
cgit v1.2.3
From de2c9ed5bf9e3d41ad52de8aa0ddf383efa6b24d Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 22:11:21 +0200
Subject: ZVISION: Disable unused code
---
engines/zvision/graphics/render_manager.cpp | 2 ++
engines/zvision/graphics/render_manager.h | 4 +++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 2f0d2a3a2c..01df82410f 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -983,9 +983,11 @@ void RenderManager::markDirty() {
_backgroundDirtyRect = Common::Rect(_backgroundWidth, _backgroundHeight);
}
+#if 0
void RenderManager::bkgFill(uint8 r, uint8 g, uint8 b) {
_currentBackgroundImage.fillRect(Common::Rect(_currentBackgroundImage.w, _currentBackgroundImage.h), _currentBackgroundImage.format.RGBToColor(r, g, b));
markDirty();
}
+#endif
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index 711c607c7b..c2dc169945 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -328,8 +328,10 @@ public:
// Mark whole background surface as dirty
void markDirty();
- // Fille background surface by color
+#if 0
+ // Fill background surface by color
void bkgFill(uint8 r, uint8 g, uint8 b);
+#endif
};
} // End of namespace ZVision
--
cgit v1.2.3
From 1bc9b13357e36f6f52e3dd6f8223ab569e5b5362 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 22:26:23 +0200
Subject: ZVISION: Introduce pixel formats for resources (555) and screen (565)
---
engines/zvision/zvision.cpp | 8 +++++---
engines/zvision/zvision.h | 2 ++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index cf7ed288d7..145b2ebeac 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -82,6 +82,8 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
: Engine(syst),
_gameDescription(gameDesc),
_pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /*RGB 565*/
+ _resourcePixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /* RGB 555 */
+ _screenPixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /* RGB 565 */
_desiredFrameTime(33), /* ~30 fps */
_clock(_system),
_scriptManager(nullptr),
@@ -182,17 +184,17 @@ void ZVision::initialize() {
} else if (_gameDescription->gameId == GID_NEMESIS)
_searchManager->loadZix("NEMESIS.ZIX");
- initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_pixelFormat);
+ initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
// Register random source
_rnd = new Common::RandomSource("zvision");
// Create managers
_scriptManager = new ScriptManager(this);
- _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _pixelFormat);
+ _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _screenPixelFormat);
_saveManager = new SaveManager(this);
_stringManager = new StringManager(this);
- _cursorManager = new CursorManager(this, &_pixelFormat);
+ _cursorManager = new CursorManager(this, &_screenPixelFormat);
_textRenderer = new TextRenderer(this);
_midiManager = new MidiManager();
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 7ea10ed64d..a63b66f70f 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -69,6 +69,8 @@ public:
*/
Common::Rect _workingWindow;
const Graphics::PixelFormat _pixelFormat;
+ const Graphics::PixelFormat _resourcePixelFormat;
+ const Graphics::PixelFormat _screenPixelFormat;
private:
enum {
--
cgit v1.2.3
From 84341a889cfafc4c7ecef6cf7d6841df8353fe4b Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 22:29:52 +0200
Subject: ZVISION: Let the cursor manager do pixel format conversion for
cursors
---
engines/zvision/graphics/cursors/cursor.cpp | 5 +----
engines/zvision/graphics/cursors/cursor_manager.cpp | 2 +-
engines/zvision/graphics/cursors/cursor_manager.h | 4 ++--
engines/zvision/zvision.cpp | 2 +-
4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/engines/zvision/graphics/cursors/cursor.cpp b/engines/zvision/graphics/cursors/cursor.cpp
index 515358fe59..eb25e92860 100644
--- a/engines/zvision/graphics/cursors/cursor.cpp
+++ b/engines/zvision/graphics/cursors/cursor.cpp
@@ -57,12 +57,9 @@ ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
_height = file.readUint16LE();
uint dataSize = _width * _height * sizeof(uint16);
- _surface.create(_width, _height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+ _surface.create(_width, _height, engine->_resourcePixelFormat);
uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
assert(bytesRead == dataSize);
-
- // Convert to RGB 565
- _surface.convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
}
ZorkCursor::ZorkCursor(const ZorkCursor &other) {
diff --git a/engines/zvision/graphics/cursors/cursor_manager.cpp b/engines/zvision/graphics/cursors/cursor_manager.cpp
index 92fd461c72..a197c7ed87 100644
--- a/engines/zvision/graphics/cursors/cursor_manager.cpp
+++ b/engines/zvision/graphics/cursors/cursor_manager.cpp
@@ -45,7 +45,7 @@ const char *CursorManager::_zNemCursorFileNames[NUM_CURSORS] = { "00act", "arrow
"hright", "hup", "00idle", "left", "right", "ssurr", "stilt", "turn", "up"
};
-CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat)
+CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat pixelFormat)
: _engine(engine),
_pixelFormat(pixelFormat),
_cursorIsPushed(false),
diff --git a/engines/zvision/graphics/cursors/cursor_manager.h b/engines/zvision/graphics/cursors/cursor_manager.h
index bbfa085c23..35c605baf8 100644
--- a/engines/zvision/graphics/cursors/cursor_manager.h
+++ b/engines/zvision/graphics/cursors/cursor_manager.h
@@ -58,7 +58,7 @@ enum CursorIndex {
*/
class CursorManager {
public:
- CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat);
+ CursorManager(ZVision *engine, const Graphics::PixelFormat pixelFormat);
private:
static const int NUM_CURSORS = 18;
@@ -67,7 +67,7 @@ private:
ZorkCursor _cursors[NUM_CURSORS + 2][2];
ZVision *_engine;
- const Graphics::PixelFormat *_pixelFormat;
+ const Graphics::PixelFormat _pixelFormat;
bool _cursorIsPushed;
int _item;
int _lastitem;
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 145b2ebeac..5978316451 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -194,7 +194,7 @@ void ZVision::initialize() {
_renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _screenPixelFormat);
_saveManager = new SaveManager(this);
_stringManager = new StringManager(this);
- _cursorManager = new CursorManager(this, &_screenPixelFormat);
+ _cursorManager = new CursorManager(this, _resourcePixelFormat);
_textRenderer = new TextRenderer(this);
_midiManager = new MidiManager();
--
cgit v1.2.3
From e8e21fabe4dbe4effdfb3df05fd3fae75940f1c5 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 22:40:54 +0200
Subject: ZVISION: Set all the internal graphics operations to use RGB555 (1/2)
This is the first part of the changes to make the engine use RGB555
internally again. This is done to simplify the rendering pipeline -
the engine will use RGB555 internally, but will output to RGB565.
The overall changes have been broken into two commits, thus this
first commit will break all the game colors
---
engines/zvision/graphics/effect.h | 2 +-
engines/zvision/graphics/effects/fog.cpp | 10 ++++-----
engines/zvision/graphics/effects/light.cpp | 4 ++--
engines/zvision/scripting/actions.cpp | 25 ++--------------------
.../zvision/scripting/controls/input_control.cpp | 2 +-
.../zvision/scripting/controls/titler_control.cpp | 2 +-
engines/zvision/scripting/sidefx/ttytext_node.cpp | 4 ++--
engines/zvision/text/text.cpp | 4 ++--
engines/zvision/text/truetype_font.cpp | 2 +-
engines/zvision/video/rlf_decoder.cpp | 22 ++++---------------
engines/zvision/video/rlf_decoder.h | 2 +-
engines/zvision/zvision.cpp | 2 +-
12 files changed, 23 insertions(+), 58 deletions(-)
diff --git a/engines/zvision/graphics/effect.h b/engines/zvision/graphics/effect.h
index c6653c6037..234cd8209d 100644
--- a/engines/zvision/graphics/effect.h
+++ b/engines/zvision/graphics/effect.h
@@ -37,7 +37,7 @@ class Effect {
public:
Effect(ZVision *engine, uint32 key, Common::Rect region, bool ported) : _engine(engine), _key(key), _region(region), _ported(ported) {
- _surface.create(_region.width(), _region.height(), _engine->_pixelFormat);
+ _surface.create(_region.width(), _region.height(), _engine->_resourcePixelFormat);
}
virtual ~Effect() {}
diff --git a/engines/zvision/graphics/effects/fog.cpp b/engines/zvision/graphics/effects/fog.cpp
index f59e82a4a0..c28bdde330 100644
--- a/engines/zvision/graphics/effects/fog.cpp
+++ b/engines/zvision/graphics/effects/fog.cpp
@@ -79,10 +79,10 @@ const Graphics::Surface *FogFx::draw(const Graphics::Surface &srcSubRect) {
if (it->inEffect) {
// Not 100% equivalent, but looks nice and not buggy
uint8 sr, sg, sb;
- _engine->_pixelFormat.colorToRGB(lineBuf[i], sr, sg, sb);
+ _engine->_resourcePixelFormat.colorToRGB(lineBuf[i], sr, sg, sb);
uint16 fogColor = *(uint16 *)_fog.getBasePtr((i + _pos) % _fog.w, j);
uint8 dr, dg, db;
- _engine->_pixelFormat.colorToRGB(_colorMap[fogColor & 0x1F], dr, dg, db);
+ _engine->_resourcePixelFormat.colorToRGB(_colorMap[fogColor & 0x1F], dr, dg, db);
uint16 fr = dr + sr;
if (fr > 255)
fr = 255;
@@ -92,7 +92,7 @@ const Graphics::Surface *FogFx::draw(const Graphics::Surface &srcSubRect) {
uint16 fb = db + sb;
if (fb > 255)
fb = 255;
- lineBuf[i] = _engine->_pixelFormat.RGBToColor(fr, fg, fb);
+ lineBuf[i] = _engine->_resourcePixelFormat.RGBToColor(fr, fg, fb);
}
cnt++;
if (cnt >= it->count) {
@@ -138,14 +138,14 @@ void FogFx::update() {
// Not 100% equivalent, but looks nice and not buggy
- _colorMap[31] = _engine->_pixelFormat.RGBToColor(_r << 3, _g << 3, _b << 3);
+ _colorMap[31] = _engine->_resourcePixelFormat.RGBToColor(_r << 3, _g << 3, _b << 3);
for (uint8 i = 0; i < 31; i++) {
float perc = (float)i / 31.0;
uint8 cr = (float)_r * perc;
uint8 cg = (float)_g * perc;
uint8 cb = (float)_b * perc;
- _colorMap[i] = _engine->_pixelFormat.RGBToColor(cr << 3, cg << 3, cb << 3);
+ _colorMap[i] = _engine->_resourcePixelFormat.RGBToColor(cr << 3, cg << 3, cb << 3);
}
}
diff --git a/engines/zvision/graphics/effects/light.cpp b/engines/zvision/graphics/effects/light.cpp
index 00b3811d65..bf6513292f 100644
--- a/engines/zvision/graphics/effects/light.cpp
+++ b/engines/zvision/graphics/effects/light.cpp
@@ -59,10 +59,10 @@ const Graphics::Surface *LightFx::draw(const Graphics::Surface &srcSubRect) {
if (_pos < 0) {
uint8 cc = ((-_pos) & 0x1F) << 3;
- dcolor = _engine->_pixelFormat.RGBToColor(cc, cc, cc);
+ dcolor = _engine->_resourcePixelFormat.RGBToColor(cc, cc, cc);
} else {
uint8 cc = (_pos & 0x1F) << 3;
- dcolor = _engine->_pixelFormat.RGBToColor(cc, cc, cc);
+ dcolor = _engine->_resourcePixelFormat.RGBToColor(cc, cc, cc);
}
for (uint16 j = 0; j < _surface.h; j++) {
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 5af847c61a..1b6e1e2fdc 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -580,12 +580,6 @@ ActionPreloadAnimation::ActionPreloadAnimation(ZVision *engine, int32 slotkey, c
// The two %*u are usually 0 and dont seem to have a use
sscanf(line.c_str(), "%24s %*u %*u %d %d", fileName, &_mask, &_framerate);
- if (_mask > 0) {
- byte r, g, b;
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(_mask, r, g, b);
- _mask = _engine->_pixelFormat.RGBToColor(r, g, b);
- }
-
_fileName = Common::String(fileName);
}
@@ -648,12 +642,6 @@ ActionPlayAnimation::ActionPlayAnimation(ZVision *engine, int32 slotkey, const C
"%24s %u %u %u %u %u %u %d %*u %*u %d %d",
fileName, &_x, &_y, &_x2, &_y2, &_start, &_end, &_loopCount, &_mask, &_framerate);
- if (_mask > 0) {
- byte r, g, b;
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(_mask, r, g, b);
- _mask = _engine->_pixelFormat.RGBToColor(r, g, b);
- }
-
_fileName = Common::String(fileName);
}
@@ -861,21 +849,12 @@ ActionSetPartialScreen::ActionSetPartialScreen(ZVision *engine, int32 slotkey, c
_y = 0;
char fileName[25];
- int color;
- sscanf(line.c_str(), "%u %u %24s %*u %d", &_x, &_y, fileName, &color);
+ sscanf(line.c_str(), "%u %u %24s %*u %d", &_x, &_y, fileName, &_backgroundColor);
_fileName = Common::String(fileName);
- if (color >= 0) {
- byte r, g, b;
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(color, r, g, b);
- _backgroundColor = _engine->_pixelFormat.RGBToColor(r, g, b);
- } else {
- _backgroundColor = color;
- }
-
- if (color > 65535) {
+ if (_backgroundColor > 65535) {
warning("Background color for ActionSetPartialScreen is bigger than a uint16");
}
}
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index d7734f6d7a..e1e6e6ec9d 100644
--- a/engines/zvision/scripting/controls/input_control.cpp
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -199,7 +199,7 @@ bool InputControl::process(uint32 deltaTimeInMillis) {
// Blit the text using the RenderManager
Graphics::Surface txt;
- txt.create(_textRectangle.width(), _textRectangle.height(), _engine->_pixelFormat);
+ txt.create(_textRectangle.width(), _textRectangle.height(), _engine->_resourcePixelFormat);
if (!_readOnly || !_focused)
_txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringInit, txt);
diff --git a/engines/zvision/scripting/controls/titler_control.cpp b/engines/zvision/scripting/controls/titler_control.cpp
index 10ba0af655..d6b1d34bae 100644
--- a/engines/zvision/scripting/controls/titler_control.cpp
+++ b/engines/zvision/scripting/controls/titler_control.cpp
@@ -67,7 +67,7 @@ TitlerControl::TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadSt
if (!_rectangle.isEmpty()) {
_surface = new Graphics::Surface;
- _surface->create(_rectangle.width(), _rectangle.height(), _engine->_pixelFormat);
+ _surface->create(_rectangle.width(), _rectangle.height(), _engine->_resourcePixelFormat);
_surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
}
}
diff --git a/engines/zvision/scripting/sidefx/ttytext_node.cpp b/engines/zvision/scripting/sidefx/ttytext_node.cpp
index 2930118524..66a27e96c5 100644
--- a/engines/zvision/scripting/sidefx/ttytext_node.cpp
+++ b/engines/zvision/scripting/sidefx/ttytext_node.cpp
@@ -56,7 +56,7 @@ ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file
delete infile;
}
- _img.create(_r.width(), _r.height(), _engine->_pixelFormat);
+ _img.create(_r.width(), _r.height(), _engine->_resourcePixelFormat);
_style._sharp = true;
_style.readAllStyle(_txtbuf);
_style.setFont(_fnt);
@@ -158,7 +158,7 @@ void ttyTextNode::newline() {
}
void ttyTextNode::outchar(uint16 chr) {
- uint32 clr = _engine->_pixelFormat.RGBToColor(_style._red, _style._green, _style._blue);
+ uint32 clr = _engine->_resourcePixelFormat.RGBToColor(_style._red, _style._green, _style._blue);
if (_dx + _fnt.getCharWidth(chr) > _r.width())
newline();
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index 8ddba3fbab..f28ba6ade3 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -298,7 +298,7 @@ void cTxtStyle::setFont(StyledTTFont &font) {
Graphics::Surface *TextRenderer::render(StyledTTFont &fnt, const Common::String &txt, cTxtStyle &style) {
style.setFontStyle(fnt);
- uint32 clr = _engine->_pixelFormat.RGBToColor(style._red, style._green, style._blue);
+ uint32 clr = _engine->_resourcePixelFormat.RGBToColor(style._red, style._green, style._blue);
return fnt.renderSolidText(txt, clr);
}
@@ -317,7 +317,7 @@ int32 TextRenderer::drawTxt(const Common::String &txt, cTxtStyle &fontStyle, Gra
dst.fillRect(Common::Rect(dst.w, dst.h), 0);
- uint32 clr = _engine->_pixelFormat.RGBToColor(fontStyle._red, fontStyle._green, fontStyle._blue);
+ uint32 clr = _engine->_resourcePixelFormat.RGBToColor(fontStyle._red, fontStyle._green, fontStyle._blue);
int16 w;
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
index f373afe437..f64c0ab3bc 100644
--- a/engines/zvision/text/truetype_font.cpp
+++ b/engines/zvision/text/truetype_font.cpp
@@ -218,7 +218,7 @@ Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint
if (_font) {
int16 w = _font->getStringWidth(str);
if (w && w < 1024) {
- tmp->create(w, _font->getFontHeight(), _engine->_pixelFormat);
+ tmp->create(w, _font->getFontHeight(), _engine->_resourcePixelFormat);
drawString(tmp, str, 0, 0, w, color);
}
}
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index f1ac10bf88..260f912ade 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -64,7 +64,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
return;
}
- _currentFrameBuffer.create(_width, _height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ _currentFrameBuffer.create(_width, _height, getPixelFormat());
_frameBufferByteSize = _width * _height * sizeof(uint16);
_frames = new Frame[_frameCount];
@@ -239,12 +239,7 @@ void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- // NOTE: Color masks can't be used here, since accurate colors
- // are required to handle transparency correctly
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b);
- WRITE_UINT16(dest + destOffset, destColor);
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
sourceOffset += 2;
destOffset += 2;
@@ -288,12 +283,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- // NOTE: Color masks can't be used here, since accurate colors
- // are required to handle transparency correctly
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b);
- WRITE_UINT16(dest + destOffset, destColor);
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
sourceOffset += 2;
destOffset += 2;
@@ -307,11 +297,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- // NOTE: Color masks can't be used here, since accurate colors
- // are required to handle transparency correctly
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 sampleColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b);
+ uint16 sampleColor = READ_LE_UINT16(source + sourceOffset);
sourceOffset += 2;
numberOfCopy = numberOfSamples + 2;
diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h
index f0f31c2128..d56ff2da92 100644
--- a/engines/zvision/video/rlf_decoder.h
+++ b/engines/zvision/video/rlf_decoder.h
@@ -45,7 +45,7 @@ private:
uint16 getWidth() const { return _width; }
uint16 getHeight() const { return _height; }
- Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); /*RGB 565*/ }
+ Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); /* RGB 555 */ }
int getCurFrame() const { return _curFrame; }
int getFrameCount() const { return _frameCount; }
const Graphics::Surface *decodeNextFrame();
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 5978316451..b865ae9e6e 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -191,7 +191,7 @@ void ZVision::initialize() {
// Create managers
_scriptManager = new ScriptManager(this);
- _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _screenPixelFormat);
+ _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat);
_saveManager = new SaveManager(this);
_stringManager = new StringManager(this);
_cursorManager = new CursorManager(this, _resourcePixelFormat);
--
cgit v1.2.3
From 5f8418394b925adfc62ee6d180515157190a8cd9 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 22:54:24 +0200
Subject: ZVISION: Set all the internal graphics operations to use RGB555 (2/2)
This is the second part of the changes to make the engine use RGB555
internally again. This is done to simplify the rendering pipeline -
the engine will use RGB555 internally, but will output to RGB565.
The overall changes have been broken into two commits, with this
commit finishing all the changes.
This is needed, as the game uses RGB555 graphics internally, but
its AVI animations (full screen and in-game) use RGB565
---
.../zvision/graphics/cursors/cursor_manager.cpp | 2 +-
engines/zvision/graphics/render_manager.cpp | 111 +++++++++++++--------
engines/zvision/graphics/render_manager.h | 2 +
engines/zvision/video/video.cpp | 3 +-
engines/zvision/zvision.cpp | 1 -
engines/zvision/zvision.h | 1 -
6 files changed, 72 insertions(+), 48 deletions(-)
diff --git a/engines/zvision/graphics/cursors/cursor_manager.cpp b/engines/zvision/graphics/cursors/cursor_manager.cpp
index a197c7ed87..c364426bad 100644
--- a/engines/zvision/graphics/cursors/cursor_manager.cpp
+++ b/engines/zvision/graphics/cursors/cursor_manager.cpp
@@ -106,7 +106,7 @@ void CursorManager::initialize() {
}
void CursorManager::changeCursor(const ZorkCursor &cursor) {
- CursorMan.replaceCursor(cursor.getSurface(), cursor.getWidth(), cursor.getHeight(), cursor.getHotspotX(), cursor.getHotspotY(), cursor.getKeyColor(), false, _pixelFormat);
+ CursorMan.replaceCursor(cursor.getSurface(), cursor.getWidth(), cursor.getHeight(), cursor.getHotspotX(), cursor.getHotspotY(), cursor.getKeyColor(), false, &_pixelFormat);
}
void CursorManager::cursorDown(bool pushed) {
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 01df82410f..07ed6d2e2b 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -127,14 +127,29 @@ void RenderManager::renderSceneToScreen() {
}
if (!outWndDirtyRect.isEmpty()) {
- _system->copyRectToScreen(out->getBasePtr(outWndDirtyRect.left, outWndDirtyRect.top), out->pitch,
- outWndDirtyRect.left + _workingWindow.left,
- outWndDirtyRect.top + _workingWindow.top,
- outWndDirtyRect.width(),
- outWndDirtyRect.height());
+ Common::Rect rect(
+ outWndDirtyRect.left + _workingWindow.left,
+ outWndDirtyRect.top + _workingWindow.top,
+ outWndDirtyRect.left + _workingWindow.left + outWndDirtyRect.width(),
+ outWndDirtyRect.top + _workingWindow.top + outWndDirtyRect.height()
+ );
+ copyToScreen(*out, rect, outWndDirtyRect.left, outWndDirtyRect.top);
}
}
+void RenderManager::copyToScreen(const Graphics::Surface &surface, Common::Rect &rect, int16 srcLeft, int16 srcTop) {
+ // Convert the surface to RGB565, if needed
+ Graphics::Surface *outSurface = surface.convertTo(_engine->_screenPixelFormat);
+ _system->copyRectToScreen(outSurface->getBasePtr(srcLeft, srcTop),
+ outSurface->pitch,
+ rect.left,
+ rect.top,
+ rect.width(),
+ rect.height());
+ outSurface->free();
+ delete outSurface;
+}
+
void RenderManager::renderImageToBackground(const Common::String &fileName, int16 destX, int16 destY) {
Graphics::Surface surface;
readImageToSurface(fileName, surface);
@@ -183,8 +198,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
Image::TGADecoder tga;
uint16 *buffer;
// All ZVision images are in RGB 555
- Graphics::PixelFormat pixelFormat555 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
- destination.format = pixelFormat555;
+ destination.format = _engine->_resourcePixelFormat;
bool isTGZ;
@@ -229,7 +243,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
// If the destination internal buffer is the same size as what we're copying into it,
// there is no need to free() and re-create
if (imageWidth != destination.w || imageHeight != destination.h) {
- destination.create(imageWidth, imageHeight, pixelFormat555);
+ destination.create(imageWidth, imageHeight, _engine->_resourcePixelFormat);
}
// If transposed, 'un-transpose' the data while copying it to the destination
@@ -245,7 +259,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
}
}
} else {
- memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * _pixelFormat.bytesPerPixel);
+ memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * destination.format.bytesPerPixel);
}
// Cleanup
@@ -254,9 +268,6 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
} else {
tga.destroy();
}
-
- // Convert in place to RGB 565 from RGB 555
- destination.convertToInPlace(_pixelFormat);
}
const Common::Point RenderManager::screenSpaceToImageSpace(const Common::Point &point) {
@@ -370,10 +381,6 @@ void RenderManager::scaleBuffer(const void *src, void *dst, uint32 srcWidth, uin
}
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y) {
-
- if (src.format != dst.format)
- return;
-
Common::Rect srcRect = _srcRect;
if (srcRect.isEmpty())
srcRect = Common::Rect(src.w, src.h);
@@ -384,8 +391,10 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (srcRect.isEmpty() || !srcRect.isValidRect())
return;
+ Graphics::Surface *srcAdapted = src.convertTo(dst.format);
+
// Copy srcRect from src surface to dst surface
- const byte *srcBuffer = (const byte *)src.getBasePtr(srcRect.left, srcRect.top);
+ const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);
int xx = _x;
int yy = _y;
@@ -395,8 +404,11 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (yy < 0)
yy = 0;
- if (_x >= dst.w || _y >= dst.h)
+ if (_x >= dst.w || _y >= dst.h) {
+ srcAdapted->free();
+ delete srcAdapted;
return;
+ }
byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);
@@ -404,17 +416,16 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
int32 h = srcRect.height();
for (int32 y = 0; y < h; y++) {
- memcpy(dstBuffer, srcBuffer, w * src.format.bytesPerPixel);
- srcBuffer += src.pitch;
+ memcpy(dstBuffer, srcBuffer, w * srcAdapted->format.bytesPerPixel);
+ srcBuffer += srcAdapted->pitch;
dstBuffer += dst.pitch;
}
+
+ srcAdapted->free();
+ delete srcAdapted;
}
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y, uint32 colorkey) {
-
- if (src.format != dst.format)
- return;
-
Common::Rect srcRect = _srcRect;
if (srcRect.isEmpty())
srcRect = Common::Rect(src.w, src.h);
@@ -425,10 +436,11 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (srcRect.isEmpty() || !srcRect.isValidRect())
return;
- uint32 _keycolor = colorkey & ((1 << (src.format.bytesPerPixel << 3)) - 1);
+ Graphics::Surface *srcAdapted = src.convertTo(dst.format);
+ uint32 keycolor = colorkey & ((1 << (src.format.bytesPerPixel << 3)) - 1);
// Copy srcRect from src surface to dst surface
- const byte *srcBuffer = (const byte *)src.getBasePtr(srcRect.left, srcRect.top);
+ const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);
int xx = _x;
int yy = _y;
@@ -438,8 +450,11 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (yy < 0)
yy = 0;
- if (_x >= dst.w || _y >= dst.h)
+ if (_x >= dst.w || _y >= dst.h) {
+ srcAdapted->free();
+ delete srcAdapted;
return;
+ }
byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);
@@ -447,12 +462,12 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
int32 h = srcRect.height();
for (int32 y = 0; y < h; y++) {
- switch (src.format.bytesPerPixel) {
+ switch (srcAdapted->format.bytesPerPixel) {
case 1: {
const uint *srcTemp = (const uint *)srcBuffer;
uint *dstTemp = (uint *)dstBuffer;
for (int32 x = 0; x < w; x++) {
- if (*srcTemp != _keycolor)
+ if (*srcTemp != keycolor)
*dstTemp = *srcTemp;
srcTemp++;
dstTemp++;
@@ -464,7 +479,7 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
const uint16 *srcTemp = (const uint16 *)srcBuffer;
uint16 *dstTemp = (uint16 *)dstBuffer;
for (int32 x = 0; x < w; x++) {
- if (*srcTemp != _keycolor)
+ if (*srcTemp != keycolor)
*dstTemp = *srcTemp;
srcTemp++;
dstTemp++;
@@ -476,7 +491,7 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
const uint32 *srcTemp = (const uint32 *)srcBuffer;
uint32 *dstTemp = (uint32 *)dstBuffer;
for (int32 x = 0; x < w; x++) {
- if (*srcTemp != _keycolor)
+ if (*srcTemp != keycolor)
*dstTemp = *srcTemp;
srcTemp++;
dstTemp++;
@@ -487,9 +502,12 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
default:
break;
}
- srcBuffer += src.pitch;
+ srcBuffer += srcAdapted->pitch;
dstBuffer += dst.pitch;
}
+
+ srcAdapted->free();
+ delete srcAdapted;
}
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y) {
@@ -699,12 +717,15 @@ void RenderManager::clearMenuSurface(const Common::Rect &r) {
void RenderManager::renderMenuToScreen() {
if (!_menuSurfaceDirtyRect.isEmpty()) {
_menuSurfaceDirtyRect.clip(Common::Rect(_menuSurface.w, _menuSurface.h));
- if (!_menuSurfaceDirtyRect.isEmpty())
- _system->copyRectToScreen(_menuSurface.getBasePtr(_menuSurfaceDirtyRect.left, _menuSurfaceDirtyRect.top), _menuSurface.pitch,
- _menuSurfaceDirtyRect.left + _menuArea.left,
- _menuSurfaceDirtyRect.top + _menuArea.top,
- _menuSurfaceDirtyRect.width(),
- _menuSurfaceDirtyRect.height());
+ if (!_menuSurfaceDirtyRect.isEmpty()) {
+ Common::Rect rect(
+ _menuSurfaceDirtyRect.left + _menuArea.left,
+ _menuSurfaceDirtyRect.top + _menuArea.top,
+ _menuSurfaceDirtyRect.left + _menuArea.left + _menuSurfaceDirtyRect.width(),
+ _menuSurfaceDirtyRect.top + _menuArea.top + _menuSurfaceDirtyRect.height()
+ );
+ copyToScreen(_menuSurface, rect, _menuSurfaceDirtyRect.left, _menuSurfaceDirtyRect.top);
+ }
_menuSurfaceDirtyRect = Common::Rect();
}
}
@@ -779,7 +800,7 @@ void RenderManager::processSubs(uint16 deltatime) {
OneSubtitle *sub = &it->_value;
if (sub->txt.size()) {
Graphics::Surface *rndr = new Graphics::Surface();
- rndr->create(sub->r.width(), sub->r.height(), _pixelFormat);
+ rndr->create(sub->r.width(), sub->r.height(), _engine->_resourcePixelFormat);
_engine->getTextRenderer()->drawTxtInOneLine(sub->txt, *rndr);
blitSurfaceToSurface(*rndr, _subtitleSurface, sub->r.left - _subtitleArea.left + _workingWindow.left, sub->r.top - _subtitleArea.top + _workingWindow.top);
rndr->free();
@@ -788,11 +809,13 @@ void RenderManager::processSubs(uint16 deltatime) {
sub->redraw = false;
}
- _system->copyRectToScreen(_subtitleSurface.getPixels(), _subtitleSurface.pitch,
- _subtitleArea.left,
- _subtitleArea.top,
- _subtitleSurface.w,
- _subtitleSurface.h);
+ Common::Rect rect(
+ _subtitleArea.left,
+ _subtitleArea.top,
+ _subtitleArea.left + _subtitleSurface.w,
+ _subtitleArea.top + _subtitleSurface.h
+ );
+ copyToScreen(_subtitleSurface, rect, 0, 0);
}
}
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index c2dc169945..d67ae29a3a 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -146,6 +146,8 @@ public:
*/
void renderSceneToScreen();
+ void copyToScreen(const Graphics::Surface &surface, Common::Rect &rect, int16 srcLeft, int16 srcTop);
+
/**
* Blits the image or a portion of the image to the background.
*
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 50a6fc136a..e67e6570c5 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -114,7 +114,8 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
_renderManager->scaleBuffer(frame->getPixels(), scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, scaled->w, scaled->h);
frame = scaled;
}
- _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, x, y, finalWidth, finalHeight);
+ Common::Rect rect = Common::Rect(x, y, x + finalWidth, y + finalHeight);
+ _renderManager->copyToScreen(*frame, rect, 0, 0);
_renderManager->processSubs(0);
}
}
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index b865ae9e6e..db96884103 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -81,7 +81,6 @@ struct zvisionIniSettings {
ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
: Engine(syst),
_gameDescription(gameDesc),
- _pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /*RGB 565*/
_resourcePixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /* RGB 555 */
_screenPixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /* RGB 565 */
_desiredFrameTime(33), /* ~30 fps */
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index a63b66f70f..e9b8ca4547 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -68,7 +68,6 @@ public:
* edges of this Rectangle
*/
Common::Rect _workingWindow;
- const Graphics::PixelFormat _pixelFormat;
const Graphics::PixelFormat _resourcePixelFormat;
const Graphics::PixelFormat _screenPixelFormat;
--
cgit v1.2.3
From 75d78c71cc2190ae4afa655d27cdbc35a748f901 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 23:18:01 +0200
Subject: ZVISION: Plug another memory leak. Some cleanup
---
engines/zvision/scripting/sidefx/animation_node.cpp | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index bf3509f545..dec70e2642 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -44,7 +44,7 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S
Common::File *tmp = engine->getSearchManager()->openFile(fileName);
if (tmp) {
tmp->seek(176, SEEK_SET);
- _frmDelay = tmp->readUint32LE() / 10;
+ _frmDelay = Common::Rational(tmp->readUint32LE(), 10).toInt();
delete tmp;
}
@@ -73,8 +73,10 @@ AnimationNode::~AnimationNode() {
if (it != _playList.end()) {
_engine->getScriptManager()->setStateValue((*it).slot, 2);
- if ((*it)._scaled)
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
delete(*it)._scaled;
+ }
}
_playList.clear();
@@ -109,8 +111,10 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (nod->loop == 0) {
if (nod->slot >= 0)
_engine->getScriptManager()->setStateValue(nod->slot, 2);
- if (nod->_scaled)
+ if (nod->_scaled) {
+ nod->_scaled->free();
delete nod->_scaled;
+ }
_playList.erase(it);
return _DisposeAfterUse;
}
@@ -142,6 +146,7 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (frame->w > dstw || frame->h > dsth || (frame->w == dstw / 2 && frame->h == dsth / 2)) {
if (nod->_scaled)
if (nod->_scaled->w != dstw || nod->_scaled->h != dsth) {
+ nod->_scaled->free();
delete nod->_scaled;
nod->_scaled = NULL;
}
@@ -197,8 +202,10 @@ bool AnimationNode::stop() {
PlayNodes::iterator it = _playList.begin();
if (it != _playList.end()) {
_engine->getScriptManager()->setStateValue((*it).slot, 2);
- if ((*it)._scaled)
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
delete(*it)._scaled;
+ }
}
_playList.clear();
--
cgit v1.2.3
From fa2d8d927b353162ac9ee434b4611e03b22246e8 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Wed, 24 Dec 2014 23:27:03 +0200
Subject: ZVISION: Plug more memory leaks
---
engines/zvision/scripting/controls/paint_control.cpp | 12 +++++++++---
engines/zvision/scripting/controls/titler_control.cpp | 4 +++-
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/engines/zvision/scripting/controls/paint_control.cpp b/engines/zvision/scripting/controls/paint_control.cpp
index df06bb814e..62dde3d170 100644
--- a/engines/zvision/scripting/controls/paint_control.cpp
+++ b/engines/zvision/scripting/controls/paint_control.cpp
@@ -114,12 +114,18 @@ PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStre
PaintControl::~PaintControl() {
// Clear the state value back to 0
//_engine->getScriptManager()->setStateValue(_key, 0);
- if (_paint)
+ if (_paint) {
+ _paint->free();
delete _paint;
- if (_brush)
+ }
+ if (_brush) {
+ _brush->free();
delete _brush;
- if (_bkg)
+ }
+ if (_bkg) {
+ _bkg->free();
delete _bkg;
+ }
}
bool PaintControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
diff --git a/engines/zvision/scripting/controls/titler_control.cpp b/engines/zvision/scripting/controls/titler_control.cpp
index d6b1d34bae..542e0a0b67 100644
--- a/engines/zvision/scripting/controls/titler_control.cpp
+++ b/engines/zvision/scripting/controls/titler_control.cpp
@@ -73,8 +73,10 @@ TitlerControl::TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadSt
}
TitlerControl::~TitlerControl() {
- if (_surface)
+ if (_surface) {
+ _surface->free();
delete _surface;
+ }
}
void TitlerControl::setString(int strLine) {
--
cgit v1.2.3
From 381b7592a49e5d022159b5684dbba32eceaa6657 Mon Sep 17 00:00:00 2001
From: Martin Kiewitz
Date: Thu, 25 Dec 2014 00:31:17 +0100
Subject: SCI: actor file format, add debug code kPortrait
---
engines/sci/graphics/portrait.cpp | 51 +++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp
index 668de616fb..959c0f6817 100644
--- a/engines/sci/graphics/portrait.cpp
+++ b/engines/sci/graphics/portrait.cpp
@@ -57,13 +57,39 @@ void Portrait::init() {
// 4 bytes paletteSize (base 1)
// -> 17 bytes
// paletteSize bytes paletteData
- // 14 bytes bitmap header
- // -> 4 bytes unknown
- // -> 2 bytes height
- // -> 2 bytes width
- // -> 6 bytes unknown
- // height * width bitmap data
- // another animation count times bitmap header and data
+ //
+ // bitmap-data follows, total of [animation count]
+ // 14 bytes bitmap header
+ // -> 4 bytes unknown
+ // -> 2 bytes height
+ // -> 2 bytes width
+ // -> 6 bytes unknown
+ // height * width bitmap data
+ //
+ // 4 bytes offset table size (may be larger than the actual known entries?!)
+ // 14 bytes all zeroes (dummy entry?!)
+ //
+ // 14 bytes for each entry
+ // -> 2 bytes displace X
+ // -> 2 bytes displace Y
+ // -> 2 bytes height (again)
+ // -> 2 bytes width (again)
+ // -> 6 bytes unknown (normally 01 00 00 00 00 00 for delta bitmaps, 00 00 00 00 00 00 for first bitmap)
+ // random data may be used as filler
+ //
+ // 4 bytes lip sync id table size (is [lip sync id count] * 4, should be 0x2E0 for all actors)
+ // 4 bytes per lip sync id
+ // -> 1 byte length of ID
+ // -> 3 bytes actual ID
+ //
+ // 4 bytes lip sync id data table size (seems to be the same for all actors, always 0x220 in size)
+ // 1 byte animation number or 0xFF as terminator
+ // 1 byte delay, if last byte was not terminator
+ // one array for every lip sync id
+ //
+ // 4 bytes appended, seem to be random
+ // 9E11120E for alex
+ // 9E9E9E9E for vizier
int32 fileSize = 0;
Common::SeekableReadStream *file =
SearchMan.createReadStreamForMember("actors/" + _resourceName + ".bin");
@@ -202,6 +228,7 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
if (raveResource->size < 4000) {
memcpy(debugPrint, raveResource->data, raveResource->size);
debugPrint[raveResource->size] = 0; // set terminating NUL
+ debug("kPortrait: using actor %s", _resourceName.c_str());
debug("kPortrait (noun %d, verb %d, cond %d, seq %d)", noun, verb, cond, seq);
debug("kPortrait: %s", debugPrint);
}
@@ -273,6 +300,10 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
raveLipSyncData = NULL;
}
+#ifdef DEBUG_PORTRAIT
+ debug("kPortrait: %d: %x", raveTicks, raveID);
+#endif
+
timerPosition += raveTicks;
// Wait till syncTime passed, then show specific animation bitmap
@@ -294,6 +325,9 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
// Tick = 0xFF is the terminator for the data
timerPositionWithin = timerPosition;
raveLipSyncTicks = *raveLipSyncData++;
+#ifdef DEBUG_PORTRAIT
+ debug("kPortrait: waiting %d", raveLipSyncTicks);
+#endif
while ( (raveLipSyncData < _lipSyncDataOffsetTableEnd) && (raveLipSyncTicks != 0xFF) ) {
timerPositionWithin += raveLipSyncTicks;
@@ -308,6 +342,9 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
} while ((curPosition != -1) && (curPosition < timerPositionWithin) && (!userAbort));
raveLipSyncBitmapNr = *raveLipSyncData++;
+#ifdef DEBUG_PORTRAIT
+ debug("kPortrait: showing bitmap %d", raveLipSyncBitmapNr);
+#endif
// bitmap nr within sync data is base 1, we need base 0
raveLipSyncBitmapNr--;
--
cgit v1.2.3
From 319323c668003b284d51b84ec95a64ba7c072450 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 15:00:49 +0200
Subject: ZVISION: Document some of the ActionRegion effects
---
engines/zvision/graphics/effects/fog.h | 1 +
engines/zvision/scripting/actions.cpp | 2 +-
engines/zvision/scripting/scr_file_handling.cpp | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/engines/zvision/graphics/effects/fog.h b/engines/zvision/graphics/effects/fog.h
index 45d6f9596d..fe88707bbe 100644
--- a/engines/zvision/graphics/effects/fog.h
+++ b/engines/zvision/graphics/effects/fog.h
@@ -29,6 +29,7 @@ namespace ZVision {
class ZVision;
+// Used by Zork: Nemesis for the mixing chamber gas effect in the gas puzzle (location tt5e, when the blinds are down)
class FogFx : public Effect {
public:
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 1b6e1e2fdc..89b311e81c 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -704,7 +704,7 @@ bool ActionQuit::execute() {
}
//////////////////////////////////////////////////////////////////////////////
-// ActionRegion
+// ActionRegion - only used by Zork: Nemesis
//////////////////////////////////////////////////////////////////////////////
ActionRegion::ActionRegion(ZVision *engine, int32 slotkey, const Common::String &line) :
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index 47b8b0aa39..cca492d649 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -264,6 +264,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("random", true)) {
actionList.push_back(new ActionRandom(_engine, slot, args));
} else if (act.matchString("region", true)) {
+ // Only used by Zork: Nemesis
actionList.push_back(new ActionRegion(_engine, slot, args));
} else if (act.matchString("restore_game", true)) {
actionList.push_back(new ActionRestoreGame(_engine, slot, args));
--
cgit v1.2.3
From 5535cb02fc8dfaf2c77911c223c912f5b07bdb63 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 15:14:59 +0200
Subject: ZVISION: Resolve some TODOs
---
engines/zvision/scripting/actions.h | 2 +-
engines/zvision/scripting/scr_file_handling.cpp | 1 +
engines/zvision/scripting/script_manager.h | 3 +--
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h
index 292e25e19c..3501372c7f 100644
--- a/engines/zvision/scripting/actions.h
+++ b/engines/zvision/scripting/actions.h
@@ -338,7 +338,7 @@ private:
uint16 _unk2;
};
-// TODO: See if this exists in ZGI. It doesn't in ZNem
+// Only used by ZGI (locations cd6e, cd6k, dg2f, dg4e, dv1j)
class ActionUnloadAnimation : public ResultAction {
public:
ActionUnloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line);
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index cca492d649..83be3b5ad4 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -216,6 +216,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("animpreload", true)) {
actionList.push_back(new ActionPreloadAnimation(_engine, slot, args));
} else if (act.matchString("animunload", true)) {
+ // Only used by ZGI (locations cd6e, cd6k, dg2f, dg4e, dv1j)
actionList.push_back(new ActionUnloadAnimation(_engine, slot, args));
} else if (act.matchString("attenuate", true)) {
actionList.push_back(new ActionAttenuate(_engine, slot, args));
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
index 1e308faf0d..c5ade08e14 100644
--- a/engines/zvision/scripting/script_manager.h
+++ b/engines/zvision/scripting/script_manager.h
@@ -282,7 +282,7 @@ public:
void inventoryDrop(int16 item);
void inventoryCycle();
- // TODO: Make this private. It was only made public so Console::cmdParseAllScrFiles() could use it
+private:
/**
* Parses a script file into triggers and events
*
@@ -291,7 +291,6 @@ public:
*/
void parseScrFile(const Common::String &fileName, ScriptScope &scope);
-private:
/**
* Parses the stream into a Puzzle object
* Helper method for parseScrFile.
--
cgit v1.2.3
From 36c851d0e47b18205ac7ac91eb33666e4abe95ca Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 16:22:36 +0200
Subject: ZVISION: Fix frame rate for RLF videos and remove hack in
AnimationNode
_frameTime refers to msec, not ticks
---
engines/zvision/scripting/sidefx/animation_node.cpp | 16 ++++------------
engines/zvision/video/rlf_decoder.h | 2 +-
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index dec70e2642..97c6eeeab5 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -39,20 +39,12 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S
_mask(mask),
_animation(NULL) {
- if (fileName.hasSuffix(".rlf")) {
- // HACK: Read the frame delay directly
- Common::File *tmp = engine->getSearchManager()->openFile(fileName);
- if (tmp) {
- tmp->seek(176, SEEK_SET);
- _frmDelay = Common::Rational(tmp->readUint32LE(), 10).toInt();
- delete tmp;
- }
+ _animation = engine->loadAnimation(fileName);
- _animation = engine->loadAnimation(fileName);
- } else {
- _animation = engine->loadAnimation(fileName);
+ if (fileName.hasSuffix(".rlf"))
+ _frmDelay = _animation->getTimeToNextFrame();
+ else
_frmDelay = Common::Rational(1000, _animation->getDuration().framerate()).toInt();
- }
if (frate > 0)
_frmDelay = 1000.0 / frate;
diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h
index d56ff2da92..740f3fdd43 100644
--- a/engines/zvision/video/rlf_decoder.h
+++ b/engines/zvision/video/rlf_decoder.h
@@ -53,7 +53,7 @@ private:
bool seek(const Audio::Timestamp &time);
protected:
- Common::Rational getFrameRate() const { return Common::Rational(60, _frameTime); }
+ Common::Rational getFrameRate() const { return Common::Rational(1000, _frameTime); }
private:
enum EncodingType {
--
cgit v1.2.3
From 06fbca1e8109bdd3d1fdf72fc1056cbf658659e5 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 20:10:24 +0200
Subject: ZVISION: Remove dead code
---
engines/zvision/scripting/sidefx/animation_node.cpp | 4 ----
engines/zvision/scripting/sidefx/animation_node.h | 2 --
2 files changed, 6 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 97c6eeeab5..b966aa9cb8 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -206,8 +206,4 @@ bool AnimationNode::stop() {
return false;
}
-int32 AnimationNode::getFrameDelay() {
- return _frmDelay;
-}
-
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/sidefx/animation_node.h
index 74941aa764..368f0291fd 100644
--- a/engines/zvision/scripting/sidefx/animation_node.h
+++ b/engines/zvision/scripting/sidefx/animation_node.h
@@ -72,8 +72,6 @@ public:
void addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops = 1);
bool stop();
-
- int32 getFrameDelay();
};
} // End of namespace ZVision
--
cgit v1.2.3
From dbbcf641874ace35b871226664370413de176c37 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 21:17:47 +0200
Subject: ZVISION: Use the search manager to open files in console commands
---
engines/zvision/core/console.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index 07d3114ec8..c7592c8d9d 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -79,12 +79,14 @@ bool Console::cmdLoadSound(int argc, const char **argv) {
Audio::AudioStream *soundStream = makeRawZorkStream(argv[1], _engine);
Audio::SoundHandle handle;
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream, -1, 100, 0, DisposeAfterUse::YES, false, false);
-
} else if (argc == 4) {
int isStereo = atoi(argv[3]);
Common::File *file = new Common::File();
- file->open(argv[1]);
+ if (!_engine->getSearchManager()->openFile(*file, argv[1])) {
+ warning("File not found: %s", argv[1]);
+ return true;
+ }
Audio::AudioStream *soundStream = makeRawZorkStream(file, atoi(argv[2]), isStereo == 0 ? false : true);
Audio::SoundHandle handle;
@@ -104,8 +106,10 @@ bool Console::cmdRawToWav(int argc, const char **argv) {
}
Common::File file;
- if (!file.open(argv[1]))
+ if (!_engine->getSearchManager()->openFile(file, argv[1])) {
+ warning("File not found: %s", argv[1]);
return true;
+ }
Audio::AudioStream *audioStream = makeRawZorkStream(argv[1], _engine);
--
cgit v1.2.3
From 11cf9b53ba138b5e069d7ffbd6af7f36b26a9add Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 21:19:19 +0200
Subject: ZVISION: Remove dead code, and fix bad usage of assert()
Since some compilers, like MSVC, strip out asserts in non-debug builds,
it's a bad idea to perform active commands within assert() statements.
In this particular case, the engine would attempt to open a file in an
assert statement
---
engines/zvision/sound/zork_raw.cpp | 11 ++---------
engines/zvision/sound/zork_raw.h | 14 --------------
2 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
index b2c88b34df..6d1980b1af 100644
--- a/engines/zvision/sound/zork_raw.cpp
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -213,7 +213,6 @@ RawZorkStream::RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag dis
}
int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
-
int32 bytesRead = _streamReader.readBuffer(buffer, _stream.get(), numSamples);
if (_stream->eos())
@@ -241,16 +240,10 @@ Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stre
return new RawZorkStream(rate, stereo, disposeAfterUse, stream);
}
-Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
- int rate,
- bool stereo,
- DisposeAfterUse::Flag disposeAfterUse) {
- return makeRawZorkStream(new Common::MemoryReadStream(buffer, size, disposeAfterUse), rate, stereo, DisposeAfterUse::YES);
-}
-
Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine) {
Common::File *file = new Common::File();
- assert(engine->getSearchManager()->openFile(*file, filePath));
+ if (!engine->getSearchManager()->openFile(*file, filePath))
+ error("File not found: %s", filePath.c_str());
// Get the file name
Common::StringTokenizer tokenizer(filePath, "/\\");
diff --git a/engines/zvision/sound/zork_raw.h b/engines/zvision/sound/zork_raw.h
index 0b408d818c..892bad4d5f 100644
--- a/engines/zvision/sound/zork_raw.h
+++ b/engines/zvision/sound/zork_raw.h
@@ -122,20 +122,6 @@ public:
bool rewind();
};
-/**
- * Creates an audio stream, which plays from the given buffer.
- *
- * @param buffer Buffer to play from.
- * @param size Size of the buffer in bytes.
- * @param rate Rate of the sound data.
- * @param dispose AfterUse Whether to free the buffer after use (with free!).
- * @return The new SeekableAudioStream (or 0 on failure).
- */
-Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
- int rate,
- bool stereo,
- DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
-
/**
* Creates an audio stream, which plays from the given stream.
*
--
cgit v1.2.3
From 6c451c9cf481dcaa6261c34773b79689386ded42 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 21:48:59 +0200
Subject: ZVISION: Document where MIDI commands are used
---
engines/zvision/scripting/actions.cpp | 4 +++-
engines/zvision/scripting/sidefx/music_node.h | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 89b311e81c..be2079736e 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -477,7 +477,9 @@ ActionMusic::ActionMusic(ZVision *engine, int32 slotkey, const Common::String &l
sscanf(line.c_str(), "%u %24s %u %u", &type, fileNameBuffer, &loop, &volume);
- // type 4 are midi sound effect files
+ // Type 4 actions are MIDI commands, not files. These are only used by
+ // Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well
+ // as vr)
if (type == 4) {
_midi = true;
int note;
diff --git a/engines/zvision/scripting/sidefx/music_node.h b/engines/zvision/scripting/sidefx/music_node.h
index 8f4a46f3fc..3f1ca5cf7b 100644
--- a/engines/zvision/scripting/sidefx/music_node.h
+++ b/engines/zvision/scripting/sidefx/music_node.h
@@ -91,6 +91,7 @@ private:
bool _loaded;
};
+// Only used by Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well as vr)
class MusicMidiNode : public MusicNodeBASE {
public:
MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume);
--
cgit v1.2.3
From 6368a6ea91364f90bcb0d5d9d88826d856181a52 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 22:00:55 +0200
Subject: ZVISION: Move the menu code together with the other scripting code
---
engines/zvision/core/events.cpp | 2 +-
engines/zvision/core/menu.cpp | 765 -------------------------------------
engines/zvision/core/menu.h | 125 ------
engines/zvision/module.mk | 2 +-
engines/zvision/scripting/menu.cpp | 762 ++++++++++++++++++++++++++++++++++++
engines/zvision/scripting/menu.h | 125 ++++++
engines/zvision/zvision.cpp | 2 +-
7 files changed, 890 insertions(+), 893 deletions(-)
delete mode 100644 engines/zvision/core/menu.cpp
delete mode 100644 engines/zvision/core/menu.h
create mode 100644 engines/zvision/scripting/menu.cpp
create mode 100644 engines/zvision/scripting/menu.h
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 1920ffd769..89f1595460 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -28,7 +28,7 @@
#include "zvision/graphics/cursors/cursor_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/core/menu.h"
+#include "zvision/scripting/menu.h"
#include "zvision/sound/zork_raw.h"
#include "common/events.h"
diff --git a/engines/zvision/core/menu.cpp b/engines/zvision/core/menu.cpp
deleted file mode 100644
index 31e0d71370..0000000000
--- a/engines/zvision/core/menu.cpp
+++ /dev/null
@@ -1,765 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/core/menu.h"
-
-#include "zvision/graphics/render_manager.h"
-
-namespace ZVision {
-
-enum {
- SLOT_START_SLOT = 151,
- SLOT_SPELL_1 = 191,
- SLOT_USER_CHOSE_THIS_SPELL = 205,
- SLOT_REVERSED_SPELLBOOK = 206
-};
-
-enum {
- menu_MAIN_SAVE = 0,
- menu_MAIN_REST = 1,
- menu_MAIN_PREF = 2,
- menu_MAIN_EXIT = 3
-};
-
-MenuHandler::MenuHandler(ZVision *engine) {
- _engine = engine;
- menuBarFlag = 0xFFFF;
-}
-
-MenuZGI::MenuZGI(ZVision *engine) :
- MenuHandler(engine) {
- menuMouseFocus = -1;
- inmenu = false;
- scrolled[0] = false;
- scrolled[1] = false;
- scrolled[2] = false;
- scrollPos[0] = 0.0;
- scrollPos[1] = 0.0;
- scrollPos[2] = 0.0;
- mouseOnItem = -1;
- redraw = false;
- clean = false;
-
- char buf[24];
- for (int i = 1; i < 4; i++) {
- sprintf(buf, "gmzau%2.2x1.tga", i);
- _engine->getRenderManager()->readImageToSurface(buf, menuback[i - 1][0], false);
- sprintf(buf, "gmzau%2.2x1.tga", i + 0x10);
- _engine->getRenderManager()->readImageToSurface(buf, menuback[i - 1][1], false);
- }
- for (int i = 0; i < 4; i++) {
- sprintf(buf, "gmzmu%2.2x1.tga", i);
- _engine->getRenderManager()->readImageToSurface(buf, menubar[i][0], false);
- sprintf(buf, "gmznu%2.2x1.tga", i);
- _engine->getRenderManager()->readImageToSurface(buf, menubar[i][1], false);
- }
-
- for (int i = 0; i < 50; i++) {
- items[i][0] = NULL;
- items[i][1] = NULL;
- itemId[i] = 0;
- }
-
- for (int i = 0; i < 12; i++) {
- magic[i][0] = NULL;
- magic[i][1] = NULL;
- magicId[i] = 0;
- }
-}
-
-MenuZGI::~MenuZGI() {
- for (int i = 0; i < 3; i++) {
- menuback[i][0].free();
- menuback[i][1].free();
- }
- for (int i = 0; i < 4; i++) {
- menubar[i][0].free();
- menubar[i][1].free();
- }
- for (int i = 0; i < 50; i++) {
- if (items[i][0]) {
- items[i][0]->free();
- delete items[i][0];
- }
- if (items[i][1]) {
- items[i][1]->free();
- delete items[i][1];
- }
- }
- for (int i = 0; i < 12; i++) {
- if (magic[i][0]) {
- magic[i][0]->free();
- delete magic[i][0];
- }
- if (magic[i][1]) {
- magic[i][1]->free();
- delete magic[i][1];
- }
- }
-}
-
-void MenuZGI::onMouseUp(const Common::Point &Pos) {
- if (Pos.y < 40) {
- switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items) {
- int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
- if (itemCount == 0)
- itemCount = 20;
-
- for (int i = 0; i < itemCount; i++) {
- int itemspace = (600 - 28) / itemCount;
-
- if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
- scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
- int32 mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
- if (mouseItem >= 0 && mouseItem < 0xE0) {
- _engine->getScriptManager()->inventoryDrop(mouseItem);
- _engine->getScriptManager()->inventoryAdd(_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i));
- _engine->getScriptManager()->setStateValue(SLOT_START_SLOT + i, mouseItem);
-
- redraw = true;
- }
- }
- }
- }
- break;
-
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic) {
- for (int i = 0; i < 12; i++) {
-
- uint itemnum = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
- if (itemnum != 0) {
- if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
- itemnum = 0xEE + i;
- else
- itemnum = 0xE0 + i;
- }
- if (itemnum)
- if (_engine->getScriptManager()->getStateValue(StateKey_InventoryItem) == 0 || _engine->getScriptManager()->getStateValue(StateKey_InventoryItem) >= 0xE0)
- if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
- 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos))
- _engine->getScriptManager()->setStateValue(SLOT_USER_CHOSE_THIS_SPELL, itemnum);
- }
-
- }
- break;
-
- case menu_MAIN:
-
- // Exit
- if (menuBarFlag & menuBar_Exit)
- if (Common::Rect(320 + 135,
- scrollPos[menu_MAIN],
- 320 + 135 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- _engine->ifQuit();
- }
-
- // Settings
- if (menuBarFlag & menuBar_Settings)
- if (Common::Rect(320 ,
- scrollPos[menu_MAIN],
- 320 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- _engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
- }
-
- // Load
- if (menuBarFlag & menuBar_Restore)
- if (Common::Rect(320 - 135,
- scrollPos[menu_MAIN],
- 320,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- _engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
- }
-
- // Save
- if (menuBarFlag & menuBar_Save)
- if (Common::Rect(320 - 135 * 2,
- scrollPos[menu_MAIN],
- 320 - 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- _engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
- }
- break;
- }
- }
-}
-
-void MenuZGI::onMouseMove(const Common::Point &Pos) {
- if (Pos.y < 40) {
-
- if (!inmenu)
- redraw = true;
- inmenu = true;
- switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items) {
- int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
- if (itemCount == 0)
- itemCount = 20;
- else if (itemCount > 50)
- itemCount = 50;
-
- int lastItem = mouseOnItem;
-
- mouseOnItem = -1;
-
- for (int i = 0; i < itemCount; i++) {
- int itemspace = (600 - 28) / itemCount;
-
- if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
- scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
- mouseOnItem = i;
- break;
- }
- }
-
- if (lastItem != mouseOnItem)
- if (_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + mouseOnItem) ||
- _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + lastItem))
- redraw = true;
- }
- break;
-
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic) {
- int lastItem = mouseOnItem;
- mouseOnItem = -1;
- for (int i = 0; i < 12; i++) {
- if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
- 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos)) {
- mouseOnItem = i;
- break;
- }
- }
-
- if (lastItem != mouseOnItem)
- if (_engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + mouseOnItem) ||
- _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + lastItem))
- redraw = true;
-
- }
- break;
-
- case menu_MAIN: {
- int lastItem = mouseOnItem;
- mouseOnItem = -1;
-
- // Exit
- if (menuBarFlag & menuBar_Exit)
- if (Common::Rect(320 + 135,
- scrollPos[menu_MAIN],
- 320 + 135 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_EXIT;
- }
-
- // Settings
- if (menuBarFlag & menuBar_Settings)
- if (Common::Rect(320 ,
- scrollPos[menu_MAIN],
- 320 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_PREF;
- }
-
- // Load
- if (menuBarFlag & menuBar_Restore)
- if (Common::Rect(320 - 135,
- scrollPos[menu_MAIN],
- 320,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_REST;
- }
-
- // Save
- if (menuBarFlag & menuBar_Save)
- if (Common::Rect(320 - 135 * 2,
- scrollPos[menu_MAIN],
- 320 - 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_SAVE;
- }
-
- if (lastItem != mouseOnItem)
- redraw = true;
- }
- break;
-
- default:
- int cur_menu = menuMouseFocus;
- if (Common::Rect(64, 0, 64 + 512, 8).contains(Pos)) { // Main
- menuMouseFocus = menu_MAIN;
- scrolled[menu_MAIN] = false;
- scrollPos[menu_MAIN] = menuback[menu_MAIN][1].h - menuback[menu_MAIN][0].h;
- _engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
- }
-
- if (menuBarFlag & menuBar_Magic)
- if (Common::Rect(640 - 28, 0, 640, 32).contains(Pos)) { // Magic
- menuMouseFocus = menu_MAGIC;
- scrolled[menu_MAGIC] = false;
- scrollPos[menu_MAGIC] = 28;
- _engine->getScriptManager()->setStateValue(StateKey_MenuState, 3);
- }
-
- if (menuBarFlag & menuBar_Items)
- if (Common::Rect(0, 0, 28, 32).contains(Pos)) { // Items
- menuMouseFocus = menu_ITEM;
- scrolled[menu_ITEM] = false;
- scrollPos[menu_ITEM] = 28 - 600;
- _engine->getScriptManager()->setStateValue(StateKey_MenuState, 1);
- }
-
- if (cur_menu != menuMouseFocus)
- clean = true;
-
- break;
- }
- } else {
- if (inmenu)
- clean = true;
- inmenu = false;
- if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
- _engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
- menuMouseFocus = -1;
- }
-}
-
-void MenuZGI::process(uint32 deltatime) {
- if (clean) {
- _engine->getRenderManager()->clearMenuSurface();
- clean = false;
- }
- switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items)
- if (!scrolled[menu_ITEM]) {
- redraw = true;
- float scrl = 600.0 * (deltatime / 1000.0);
-
- if (scrl == 0)
- scrl = 1.0;
-
- scrollPos [menu_ITEM] += scrl;
-
- if (scrollPos[menu_ITEM] >= 0) {
- scrolled[menu_ITEM] = true;
- scrollPos [menu_ITEM] = 0;
- }
- }
- if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][0], scrollPos[menu_ITEM], 0);
-
- int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
- if (itemCount == 0)
- itemCount = 20;
- else if (itemCount > 50)
- itemCount = 50;
-
- for (int i = 0; i < itemCount; i++) {
- int itemspace = (600 - 28) / itemCount;
-
- bool inrect = false;
-
- if (mouseOnItem == i)
- inrect = true;
-
- uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i);
-
- if (curItemId != 0) {
- if (itemId[i] != curItemId) {
- char buf[16];
- sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
- items[i][0] = _engine->getRenderManager()->loadImage(buf, false);
- sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
- items[i][1] = _engine->getRenderManager()->loadImage(buf, false);
- itemId[i] = curItemId;
- }
-
- if (inrect)
- _engine->getRenderManager()->blitSurfaceToMenu(*items[i][1], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
- else
- _engine->getRenderManager()->blitSurfaceToMenu(*items[i][0], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
-
- } else {
- if (items[i][0]) {
- items[i][0]->free();
- delete items[i][0];
- items[i][0] = NULL;
- }
- if (items[i][1]) {
- items[i][1]->free();
- delete items[i][1];
- items[i][1] = NULL;
- }
- itemId[i] = 0;
- }
- }
-
- redraw = false;
- }
- break;
-
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic)
- if (!scrolled[menu_MAGIC]) {
- redraw = true;
- float scrl = 600.0 * (deltatime / 1000.0);
-
- if (scrl == 0)
- scrl = 1.0;
-
- scrollPos [menu_MAGIC] += scrl;
-
- if (scrollPos[menu_MAGIC] >= 600) {
- scrolled[menu_MAGIC] = true;
- scrollPos [menu_MAGIC] = 600;
- }
- }
- if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][0], 640 - scrollPos[menu_MAGIC], 0);
-
- for (int i = 0; i < 12; i++) {
- bool inrect = false;
-
- if (mouseOnItem == i)
- inrect = true;
-
- uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
- if (curItemId) {
- if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
- curItemId = 0xEE + i;
- else
- curItemId = 0xE0 + i;
- }
-
- if (curItemId != 0) {
- if (itemId[i] != curItemId) {
- char buf[16];
- sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
- magic[i][0] = _engine->getRenderManager()->loadImage(buf, false);
- sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
- magic[i][1] = _engine->getRenderManager()->loadImage(buf, false);
- magicId[i] = curItemId;
- }
-
- if (inrect)
- _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][1], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
- else
- _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][0], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
-
- } else {
- if (magic[i][0]) {
- magic[i][0]->free();
- delete magic[i][0];
- magic[i][0] = NULL;
- }
- if (magic[i][1]) {
- magic[i][1]->free();
- delete magic[i][1];
- magic[i][1] = NULL;
- }
- magicId[i] = 0;
- }
- }
- redraw = false;
- }
- break;
-
- case menu_MAIN:
- if (!scrolled[menu_MAIN]) {
- redraw = true;
- float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
-
- if (scrl == 0)
- scrl = 1.0;
-
- scrollPos [menu_MAIN] += scrl;
-
- if (scrollPos[menu_MAIN] >= 0) {
- scrolled[menu_MAIN] = true;
- scrollPos [menu_MAIN] = 0;
- }
- }
- if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][0], 30, scrollPos[menu_MAIN]);
-
- if (menuBarFlag & menuBar_Exit) {
- if (mouseOnItem == menu_MAIN_EXIT)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][1], 320 + 135, scrollPos[menu_MAIN]);
- else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][0], 320 + 135, scrollPos[menu_MAIN]);
- }
- if (menuBarFlag & menuBar_Settings) {
- if (mouseOnItem == menu_MAIN_PREF)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][1], 320, scrollPos[menu_MAIN]);
- else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][0], 320, scrollPos[menu_MAIN]);
- }
- if (menuBarFlag & menuBar_Restore) {
- if (mouseOnItem == menu_MAIN_REST)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][1], 320 - 135, scrollPos[menu_MAIN]);
- else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][0], 320 - 135, scrollPos[menu_MAIN]);
- }
- if (menuBarFlag & menuBar_Save) {
- if (mouseOnItem == menu_MAIN_SAVE)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][1], 320 - 135 * 2, scrollPos[menu_MAIN]);
- else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][0], 320 - 135 * 2, scrollPos[menu_MAIN]);
- }
- redraw = false;
- }
- break;
- default:
- if (redraw) {
- if (inmenu) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][1], 30, 0);
-
- if (menuBarFlag & menuBar_Items)
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][1], 0, 0);
-
- if (menuBarFlag & menuBar_Magic)
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][1], 640 - 28, 0);
- }
- redraw = false;
- }
- break;
- }
-}
-
-MenuNemesis::MenuNemesis(ZVision *engine) :
- MenuHandler(engine) {
- inmenu = false;
- scrolled = false;
- scrollPos = 0.0;
- mouseOnItem = -1;
- redraw = false;
- delay = 0;
-
- char buf[24];
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 6; j++) {
- sprintf(buf, "butfrm%d%d.tga", i + 1, j);
- _engine->getRenderManager()->readImageToSurface(buf, but[i][j], false);
- }
-
- _engine->getRenderManager()->readImageToSurface("bar.tga", menubar, false);
-
- frm = 0;
-}
-
-MenuNemesis::~MenuNemesis() {
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 6; j++)
- but[i][j].free();
-
- menubar.free();
-}
-
-static const int16 buts[4][2] = { {120 , 64}, {144, 184}, {128, 328}, {120, 456} };
-
-void MenuNemesis::onMouseUp(const Common::Point &Pos) {
- if (Pos.y < 40) {
- // Exit
- if (menuBarFlag & menuBar_Exit)
- if (Common::Rect(buts[3][1],
- scrollPos,
- buts[3][0] + buts[3][1],
- scrollPos + 32).contains(Pos)) {
- _engine->ifQuit();
- frm = 5;
- redraw = true;
- }
-
- // Settings
- if (menuBarFlag & menuBar_Settings)
- if (Common::Rect(buts[2][1],
- scrollPos,
- buts[2][0] + buts[2][1],
- scrollPos + 32).contains(Pos)) {
- _engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
- frm = 5;
- redraw = true;
- }
-
- // Load
- if (menuBarFlag & menuBar_Restore)
- if (Common::Rect(buts[1][1],
- scrollPos,
- buts[1][0] + buts[1][1],
- scrollPos + 32).contains(Pos)) {
- _engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
- frm = 5;
- redraw = true;
- }
-
- // Save
- if (menuBarFlag & menuBar_Save)
- if (Common::Rect(buts[0][1],
- scrollPos,
- buts[0][0] + buts[0][1],
- scrollPos + 32).contains(Pos)) {
- _engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
- frm = 5;
- redraw = true;
- }
- }
-}
-
-void MenuNemesis::onMouseMove(const Common::Point &Pos) {
- if (Pos.y < 40) {
-
- inmenu = true;
-
- if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 2)
- _engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
-
- int lastItem = mouseOnItem;
- mouseOnItem = -1;
-
- // Exit
- if (menuBarFlag & menuBar_Exit)
- if (Common::Rect(buts[3][1],
- scrollPos,
- buts[3][0] + buts[3][1],
- scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_EXIT;
- }
-
- // Settings
- if (menuBarFlag & menuBar_Settings)
- if (Common::Rect(buts[2][1],
- scrollPos,
- buts[2][0] + buts[2][1],
- scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_PREF;
- }
-
- // Load
- if (menuBarFlag & menuBar_Restore)
- if (Common::Rect(buts[1][1],
- scrollPos,
- buts[1][0] + buts[1][1],
- scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_REST;
- }
-
- // Save
- if (menuBarFlag & menuBar_Save)
- if (Common::Rect(buts[0][1],
- scrollPos,
- buts[0][0] + buts[0][1],
- scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_SAVE;
- }
-
- if (lastItem != mouseOnItem) {
- redraw = true;
- frm = 0;
- delay = 200;
- }
- } else {
- inmenu = false;
- if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
- _engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
- mouseOnItem = -1;
- }
-}
-
-void MenuNemesis::process(uint32 deltatime) {
- if (inmenu) {
- if (!scrolled) {
- float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
-
- if (scrl == 0)
- scrl = 1.0;
-
- scrollPos += scrl;
- redraw = true;
- }
-
- if (scrollPos >= 0) {
- scrolled = true;
- scrollPos = 0;
- }
-
- if (mouseOnItem != -1) {
- delay -= deltatime;
- if (delay <= 0 && frm < 4) {
- delay = 200;
- frm++;
- redraw = true;
- }
- }
-
- if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
-
- if (menuBarFlag & menuBar_Exit)
- if (mouseOnItem == menu_MAIN_EXIT)
- _engine->getRenderManager()->blitSurfaceToMenu(but[3][frm], buts[3][1], scrollPos);
-
- if (menuBarFlag & menuBar_Settings)
- if (mouseOnItem == menu_MAIN_PREF)
- _engine->getRenderManager()->blitSurfaceToMenu(but[2][frm], buts[2][1], scrollPos);
-
- if (menuBarFlag & menuBar_Restore)
- if (mouseOnItem == menu_MAIN_REST)
- _engine->getRenderManager()->blitSurfaceToMenu(but[1][frm], buts[1][1], scrollPos);
-
- if (menuBarFlag & menuBar_Save)
- if (mouseOnItem == menu_MAIN_SAVE)
- _engine->getRenderManager()->blitSurfaceToMenu(but[0][frm], buts[0][1], scrollPos);
-
- redraw = false;
- }
- } else {
- scrolled = false;
- if (scrollPos > -32) {
- float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
-
- if (scrl == 0)
- scrl = 1.0;
-
- Common::Rect cl(64, 32 + scrollPos - scrl, 64 + 512, 32 + scrollPos + 1);
- _engine->getRenderManager()->clearMenuSurface(cl);
-
- scrollPos -= scrl;
- redraw = true;
- } else
- scrollPos = -32;
-
- if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
- redraw = false;
- }
- }
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/core/menu.h b/engines/zvision/core/menu.h
deleted file mode 100644
index ebe0bb50ac..0000000000
--- a/engines/zvision/core/menu.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_MENU_H
-#define ZVISION_MENU_H
-
-#include "graphics/surface.h"
-#include "common/rect.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-
-namespace ZVision {
-
-enum menuBar {
- menuBar_Exit = 0x1,
- menuBar_Settings = 0x2,
- menuBar_Restore = 0x4,
- menuBar_Save = 0x8,
- menuBar_Items = 0x100,
- menuBar_Magic = 0x200
-};
-
-class MenuHandler {
-public:
- MenuHandler(ZVision *engine);
- virtual ~MenuHandler() {};
- virtual void onMouseMove(const Common::Point &Pos) {};
- virtual void onMouseDown(const Common::Point &Pos) {};
- virtual void onMouseUp(const Common::Point &Pos) {};
- virtual void process(uint32 deltaTimeInMillis) {};
-
- void setEnable(uint16 flags) {
- menuBarFlag = flags;
- }
- uint16 getEnable() {
- return menuBarFlag;
- }
-protected:
- uint16 menuBarFlag;
- ZVision *_engine;
-};
-
-class MenuZGI: public MenuHandler {
-public:
- MenuZGI(ZVision *engine);
- ~MenuZGI();
- void onMouseMove(const Common::Point &Pos);
- void onMouseUp(const Common::Point &Pos);
- void process(uint32 deltaTimeInMillis);
-private:
- Graphics::Surface menuback[3][2];
- Graphics::Surface menubar[4][2];
- Graphics::Surface *items[50][2];
- uint itemId[50];
-
- Graphics::Surface *magic[12][2];
- uint magicId[12];
-
- int menuMouseFocus;
- bool inmenu;
-
- int mouseOnItem;
-
- bool scrolled[3];
- int16 scrollPos[3];
-
- enum {
- menu_ITEM = 0,
- menu_MAGIC = 1,
- menu_MAIN = 2
- };
-
- bool clean;
- bool redraw;
-
-};
-
-class MenuNemesis: public MenuHandler {
-public:
- MenuNemesis(ZVision *engine);
- ~MenuNemesis();
- void onMouseMove(const Common::Point &Pos);
- void onMouseUp(const Common::Point &Pos);
- void process(uint32 deltaTimeInMillis);
-private:
- Graphics::Surface but[4][6];
- Graphics::Surface menubar;
-
- bool inmenu;
-
- int mouseOnItem;
-
- bool scrolled;
- int16 scrollPos;
-
- bool redraw;
-
- int frm;
- int16 delay;
-
-};
-
-}
-
-#endif
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 3ea31abe1b..6955d62534 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -4,7 +4,6 @@ MODULE_OBJS := \
core/console.o \
core/clock.o \
core/events.o \
- core/menu.o \
core/save_manager.o \
detection.o \
file/lzss_read_stream.o \
@@ -30,6 +29,7 @@ MODULE_OBJS := \
scripting/controls/slot_control.o \
scripting/controls/titler_control.o \
scripting/inventory.o \
+ scripting/menu.o \
scripting/scr_file_handling.o \
scripting/script_manager.o \
scripting/sidefx/animation_node.o \
diff --git a/engines/zvision/scripting/menu.cpp b/engines/zvision/scripting/menu.cpp
new file mode 100644
index 0000000000..fa5e24f39f
--- /dev/null
+++ b/engines/zvision/scripting/menu.cpp
@@ -0,0 +1,762 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "zvision/graphics/render_manager.h"
+#include "zvision/scripting/menu.h"
+
+namespace ZVision {
+
+enum {
+ SLOT_START_SLOT = 151,
+ SLOT_SPELL_1 = 191,
+ SLOT_USER_CHOSE_THIS_SPELL = 205,
+ SLOT_REVERSED_SPELLBOOK = 206
+};
+
+enum {
+ menu_MAIN_SAVE = 0,
+ menu_MAIN_REST = 1,
+ menu_MAIN_PREF = 2,
+ menu_MAIN_EXIT = 3
+};
+
+MenuHandler::MenuHandler(ZVision *engine) {
+ _engine = engine;
+ menuBarFlag = 0xFFFF;
+}
+
+MenuZGI::MenuZGI(ZVision *engine) :
+ MenuHandler(engine) {
+ menuMouseFocus = -1;
+ inmenu = false;
+ scrolled[0] = false;
+ scrolled[1] = false;
+ scrolled[2] = false;
+ scrollPos[0] = 0.0;
+ scrollPos[1] = 0.0;
+ scrollPos[2] = 0.0;
+ mouseOnItem = -1;
+ redraw = false;
+ clean = false;
+
+ char buf[24];
+ for (int i = 1; i < 4; i++) {
+ sprintf(buf, "gmzau%2.2x1.tga", i);
+ _engine->getRenderManager()->readImageToSurface(buf, menuback[i - 1][0], false);
+ sprintf(buf, "gmzau%2.2x1.tga", i + 0x10);
+ _engine->getRenderManager()->readImageToSurface(buf, menuback[i - 1][1], false);
+ }
+ for (int i = 0; i < 4; i++) {
+ sprintf(buf, "gmzmu%2.2x1.tga", i);
+ _engine->getRenderManager()->readImageToSurface(buf, menubar[i][0], false);
+ sprintf(buf, "gmznu%2.2x1.tga", i);
+ _engine->getRenderManager()->readImageToSurface(buf, menubar[i][1], false);
+ }
+
+ for (int i = 0; i < 50; i++) {
+ items[i][0] = NULL;
+ items[i][1] = NULL;
+ itemId[i] = 0;
+ }
+
+ for (int i = 0; i < 12; i++) {
+ magic[i][0] = NULL;
+ magic[i][1] = NULL;
+ magicId[i] = 0;
+ }
+}
+
+MenuZGI::~MenuZGI() {
+ for (int i = 0; i < 3; i++) {
+ menuback[i][0].free();
+ menuback[i][1].free();
+ }
+ for (int i = 0; i < 4; i++) {
+ menubar[i][0].free();
+ menubar[i][1].free();
+ }
+ for (int i = 0; i < 50; i++) {
+ if (items[i][0]) {
+ items[i][0]->free();
+ delete items[i][0];
+ }
+ if (items[i][1]) {
+ items[i][1]->free();
+ delete items[i][1];
+ }
+ }
+ for (int i = 0; i < 12; i++) {
+ if (magic[i][0]) {
+ magic[i][0]->free();
+ delete magic[i][0];
+ }
+ if (magic[i][1]) {
+ magic[i][1]->free();
+ delete magic[i][1];
+ }
+ }
+}
+
+void MenuZGI::onMouseUp(const Common::Point &Pos) {
+ if (Pos.y < 40) {
+ switch (menuMouseFocus) {
+ case menu_ITEM:
+ if (menuBarFlag & menuBar_Items) {
+ int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
+ if (itemCount == 0)
+ itemCount = 20;
+
+ for (int i = 0; i < itemCount; i++) {
+ int itemspace = (600 - 28) / itemCount;
+
+ if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
+ scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
+ int32 mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
+ if (mouseItem >= 0 && mouseItem < 0xE0) {
+ _engine->getScriptManager()->inventoryDrop(mouseItem);
+ _engine->getScriptManager()->inventoryAdd(_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i));
+ _engine->getScriptManager()->setStateValue(SLOT_START_SLOT + i, mouseItem);
+
+ redraw = true;
+ }
+ }
+ }
+ }
+ break;
+
+ case menu_MAGIC:
+ if (menuBarFlag & menuBar_Magic) {
+ for (int i = 0; i < 12; i++) {
+
+ uint itemnum = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
+ if (itemnum != 0) {
+ if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
+ itemnum = 0xEE + i;
+ else
+ itemnum = 0xE0 + i;
+ }
+ if (itemnum)
+ if (_engine->getScriptManager()->getStateValue(StateKey_InventoryItem) == 0 || _engine->getScriptManager()->getStateValue(StateKey_InventoryItem) >= 0xE0)
+ if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
+ 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos))
+ _engine->getScriptManager()->setStateValue(SLOT_USER_CHOSE_THIS_SPELL, itemnum);
+ }
+
+ }
+ break;
+
+ case menu_MAIN:
+
+ // Exit
+ if (menuBarFlag & menuBar_Exit)
+ if (Common::Rect(320 + 135,
+ scrollPos[menu_MAIN],
+ 320 + 135 + 135,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ _engine->ifQuit();
+ }
+
+ // Settings
+ if (menuBarFlag & menuBar_Settings)
+ if (Common::Rect(320 ,
+ scrollPos[menu_MAIN],
+ 320 + 135,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
+ }
+
+ // Load
+ if (menuBarFlag & menuBar_Restore)
+ if (Common::Rect(320 - 135,
+ scrollPos[menu_MAIN],
+ 320,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
+ }
+
+ // Save
+ if (menuBarFlag & menuBar_Save)
+ if (Common::Rect(320 - 135 * 2,
+ scrollPos[menu_MAIN],
+ 320 - 135,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
+ }
+ break;
+ }
+ }
+}
+
+void MenuZGI::onMouseMove(const Common::Point &Pos) {
+ if (Pos.y < 40) {
+
+ if (!inmenu)
+ redraw = true;
+ inmenu = true;
+ switch (menuMouseFocus) {
+ case menu_ITEM:
+ if (menuBarFlag & menuBar_Items) {
+ int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
+ if (itemCount == 0)
+ itemCount = 20;
+ else if (itemCount > 50)
+ itemCount = 50;
+
+ int lastItem = mouseOnItem;
+
+ mouseOnItem = -1;
+
+ for (int i = 0; i < itemCount; i++) {
+ int itemspace = (600 - 28) / itemCount;
+
+ if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
+ scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
+ mouseOnItem = i;
+ break;
+ }
+ }
+
+ if (lastItem != mouseOnItem)
+ if (_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + lastItem))
+ redraw = true;
+ }
+ break;
+
+ case menu_MAGIC:
+ if (menuBarFlag & menuBar_Magic) {
+ int lastItem = mouseOnItem;
+ mouseOnItem = -1;
+ for (int i = 0; i < 12; i++) {
+ if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
+ 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos)) {
+ mouseOnItem = i;
+ break;
+ }
+ }
+
+ if (lastItem != mouseOnItem)
+ if (_engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + lastItem))
+ redraw = true;
+
+ }
+ break;
+
+ case menu_MAIN: {
+ int lastItem = mouseOnItem;
+ mouseOnItem = -1;
+
+ // Exit
+ if (menuBarFlag & menuBar_Exit)
+ if (Common::Rect(320 + 135,
+ scrollPos[menu_MAIN],
+ 320 + 135 + 135,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_EXIT;
+ }
+
+ // Settings
+ if (menuBarFlag & menuBar_Settings)
+ if (Common::Rect(320 ,
+ scrollPos[menu_MAIN],
+ 320 + 135,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_PREF;
+ }
+
+ // Load
+ if (menuBarFlag & menuBar_Restore)
+ if (Common::Rect(320 - 135,
+ scrollPos[menu_MAIN],
+ 320,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_REST;
+ }
+
+ // Save
+ if (menuBarFlag & menuBar_Save)
+ if (Common::Rect(320 - 135 * 2,
+ scrollPos[menu_MAIN],
+ 320 - 135,
+ scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_SAVE;
+ }
+
+ if (lastItem != mouseOnItem)
+ redraw = true;
+ }
+ break;
+
+ default:
+ int cur_menu = menuMouseFocus;
+ if (Common::Rect(64, 0, 64 + 512, 8).contains(Pos)) { // Main
+ menuMouseFocus = menu_MAIN;
+ scrolled[menu_MAIN] = false;
+ scrollPos[menu_MAIN] = menuback[menu_MAIN][1].h - menuback[menu_MAIN][0].h;
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
+ }
+
+ if (menuBarFlag & menuBar_Magic)
+ if (Common::Rect(640 - 28, 0, 640, 32).contains(Pos)) { // Magic
+ menuMouseFocus = menu_MAGIC;
+ scrolled[menu_MAGIC] = false;
+ scrollPos[menu_MAGIC] = 28;
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 3);
+ }
+
+ if (menuBarFlag & menuBar_Items)
+ if (Common::Rect(0, 0, 28, 32).contains(Pos)) { // Items
+ menuMouseFocus = menu_ITEM;
+ scrolled[menu_ITEM] = false;
+ scrollPos[menu_ITEM] = 28 - 600;
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 1);
+ }
+
+ if (cur_menu != menuMouseFocus)
+ clean = true;
+
+ break;
+ }
+ } else {
+ if (inmenu)
+ clean = true;
+ inmenu = false;
+ if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
+ menuMouseFocus = -1;
+ }
+}
+
+void MenuZGI::process(uint32 deltatime) {
+ if (clean) {
+ _engine->getRenderManager()->clearMenuSurface();
+ clean = false;
+ }
+ switch (menuMouseFocus) {
+ case menu_ITEM:
+ if (menuBarFlag & menuBar_Items)
+ if (!scrolled[menu_ITEM]) {
+ redraw = true;
+ float scrl = 600.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos [menu_ITEM] += scrl;
+
+ if (scrollPos[menu_ITEM] >= 0) {
+ scrolled[menu_ITEM] = true;
+ scrollPos [menu_ITEM] = 0;
+ }
+ }
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][0], scrollPos[menu_ITEM], 0);
+
+ int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
+ if (itemCount == 0)
+ itemCount = 20;
+ else if (itemCount > 50)
+ itemCount = 50;
+
+ for (int i = 0; i < itemCount; i++) {
+ int itemspace = (600 - 28) / itemCount;
+
+ bool inrect = false;
+
+ if (mouseOnItem == i)
+ inrect = true;
+
+ uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i);
+
+ if (curItemId != 0) {
+ if (itemId[i] != curItemId) {
+ char buf[16];
+ sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
+ items[i][0] = _engine->getRenderManager()->loadImage(buf, false);
+ sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
+ items[i][1] = _engine->getRenderManager()->loadImage(buf, false);
+ itemId[i] = curItemId;
+ }
+
+ if (inrect)
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][1], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][0], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
+
+ } else {
+ if (items[i][0]) {
+ items[i][0]->free();
+ delete items[i][0];
+ items[i][0] = NULL;
+ }
+ if (items[i][1]) {
+ items[i][1]->free();
+ delete items[i][1];
+ items[i][1] = NULL;
+ }
+ itemId[i] = 0;
+ }
+ }
+
+ redraw = false;
+ }
+ break;
+
+ case menu_MAGIC:
+ if (menuBarFlag & menuBar_Magic)
+ if (!scrolled[menu_MAGIC]) {
+ redraw = true;
+ float scrl = 600.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos [menu_MAGIC] += scrl;
+
+ if (scrollPos[menu_MAGIC] >= 600) {
+ scrolled[menu_MAGIC] = true;
+ scrollPos [menu_MAGIC] = 600;
+ }
+ }
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][0], 640 - scrollPos[menu_MAGIC], 0);
+
+ for (int i = 0; i < 12; i++) {
+ bool inrect = false;
+
+ if (mouseOnItem == i)
+ inrect = true;
+
+ uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
+ if (curItemId) {
+ if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
+ curItemId = 0xEE + i;
+ else
+ curItemId = 0xE0 + i;
+ }
+
+ if (curItemId != 0) {
+ if (itemId[i] != curItemId) {
+ char buf[16];
+ sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
+ magic[i][0] = _engine->getRenderManager()->loadImage(buf, false);
+ sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
+ magic[i][1] = _engine->getRenderManager()->loadImage(buf, false);
+ magicId[i] = curItemId;
+ }
+
+ if (inrect)
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][1], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][0], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
+
+ } else {
+ if (magic[i][0]) {
+ magic[i][0]->free();
+ delete magic[i][0];
+ magic[i][0] = NULL;
+ }
+ if (magic[i][1]) {
+ magic[i][1]->free();
+ delete magic[i][1];
+ magic[i][1] = NULL;
+ }
+ magicId[i] = 0;
+ }
+ }
+ redraw = false;
+ }
+ break;
+
+ case menu_MAIN:
+ if (!scrolled[menu_MAIN]) {
+ redraw = true;
+ float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos [menu_MAIN] += scrl;
+
+ if (scrollPos[menu_MAIN] >= 0) {
+ scrolled[menu_MAIN] = true;
+ scrollPos [menu_MAIN] = 0;
+ }
+ }
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][0], 30, scrollPos[menu_MAIN]);
+
+ if (menuBarFlag & menuBar_Exit) {
+ if (mouseOnItem == menu_MAIN_EXIT)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][1], 320 + 135, scrollPos[menu_MAIN]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][0], 320 + 135, scrollPos[menu_MAIN]);
+ }
+ if (menuBarFlag & menuBar_Settings) {
+ if (mouseOnItem == menu_MAIN_PREF)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][1], 320, scrollPos[menu_MAIN]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][0], 320, scrollPos[menu_MAIN]);
+ }
+ if (menuBarFlag & menuBar_Restore) {
+ if (mouseOnItem == menu_MAIN_REST)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][1], 320 - 135, scrollPos[menu_MAIN]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][0], 320 - 135, scrollPos[menu_MAIN]);
+ }
+ if (menuBarFlag & menuBar_Save) {
+ if (mouseOnItem == menu_MAIN_SAVE)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][1], 320 - 135 * 2, scrollPos[menu_MAIN]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][0], 320 - 135 * 2, scrollPos[menu_MAIN]);
+ }
+ redraw = false;
+ }
+ break;
+ default:
+ if (redraw) {
+ if (inmenu) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][1], 30, 0);
+
+ if (menuBarFlag & menuBar_Items)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][1], 0, 0);
+
+ if (menuBarFlag & menuBar_Magic)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][1], 640 - 28, 0);
+ }
+ redraw = false;
+ }
+ break;
+ }
+}
+
+MenuNemesis::MenuNemesis(ZVision *engine) :
+ MenuHandler(engine) {
+ inmenu = false;
+ scrolled = false;
+ scrollPos = 0.0;
+ mouseOnItem = -1;
+ redraw = false;
+ delay = 0;
+
+ char buf[24];
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 6; j++) {
+ sprintf(buf, "butfrm%d%d.tga", i + 1, j);
+ _engine->getRenderManager()->readImageToSurface(buf, but[i][j], false);
+ }
+
+ _engine->getRenderManager()->readImageToSurface("bar.tga", menubar, false);
+
+ frm = 0;
+}
+
+MenuNemesis::~MenuNemesis() {
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 6; j++)
+ but[i][j].free();
+
+ menubar.free();
+}
+
+static const int16 buts[4][2] = { {120 , 64}, {144, 184}, {128, 328}, {120, 456} };
+
+void MenuNemesis::onMouseUp(const Common::Point &Pos) {
+ if (Pos.y < 40) {
+ // Exit
+ if (menuBarFlag & menuBar_Exit)
+ if (Common::Rect(buts[3][1],
+ scrollPos,
+ buts[3][0] + buts[3][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->ifQuit();
+ frm = 5;
+ redraw = true;
+ }
+
+ // Settings
+ if (menuBarFlag & menuBar_Settings)
+ if (Common::Rect(buts[2][1],
+ scrollPos,
+ buts[2][0] + buts[2][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
+ frm = 5;
+ redraw = true;
+ }
+
+ // Load
+ if (menuBarFlag & menuBar_Restore)
+ if (Common::Rect(buts[1][1],
+ scrollPos,
+ buts[1][0] + buts[1][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
+ frm = 5;
+ redraw = true;
+ }
+
+ // Save
+ if (menuBarFlag & menuBar_Save)
+ if (Common::Rect(buts[0][1],
+ scrollPos,
+ buts[0][0] + buts[0][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
+ frm = 5;
+ redraw = true;
+ }
+ }
+}
+
+void MenuNemesis::onMouseMove(const Common::Point &Pos) {
+ if (Pos.y < 40) {
+
+ inmenu = true;
+
+ if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 2)
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
+
+ int lastItem = mouseOnItem;
+ mouseOnItem = -1;
+
+ // Exit
+ if (menuBarFlag & menuBar_Exit)
+ if (Common::Rect(buts[3][1],
+ scrollPos,
+ buts[3][0] + buts[3][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_EXIT;
+ }
+
+ // Settings
+ if (menuBarFlag & menuBar_Settings)
+ if (Common::Rect(buts[2][1],
+ scrollPos,
+ buts[2][0] + buts[2][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_PREF;
+ }
+
+ // Load
+ if (menuBarFlag & menuBar_Restore)
+ if (Common::Rect(buts[1][1],
+ scrollPos,
+ buts[1][0] + buts[1][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_REST;
+ }
+
+ // Save
+ if (menuBarFlag & menuBar_Save)
+ if (Common::Rect(buts[0][1],
+ scrollPos,
+ buts[0][0] + buts[0][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = menu_MAIN_SAVE;
+ }
+
+ if (lastItem != mouseOnItem) {
+ redraw = true;
+ frm = 0;
+ delay = 200;
+ }
+ } else {
+ inmenu = false;
+ if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
+ mouseOnItem = -1;
+ }
+}
+
+void MenuNemesis::process(uint32 deltatime) {
+ if (inmenu) {
+ if (!scrolled) {
+ float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos += scrl;
+ redraw = true;
+ }
+
+ if (scrollPos >= 0) {
+ scrolled = true;
+ scrollPos = 0;
+ }
+
+ if (mouseOnItem != -1) {
+ delay -= deltatime;
+ if (delay <= 0 && frm < 4) {
+ delay = 200;
+ frm++;
+ redraw = true;
+ }
+ }
+
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
+
+ if (menuBarFlag & menuBar_Exit)
+ if (mouseOnItem == menu_MAIN_EXIT)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[3][frm], buts[3][1], scrollPos);
+
+ if (menuBarFlag & menuBar_Settings)
+ if (mouseOnItem == menu_MAIN_PREF)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[2][frm], buts[2][1], scrollPos);
+
+ if (menuBarFlag & menuBar_Restore)
+ if (mouseOnItem == menu_MAIN_REST)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[1][frm], buts[1][1], scrollPos);
+
+ if (menuBarFlag & menuBar_Save)
+ if (mouseOnItem == menu_MAIN_SAVE)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[0][frm], buts[0][1], scrollPos);
+
+ redraw = false;
+ }
+ } else {
+ scrolled = false;
+ if (scrollPos > -32) {
+ float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ Common::Rect cl(64, 32 + scrollPos - scrl, 64 + 512, 32 + scrollPos + 1);
+ _engine->getRenderManager()->clearMenuSurface(cl);
+
+ scrollPos -= scrl;
+ redraw = true;
+ } else
+ scrollPos = -32;
+
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
+ redraw = false;
+ }
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/menu.h b/engines/zvision/scripting/menu.h
new file mode 100644
index 0000000000..ebe0bb50ac
--- /dev/null
+++ b/engines/zvision/scripting/menu.h
@@ -0,0 +1,125 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_MENU_H
+#define ZVISION_MENU_H
+
+#include "graphics/surface.h"
+#include "common/rect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+
+namespace ZVision {
+
+enum menuBar {
+ menuBar_Exit = 0x1,
+ menuBar_Settings = 0x2,
+ menuBar_Restore = 0x4,
+ menuBar_Save = 0x8,
+ menuBar_Items = 0x100,
+ menuBar_Magic = 0x200
+};
+
+class MenuHandler {
+public:
+ MenuHandler(ZVision *engine);
+ virtual ~MenuHandler() {};
+ virtual void onMouseMove(const Common::Point &Pos) {};
+ virtual void onMouseDown(const Common::Point &Pos) {};
+ virtual void onMouseUp(const Common::Point &Pos) {};
+ virtual void process(uint32 deltaTimeInMillis) {};
+
+ void setEnable(uint16 flags) {
+ menuBarFlag = flags;
+ }
+ uint16 getEnable() {
+ return menuBarFlag;
+ }
+protected:
+ uint16 menuBarFlag;
+ ZVision *_engine;
+};
+
+class MenuZGI: public MenuHandler {
+public:
+ MenuZGI(ZVision *engine);
+ ~MenuZGI();
+ void onMouseMove(const Common::Point &Pos);
+ void onMouseUp(const Common::Point &Pos);
+ void process(uint32 deltaTimeInMillis);
+private:
+ Graphics::Surface menuback[3][2];
+ Graphics::Surface menubar[4][2];
+ Graphics::Surface *items[50][2];
+ uint itemId[50];
+
+ Graphics::Surface *magic[12][2];
+ uint magicId[12];
+
+ int menuMouseFocus;
+ bool inmenu;
+
+ int mouseOnItem;
+
+ bool scrolled[3];
+ int16 scrollPos[3];
+
+ enum {
+ menu_ITEM = 0,
+ menu_MAGIC = 1,
+ menu_MAIN = 2
+ };
+
+ bool clean;
+ bool redraw;
+
+};
+
+class MenuNemesis: public MenuHandler {
+public:
+ MenuNemesis(ZVision *engine);
+ ~MenuNemesis();
+ void onMouseMove(const Common::Point &Pos);
+ void onMouseUp(const Common::Point &Pos);
+ void process(uint32 deltaTimeInMillis);
+private:
+ Graphics::Surface but[4][6];
+ Graphics::Surface menubar;
+
+ bool inmenu;
+
+ int mouseOnItem;
+
+ bool scrolled;
+ int16 scrollPos;
+
+ bool redraw;
+
+ int frm;
+ int16 delay;
+
+};
+
+}
+
+#endif
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index db96884103..f692969942 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -30,7 +30,7 @@
#include "zvision/core/save_manager.h"
#include "zvision/text/string_manager.h"
#include "zvision/detection.h"
-#include "zvision/core/menu.h"
+#include "zvision/scripting/menu.h"
#include "zvision/file/search_manager.h"
#include "zvision/text/text.h"
#include "zvision/text/truetype_font.h"
--
cgit v1.2.3
From 3661bc4cf13ac9bb27e60969b4195acc82fee6c5 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Thu, 25 Dec 2014 22:11:29 +0200
Subject: ZVISION: Normalize and cleanup all the menu-related enums
---
engines/zvision/core/events.cpp | 8 +-
engines/zvision/scripting/menu.cpp | 289 ++++++++++++++---------------
engines/zvision/scripting/menu.h | 18 +-
engines/zvision/scripting/script_manager.h | 7 +-
4 files changed, 160 insertions(+), 162 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 89f1595460..227cf213dc 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -43,19 +43,19 @@ void ZVision::shortKeys(Common::Event event) {
if (event.kbd.hasFlags(Common::KBD_CTRL)) {
switch (event.kbd.keycode) {
case Common::KEYCODE_s:
- if (getMenuBarEnable() & menuBar_Save)
+ if (getMenuBarEnable() & kMenubarSave)
_scriptManager->changeLocation('g', 'j', 's', 'e', 0);
break;
case Common::KEYCODE_r:
- if (getMenuBarEnable() & menuBar_Restore)
+ if (getMenuBarEnable() & kMenubarRestore)
_scriptManager->changeLocation('g', 'j', 'r', 'e', 0);
break;
case Common::KEYCODE_p:
- if (getMenuBarEnable() & menuBar_Settings)
+ if (getMenuBarEnable() & kMenubarSettings)
_scriptManager->changeLocation('g', 'j', 'p', 'e', 0);
break;
case Common::KEYCODE_q:
- if (getMenuBarEnable() & menuBar_Exit)
+ if (getMenuBarEnable() & kMenubarExit)
ifQuit();
break;
default:
diff --git a/engines/zvision/scripting/menu.cpp b/engines/zvision/scripting/menu.cpp
index fa5e24f39f..16aa57e3ae 100644
--- a/engines/zvision/scripting/menu.cpp
+++ b/engines/zvision/scripting/menu.cpp
@@ -26,17 +26,16 @@
namespace ZVision {
enum {
- SLOT_START_SLOT = 151,
- SLOT_SPELL_1 = 191,
- SLOT_USER_CHOSE_THIS_SPELL = 205,
- SLOT_REVERSED_SPELLBOOK = 206
+ kMainMenuSave = 0,
+ kMainMenuLoad = 1,
+ kMainMenuPrefs = 2,
+ kMainMenuExit = 3
};
enum {
- menu_MAIN_SAVE = 0,
- menu_MAIN_REST = 1,
- menu_MAIN_PREF = 2,
- menu_MAIN_EXIT = 3
+ kMenuItem = 0,
+ kMenuMagic = 1,
+ kMenuMain = 2
};
MenuHandler::MenuHandler(ZVision *engine) {
@@ -119,8 +118,8 @@ MenuZGI::~MenuZGI() {
void MenuZGI::onMouseUp(const Common::Point &Pos) {
if (Pos.y < 40) {
switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems) {
int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
if (itemCount == 0)
itemCount = 20;
@@ -128,13 +127,13 @@ void MenuZGI::onMouseUp(const Common::Point &Pos) {
for (int i = 0; i < itemCount; i++) {
int itemspace = (600 - 28) / itemCount;
- if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
- scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
+ if (Common::Rect(scrollPos[kMenuItem] + itemspace * i, 0,
+ scrollPos[kMenuItem] + itemspace * i + 28, 32).contains(Pos)) {
int32 mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
if (mouseItem >= 0 && mouseItem < 0xE0) {
_engine->getScriptManager()->inventoryDrop(mouseItem);
- _engine->getScriptManager()->inventoryAdd(_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i));
- _engine->getScriptManager()->setStateValue(SLOT_START_SLOT + i, mouseItem);
+ _engine->getScriptManager()->inventoryAdd(_engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + i));
+ _engine->getScriptManager()->setStateValue(StateKey_Inv_StartSlot + i, mouseItem);
redraw = true;
}
@@ -143,62 +142,62 @@ void MenuZGI::onMouseUp(const Common::Point &Pos) {
}
break;
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic) {
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic) {
for (int i = 0; i < 12; i++) {
- uint itemnum = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
+ uint itemnum = _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + i);
if (itemnum != 0) {
- if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
+ if (_engine->getScriptManager()->getStateValue(StateKey_Reversed_Spellbooc) == 1)
itemnum = 0xEE + i;
else
itemnum = 0xE0 + i;
}
if (itemnum)
if (_engine->getScriptManager()->getStateValue(StateKey_InventoryItem) == 0 || _engine->getScriptManager()->getStateValue(StateKey_InventoryItem) >= 0xE0)
- if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
- 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos))
- _engine->getScriptManager()->setStateValue(SLOT_USER_CHOSE_THIS_SPELL, itemnum);
+ if (Common::Rect(668 + 47 * i - scrollPos[kMenuMagic], 0,
+ 668 + 47 * i - scrollPos[kMenuMagic] + 28, 32).contains(Pos))
+ _engine->getScriptManager()->setStateValue(StateKey_Active_Spell, itemnum);
}
}
break;
- case menu_MAIN:
+ case kMenuMain:
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(320 + 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->ifQuit();
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(320 ,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(320 - 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(320 - 135 * 2,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 - 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
}
break;
@@ -213,8 +212,8 @@ void MenuZGI::onMouseMove(const Common::Point &Pos) {
redraw = true;
inmenu = true;
switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems) {
int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
if (itemCount == 0)
itemCount = 20;
@@ -228,78 +227,78 @@ void MenuZGI::onMouseMove(const Common::Point &Pos) {
for (int i = 0; i < itemCount; i++) {
int itemspace = (600 - 28) / itemCount;
- if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
- scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
+ if (Common::Rect(scrollPos[kMenuItem] + itemspace * i, 0,
+ scrollPos[kMenuItem] + itemspace * i + 28, 32).contains(Pos)) {
mouseOnItem = i;
break;
}
}
if (lastItem != mouseOnItem)
- if (_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + mouseOnItem) ||
- _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + lastItem))
+ if (_engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + lastItem))
redraw = true;
}
break;
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic) {
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic) {
int lastItem = mouseOnItem;
mouseOnItem = -1;
for (int i = 0; i < 12; i++) {
- if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
- 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos)) {
+ if (Common::Rect(668 + 47 * i - scrollPos[kMenuMagic], 0,
+ 668 + 47 * i - scrollPos[kMenuMagic] + 28, 32).contains(Pos)) {
mouseOnItem = i;
break;
}
}
if (lastItem != mouseOnItem)
- if (_engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + mouseOnItem) ||
- _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + lastItem))
+ if (_engine->getScriptManager()->getStateValue(StateKey_Spell_1 + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + lastItem))
redraw = true;
}
break;
- case menu_MAIN: {
+ case kMenuMain: {
int lastItem = mouseOnItem;
mouseOnItem = -1;
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(320 + 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_EXIT;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuExit;
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(320 ,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_PREF;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuPrefs;
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(320 - 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_REST;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuLoad;
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(320 - 135 * 2,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 - 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_SAVE;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuSave;
}
if (lastItem != mouseOnItem)
@@ -310,25 +309,25 @@ void MenuZGI::onMouseMove(const Common::Point &Pos) {
default:
int cur_menu = menuMouseFocus;
if (Common::Rect(64, 0, 64 + 512, 8).contains(Pos)) { // Main
- menuMouseFocus = menu_MAIN;
- scrolled[menu_MAIN] = false;
- scrollPos[menu_MAIN] = menuback[menu_MAIN][1].h - menuback[menu_MAIN][0].h;
+ menuMouseFocus = kMenuMain;
+ scrolled[kMenuMain] = false;
+ scrollPos[kMenuMain] = menuback[kMenuMain][1].h - menuback[kMenuMain][0].h;
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
}
- if (menuBarFlag & menuBar_Magic)
+ if (menuBarFlag & kMenubarMagic)
if (Common::Rect(640 - 28, 0, 640, 32).contains(Pos)) { // Magic
- menuMouseFocus = menu_MAGIC;
- scrolled[menu_MAGIC] = false;
- scrollPos[menu_MAGIC] = 28;
+ menuMouseFocus = kMenuMagic;
+ scrolled[kMenuMagic] = false;
+ scrollPos[kMenuMagic] = 28;
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 3);
}
- if (menuBarFlag & menuBar_Items)
+ if (menuBarFlag & kMenubarItems)
if (Common::Rect(0, 0, 28, 32).contains(Pos)) { // Items
- menuMouseFocus = menu_ITEM;
- scrolled[menu_ITEM] = false;
- scrollPos[menu_ITEM] = 28 - 600;
+ menuMouseFocus = kMenuItem;
+ scrolled[kMenuItem] = false;
+ scrollPos[kMenuItem] = 28 - 600;
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 1);
}
@@ -353,24 +352,24 @@ void MenuZGI::process(uint32 deltatime) {
clean = false;
}
switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items)
- if (!scrolled[menu_ITEM]) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems)
+ if (!scrolled[kMenuItem]) {
redraw = true;
float scrl = 600.0 * (deltatime / 1000.0);
if (scrl == 0)
scrl = 1.0;
- scrollPos [menu_ITEM] += scrl;
+ scrollPos [kMenuItem] += scrl;
- if (scrollPos[menu_ITEM] >= 0) {
- scrolled[menu_ITEM] = true;
- scrollPos [menu_ITEM] = 0;
+ if (scrollPos[kMenuItem] >= 0) {
+ scrolled[kMenuItem] = true;
+ scrollPos [kMenuItem] = 0;
}
}
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][0], scrollPos[menu_ITEM], 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuItem][0], scrollPos[kMenuItem], 0);
int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
if (itemCount == 0)
@@ -386,7 +385,7 @@ void MenuZGI::process(uint32 deltatime) {
if (mouseOnItem == i)
inrect = true;
- uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i);
+ uint curItemId = _engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + i);
if (curItemId != 0) {
if (itemId[i] != curItemId) {
@@ -399,9 +398,9 @@ void MenuZGI::process(uint32 deltatime) {
}
if (inrect)
- _engine->getRenderManager()->blitSurfaceToMenu(*items[i][1], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][1], scrollPos[kMenuItem] + itemspace * i, 0, 0);
else
- _engine->getRenderManager()->blitSurfaceToMenu(*items[i][0], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][0], scrollPos[kMenuItem] + itemspace * i, 0, 0);
} else {
if (items[i][0]) {
@@ -422,24 +421,24 @@ void MenuZGI::process(uint32 deltatime) {
}
break;
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic)
- if (!scrolled[menu_MAGIC]) {
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic)
+ if (!scrolled[kMenuMagic]) {
redraw = true;
float scrl = 600.0 * (deltatime / 1000.0);
if (scrl == 0)
scrl = 1.0;
- scrollPos [menu_MAGIC] += scrl;
+ scrollPos [kMenuMagic] += scrl;
- if (scrollPos[menu_MAGIC] >= 600) {
- scrolled[menu_MAGIC] = true;
- scrollPos [menu_MAGIC] = 600;
+ if (scrollPos[kMenuMagic] >= 600) {
+ scrolled[kMenuMagic] = true;
+ scrollPos [kMenuMagic] = 600;
}
}
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][0], 640 - scrollPos[menu_MAGIC], 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMagic][0], 640 - scrollPos[kMenuMagic], 0);
for (int i = 0; i < 12; i++) {
bool inrect = false;
@@ -447,9 +446,9 @@ void MenuZGI::process(uint32 deltatime) {
if (mouseOnItem == i)
inrect = true;
- uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
+ uint curItemId = _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + i);
if (curItemId) {
- if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
+ if (_engine->getScriptManager()->getStateValue(StateKey_Reversed_Spellbooc) == 1)
curItemId = 0xEE + i;
else
curItemId = 0xE0 + i;
@@ -466,9 +465,9 @@ void MenuZGI::process(uint32 deltatime) {
}
if (inrect)
- _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][1], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][1], 668 + 47 * i - scrollPos[kMenuMagic], 0, 0);
else
- _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][0], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][0], 668 + 47 * i - scrollPos[kMenuMagic], 0, 0);
} else {
if (magic[i][0]) {
@@ -488,47 +487,47 @@ void MenuZGI::process(uint32 deltatime) {
}
break;
- case menu_MAIN:
- if (!scrolled[menu_MAIN]) {
+ case kMenuMain:
+ if (!scrolled[kMenuMain]) {
redraw = true;
float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
if (scrl == 0)
scrl = 1.0;
- scrollPos [menu_MAIN] += scrl;
+ scrollPos [kMenuMain] += scrl;
- if (scrollPos[menu_MAIN] >= 0) {
- scrolled[menu_MAIN] = true;
- scrollPos [menu_MAIN] = 0;
+ if (scrollPos[kMenuMain] >= 0) {
+ scrolled[kMenuMain] = true;
+ scrollPos [kMenuMain] = 0;
}
}
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][0], 30, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMain][0], 30, scrollPos[kMenuMain]);
- if (menuBarFlag & menuBar_Exit) {
- if (mouseOnItem == menu_MAIN_EXIT)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][1], 320 + 135, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarExit) {
+ if (mouseOnItem == kMainMenuExit)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuExit][1], 320 + 135, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][0], 320 + 135, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuExit][0], 320 + 135, scrollPos[kMenuMain]);
}
- if (menuBarFlag & menuBar_Settings) {
- if (mouseOnItem == menu_MAIN_PREF)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][1], 320, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarSettings) {
+ if (mouseOnItem == kMainMenuPrefs)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuPrefs][1], 320, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][0], 320, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuPrefs][0], 320, scrollPos[kMenuMain]);
}
- if (menuBarFlag & menuBar_Restore) {
- if (mouseOnItem == menu_MAIN_REST)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][1], 320 - 135, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarRestore) {
+ if (mouseOnItem == kMainMenuLoad)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuLoad][1], 320 - 135, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][0], 320 - 135, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuLoad][0], 320 - 135, scrollPos[kMenuMain]);
}
- if (menuBarFlag & menuBar_Save) {
- if (mouseOnItem == menu_MAIN_SAVE)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][1], 320 - 135 * 2, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarSave) {
+ if (mouseOnItem == kMainMenuSave)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuSave][1], 320 - 135 * 2, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][0], 320 - 135 * 2, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuSave][0], 320 - 135 * 2, scrollPos[kMenuMain]);
}
redraw = false;
}
@@ -536,13 +535,13 @@ void MenuZGI::process(uint32 deltatime) {
default:
if (redraw) {
if (inmenu) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][1], 30, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMain][1], 30, 0);
- if (menuBarFlag & menuBar_Items)
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][1], 0, 0);
+ if (menuBarFlag & kMenubarItems)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuItem][1], 0, 0);
- if (menuBarFlag & menuBar_Magic)
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][1], 640 - 28, 0);
+ if (menuBarFlag & kMenubarMagic)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMagic][1], 640 - 28, 0);
}
redraw = false;
}
@@ -584,7 +583,7 @@ static const int16 buts[4][2] = { {120 , 64}, {144, 184}, {128, 328}, {120, 456}
void MenuNemesis::onMouseUp(const Common::Point &Pos) {
if (Pos.y < 40) {
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(buts[3][1],
scrollPos,
buts[3][0] + buts[3][1],
@@ -595,7 +594,7 @@ void MenuNemesis::onMouseUp(const Common::Point &Pos) {
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(buts[2][1],
scrollPos,
buts[2][0] + buts[2][1],
@@ -606,7 +605,7 @@ void MenuNemesis::onMouseUp(const Common::Point &Pos) {
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(buts[1][1],
scrollPos,
buts[1][0] + buts[1][1],
@@ -617,7 +616,7 @@ void MenuNemesis::onMouseUp(const Common::Point &Pos) {
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(buts[0][1],
scrollPos,
buts[0][0] + buts[0][1],
@@ -641,39 +640,39 @@ void MenuNemesis::onMouseMove(const Common::Point &Pos) {
mouseOnItem = -1;
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(buts[3][1],
scrollPos,
buts[3][0] + buts[3][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_EXIT;
+ mouseOnItem = kMainMenuExit;
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(buts[2][1],
scrollPos,
buts[2][0] + buts[2][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_PREF;
+ mouseOnItem = kMainMenuPrefs;
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(buts[1][1],
scrollPos,
buts[1][0] + buts[1][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_REST;
+ mouseOnItem = kMainMenuLoad;
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(buts[0][1],
scrollPos,
buts[0][0] + buts[0][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_SAVE;
+ mouseOnItem = kMainMenuSave;
}
if (lastItem != mouseOnItem) {
@@ -718,20 +717,20 @@ void MenuNemesis::process(uint32 deltatime) {
if (redraw) {
_engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
- if (menuBarFlag & menuBar_Exit)
- if (mouseOnItem == menu_MAIN_EXIT)
+ if (menuBarFlag & kMenubarExit)
+ if (mouseOnItem == kMainMenuExit)
_engine->getRenderManager()->blitSurfaceToMenu(but[3][frm], buts[3][1], scrollPos);
- if (menuBarFlag & menuBar_Settings)
- if (mouseOnItem == menu_MAIN_PREF)
+ if (menuBarFlag & kMenubarSettings)
+ if (mouseOnItem == kMainMenuPrefs)
_engine->getRenderManager()->blitSurfaceToMenu(but[2][frm], buts[2][1], scrollPos);
- if (menuBarFlag & menuBar_Restore)
- if (mouseOnItem == menu_MAIN_REST)
+ if (menuBarFlag & kMenubarRestore)
+ if (mouseOnItem == kMainMenuLoad)
_engine->getRenderManager()->blitSurfaceToMenu(but[1][frm], buts[1][1], scrollPos);
- if (menuBarFlag & menuBar_Save)
- if (mouseOnItem == menu_MAIN_SAVE)
+ if (menuBarFlag & kMenubarSave)
+ if (mouseOnItem == kMainMenuSave)
_engine->getRenderManager()->blitSurfaceToMenu(but[0][frm], buts[0][1], scrollPos);
redraw = false;
diff --git a/engines/zvision/scripting/menu.h b/engines/zvision/scripting/menu.h
index ebe0bb50ac..a88587966f 100644
--- a/engines/zvision/scripting/menu.h
+++ b/engines/zvision/scripting/menu.h
@@ -32,12 +32,12 @@
namespace ZVision {
enum menuBar {
- menuBar_Exit = 0x1,
- menuBar_Settings = 0x2,
- menuBar_Restore = 0x4,
- menuBar_Save = 0x8,
- menuBar_Items = 0x100,
- menuBar_Magic = 0x200
+ kMenubarExit = 0x1,
+ kMenubarSettings = 0x2,
+ kMenubarRestore = 0x4,
+ kMenubarSave = 0x8,
+ kMenubarItems = 0x100,
+ kMenubarMagic = 0x200
};
class MenuHandler {
@@ -84,12 +84,6 @@ private:
bool scrolled[3];
int16 scrollPos[3];
- enum {
- menu_ITEM = 0,
- menu_MAGIC = 1,
- menu_MAIN = 2
- };
-
bool clean;
bool redraw;
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
index c5ade08e14..9f0f2f6e10 100644
--- a/engines/zvision/scripting/script_manager.h
+++ b/engines/zvision/scripting/script_manager.h
@@ -94,7 +94,12 @@ enum StateKey {
StateKey_Inv_Cnt_Slot = 100,
StateKey_Inv_1_Slot = 101,
StateKey_Inv_49_Slot = 149,
- StateKey_Inv_TotalSlots = 150
+ // ZGI only
+ StateKey_Inv_TotalSlots = 150,
+ StateKey_Inv_StartSlot = 151,
+ StateKey_Spell_1 = 191,
+ StateKey_Active_Spell = 205,
+ StateKey_Reversed_Spellbooc = 206
};
struct Location {
--
cgit v1.2.3
From 00a252fdc561b31379ddc5f568121b8040986add Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 03:58:37 +0200
Subject: ZVISION: Slight cleanup
---
engines/zvision/core/save_manager.cpp | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/engines/zvision/core/save_manager.cpp b/engines/zvision/core/save_manager.cpp
index 20bd39fde5..b45742154d 100644
--- a/engines/zvision/core/save_manager.cpp
+++ b/engines/zvision/core/save_manager.cpp
@@ -78,9 +78,6 @@ bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
}
void SaveManager::saveGame(uint slot, const Common::String &saveName) {
- // The games only support 20 slots
- //assert(slot <= 1 && slot <= 20);
-
Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
@@ -124,7 +121,6 @@ void SaveManager::autoSave() {
}
void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName) {
-
file->writeUint32BE(SAVEGAME_ID);
// Write version
@@ -148,9 +144,6 @@ void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::S
}
Common::Error SaveManager::loadGame(uint slot) {
- // The games only support 20 slots
- //assert(slot <= 1 && slot <= 20);
-
Common::SeekableReadStream *saveFile = getSlotFile(slot);
if (saveFile == 0) {
return Common::kPathDoesNotExist;
@@ -226,7 +219,13 @@ bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &hea
// Check that the save version isn't newer than this binary
if (header.version > SAVE_VERSION) {
uint tempVersion = header.version;
- GUI::MessageDialog dialog(Common::String::format("This save file uses version %u, but this engine only supports up to version %d. You will need an updated version of the engine to use this save file.", tempVersion, SAVE_VERSION), "OK");
+ GUI::MessageDialog dialog(
+ Common::String::format(
+ "This save file uses version %u, but this engine only "
+ "supports up to version %d. You will need an updated version "
+ "of the engine to use this save file.", tempVersion, SAVE_VERSION
+ ),
+ "OK");
dialog.runModal();
}
--
cgit v1.2.3
From 4d0ebfaa2285e2741a134db36fb4f5bd0317784d Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 04:03:20 +0200
Subject: ZVISION: Move the save manager together with the other file classes
---
engines/zvision/core/save_manager.cpp | 294 ---------------------
engines/zvision/core/save_manager.h | 106 --------
engines/zvision/detection.cpp | 2 +-
engines/zvision/file/save_manager.cpp | 294 +++++++++++++++++++++
engines/zvision/file/save_manager.h | 106 ++++++++
engines/zvision/module.mk | 2 +-
engines/zvision/scripting/actions.cpp | 2 +-
.../zvision/scripting/controls/save_control.cpp | 2 +-
engines/zvision/scripting/script_manager.cpp | 2 +-
engines/zvision/zvision.cpp | 2 +-
10 files changed, 406 insertions(+), 406 deletions(-)
delete mode 100644 engines/zvision/core/save_manager.cpp
delete mode 100644 engines/zvision/core/save_manager.h
create mode 100644 engines/zvision/file/save_manager.cpp
create mode 100644 engines/zvision/file/save_manager.h
diff --git a/engines/zvision/core/save_manager.cpp b/engines/zvision/core/save_manager.cpp
deleted file mode 100644
index b45742154d..0000000000
--- a/engines/zvision/core/save_manager.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/core/save_manager.h"
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-
-#include "common/system.h"
-#include "common/translation.h"
-
-#include "graphics/surface.h"
-#include "graphics/thumbnail.h"
-
-#include "gui/message.h"
-#include "gui/saveload.h"
-
-namespace ZVision {
-
-const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G');
-
-bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
- GUI::SaveLoadChooser *dialog;
- Common::String desc;
- int slot;
-
- if (isSave) {
- dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
-
- slot = dialog->runModalWithCurrentTarget();
- desc = dialog->getResultString();
-
- if (desc.empty()) {
- // create our own description for the saved game, the user didnt enter it
- desc = dialog->createDefaultSaveDescription(slot);
- }
-
- if (desc.size() > 28)
- desc = Common::String(desc.c_str(), 28);
- } else {
- dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
- slot = dialog->runModalWithCurrentTarget();
- }
-
- delete dialog;
-
- if (slot < 0)
- return false;
-
- if (isSave) {
- saveGame(slot, desc);
- return true;
- } else {
- Common::ErrorCode result = loadGame(slot).getCode();
- return (result == Common::kNoError);
- }
-}
-
-void SaveManager::saveGame(uint slot, const Common::String &saveName) {
- Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
- Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
-
- writeSaveGameHeader(file, saveName);
-
- _engine->getScriptManager()->serialize(file);
-
- file->finalize();
- delete file;
-}
-
-void SaveManager::saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream) {
- Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
- Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
-
- writeSaveGameHeader(file, saveName);
-
- file->write(stream->getData(), stream->size());
-
- file->finalize();
- delete file;
-}
-
-void SaveManager::saveGameBuffered(uint slot, const Common::String &saveName) {
- if (_tempSave) {
- saveGame(slot, saveName, _tempSave);
- flushSaveBuffer();
- }
-}
-
-void SaveManager::autoSave() {
- Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName());
-
- writeSaveGameHeader(file, "auto");
-
- _engine->getScriptManager()->serialize(file);
-
- // Cleanup
- file->finalize();
- delete file;
-}
-
-void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName) {
- file->writeUint32BE(SAVEGAME_ID);
-
- // Write version
- file->writeByte(SAVE_VERSION);
-
- // Write savegame name
- file->writeString(saveName);
- file->writeByte(0);
-
- // Create a thumbnail and save it
- Graphics::saveThumbnail(*file);
-
- // Write out the save date/time
- TimeDate td;
- g_system->getTimeAndDate(td);
- file->writeSint16LE(td.tm_year + 1900);
- file->writeSint16LE(td.tm_mon + 1);
- file->writeSint16LE(td.tm_mday);
- file->writeSint16LE(td.tm_hour);
- file->writeSint16LE(td.tm_min);
-}
-
-Common::Error SaveManager::loadGame(uint slot) {
- Common::SeekableReadStream *saveFile = getSlotFile(slot);
- if (saveFile == 0) {
- return Common::kPathDoesNotExist;
- }
-
- // Read the header
- SaveGameHeader header;
- if (!readSaveGameHeader(saveFile, header)) {
- return Common::kUnknownError;
- }
-
- ScriptManager *scriptManager = _engine->getScriptManager();
- // Update the state table values
- scriptManager->deserialize(saveFile);
-
- delete saveFile;
- if (header.thumbnail)
- delete header.thumbnail;
-
- return Common::kNoError;
-}
-
-Common::Error SaveManager::loadGame(const Common::String &saveName) {
- Common::File *saveFile = _engine->getSearchManager()->openFile(saveName);
- if (saveFile == NULL) {
- saveFile = new Common::File;
- if (!saveFile->open(saveName)) {
- delete saveFile;
- return Common::kPathDoesNotExist;
- }
- }
-
- // Read the header
- SaveGameHeader header;
- if (!readSaveGameHeader(saveFile, header)) {
- return Common::kUnknownError;
- }
-
- ScriptManager *scriptManager = _engine->getScriptManager();
- // Update the state table values
- scriptManager->deserialize(saveFile);
-
- delete saveFile;
- if (header.thumbnail)
- delete header.thumbnail;
-
- return Common::kNoError;
-}
-
-bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
- uint32 tag = in->readUint32BE();
- // Check if it's original savegame than fill header structure
- if (tag == MKTAG('Z', 'N', 'S', 'G')) {
- header.saveYear = 0;
- header.saveMonth = 0;
- header.saveDay = 0;
- header.saveHour = 0;
- header.saveMinutes = 0;
- header.saveName = "Original Save";
- header.thumbnail = NULL;
- header.version = SAVE_ORIGINAL;
- in->seek(-4, SEEK_CUR);
- return true;
- }
- if (tag != SAVEGAME_ID) {
- warning("File is not a ZVision save file. Aborting load");
- return false;
- }
-
- // Read in the version
- header.version = in->readByte();
-
- // Check that the save version isn't newer than this binary
- if (header.version > SAVE_VERSION) {
- uint tempVersion = header.version;
- GUI::MessageDialog dialog(
- Common::String::format(
- "This save file uses version %u, but this engine only "
- "supports up to version %d. You will need an updated version "
- "of the engine to use this save file.", tempVersion, SAVE_VERSION
- ),
- "OK");
- dialog.runModal();
- }
-
- // Read in the save name
- header.saveName.clear();
- char ch;
- while ((ch = (char)in->readByte()) != '\0')
- header.saveName += ch;
-
- // Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
- return false;
-
- // Read in save date/time
- header.saveYear = in->readSint16LE();
- header.saveMonth = in->readSint16LE();
- header.saveDay = in->readSint16LE();
- header.saveHour = in->readSint16LE();
- header.saveMinutes = in->readSint16LE();
-
- return true;
-}
-
-Common::SeekableReadStream *SaveManager::getSlotFile(uint slot) {
- Common::SeekableReadStream *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot));
- if (saveFile == NULL) {
- // Try to load standard save file
- Common::String filename;
- if (_engine->getGameId() == GID_GRANDINQUISITOR)
- filename = Common::String::format("inqsav%u.sav", slot);
- else if (_engine->getGameId() == GID_NEMESIS)
- filename = Common::String::format("nemsav%u.sav", slot);
-
- saveFile = _engine->getSearchManager()->openFile(filename);
- if (saveFile == NULL) {
- Common::File *tmpFile = new Common::File;
- if (!tmpFile->open(filename)) {
- delete tmpFile;
- } else {
- saveFile = tmpFile;
- }
- }
-
- }
-
- return saveFile;
-}
-
-void SaveManager::prepareSaveBuffer() {
- if (_tempSave)
- delete _tempSave;
-
- _tempSave = new Common::MemoryWriteStreamDynamic;
-
- _engine->getScriptManager()->serialize(_tempSave);
-}
-
-void SaveManager::flushSaveBuffer() {
- if (_tempSave)
- delete _tempSave;
-
- _tempSave = NULL;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/core/save_manager.h b/engines/zvision/core/save_manager.h
deleted file mode 100644
index 75841331e7..0000000000
--- a/engines/zvision/core/save_manager.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_SAVE_MANAGER_H
-#define ZVISION_SAVE_MANAGER_H
-
-#include "common/savefile.h"
-#include "common/memstream.h"
-
-namespace Common {
-class String;
-}
-
-namespace Graphics {
-struct Surface;
-}
-
-namespace ZVision {
-
-class ZVision;
-
-struct SaveGameHeader {
- byte version;
- Common::String saveName;
- Graphics::Surface *thumbnail;
- int saveYear, saveMonth, saveDay;
- int saveHour, saveMinutes;
-};
-
-class SaveManager {
-public:
- SaveManager(ZVision *engine) : _engine(engine), _tempSave(NULL) {}
- ~SaveManager() {
- flushSaveBuffer();
- }
-
-private:
- ZVision *_engine;
- static const uint32 SAVEGAME_ID;
-
- enum {
- SAVE_ORIGINAL = 0,
- SAVE_VERSION = 1
- };
-
- Common::MemoryWriteStreamDynamic *_tempSave;
-
-public:
- /**
- * Called every room change. Saves the state of the room just before
- * we switched rooms. Uses ZVision::generateAutoSaveFileName() to
- * create the save file name.
- */
- void autoSave();
- /**
- * Copies the data from the last auto-save into a new save file. We
- * can't use the current state data because the save menu *IS* a room.
- * The file is named using ZVision::generateSaveFileName(slot)
- *
- * @param slot The save slot this save pertains to. Must be [1, 20]
- * @param saveName The internal name for this save. This is NOT the name of the actual save file.
- */
- void saveGame(uint slot, const Common::String &saveName);
- void saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream);
- void saveGameBuffered(uint slot, const Common::String &saveName);
- /**
- * Loads the state data from the save file that slot references. Uses
- * ZVision::generateSaveFileName(slot) to get the save file name.
- *
- * @param slot The save slot to load. Must be [1, 20]
- */
- Common::Error loadGame(uint slot);
- Common::Error loadGame(const Common::String &saveName);
-
- Common::SeekableReadStream *getSlotFile(uint slot);
- bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header);
-
- void prepareSaveBuffer();
- void flushSaveBuffer();
- bool scummVMSaveLoadDialog(bool isSave);
-private:
- void writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName);
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index ebf5bdcfdd..b8d6a74eee 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -26,7 +26,7 @@
#include "zvision/zvision.h"
#include "zvision/detection.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
#include "zvision/scripting/script_manager.h"
#include "common/translation.h"
diff --git a/engines/zvision/file/save_manager.cpp b/engines/zvision/file/save_manager.cpp
new file mode 100644
index 0000000000..05df834497
--- /dev/null
+++ b/engines/zvision/file/save_manager.cpp
@@ -0,0 +1,294 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/zvision.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/system.h"
+#include "common/translation.h"
+
+#include "graphics/surface.h"
+#include "graphics/thumbnail.h"
+
+#include "gui/message.h"
+#include "gui/saveload.h"
+
+namespace ZVision {
+
+const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G');
+
+bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
+ GUI::SaveLoadChooser *dialog;
+ Common::String desc;
+ int slot;
+
+ if (isSave) {
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
+
+ slot = dialog->runModalWithCurrentTarget();
+ desc = dialog->getResultString();
+
+ if (desc.empty()) {
+ // create our own description for the saved game, the user didnt enter it
+ desc = dialog->createDefaultSaveDescription(slot);
+ }
+
+ if (desc.size() > 28)
+ desc = Common::String(desc.c_str(), 28);
+ } else {
+ dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ slot = dialog->runModalWithCurrentTarget();
+ }
+
+ delete dialog;
+
+ if (slot < 0)
+ return false;
+
+ if (isSave) {
+ saveGame(slot, desc);
+ return true;
+ } else {
+ Common::ErrorCode result = loadGame(slot).getCode();
+ return (result == Common::kNoError);
+ }
+}
+
+void SaveManager::saveGame(uint slot, const Common::String &saveName) {
+ Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
+ Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
+
+ writeSaveGameHeader(file, saveName);
+
+ _engine->getScriptManager()->serialize(file);
+
+ file->finalize();
+ delete file;
+}
+
+void SaveManager::saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream) {
+ Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
+ Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
+
+ writeSaveGameHeader(file, saveName);
+
+ file->write(stream->getData(), stream->size());
+
+ file->finalize();
+ delete file;
+}
+
+void SaveManager::saveGameBuffered(uint slot, const Common::String &saveName) {
+ if (_tempSave) {
+ saveGame(slot, saveName, _tempSave);
+ flushSaveBuffer();
+ }
+}
+
+void SaveManager::autoSave() {
+ Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName());
+
+ writeSaveGameHeader(file, "auto");
+
+ _engine->getScriptManager()->serialize(file);
+
+ // Cleanup
+ file->finalize();
+ delete file;
+}
+
+void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName) {
+ file->writeUint32BE(SAVEGAME_ID);
+
+ // Write version
+ file->writeByte(SAVE_VERSION);
+
+ // Write savegame name
+ file->writeString(saveName);
+ file->writeByte(0);
+
+ // Create a thumbnail and save it
+ Graphics::saveThumbnail(*file);
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ file->writeSint16LE(td.tm_year + 1900);
+ file->writeSint16LE(td.tm_mon + 1);
+ file->writeSint16LE(td.tm_mday);
+ file->writeSint16LE(td.tm_hour);
+ file->writeSint16LE(td.tm_min);
+}
+
+Common::Error SaveManager::loadGame(uint slot) {
+ Common::SeekableReadStream *saveFile = getSlotFile(slot);
+ if (saveFile == 0) {
+ return Common::kPathDoesNotExist;
+ }
+
+ // Read the header
+ SaveGameHeader header;
+ if (!readSaveGameHeader(saveFile, header)) {
+ return Common::kUnknownError;
+ }
+
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ // Update the state table values
+ scriptManager->deserialize(saveFile);
+
+ delete saveFile;
+ if (header.thumbnail)
+ delete header.thumbnail;
+
+ return Common::kNoError;
+}
+
+Common::Error SaveManager::loadGame(const Common::String &saveName) {
+ Common::File *saveFile = _engine->getSearchManager()->openFile(saveName);
+ if (saveFile == NULL) {
+ saveFile = new Common::File;
+ if (!saveFile->open(saveName)) {
+ delete saveFile;
+ return Common::kPathDoesNotExist;
+ }
+ }
+
+ // Read the header
+ SaveGameHeader header;
+ if (!readSaveGameHeader(saveFile, header)) {
+ return Common::kUnknownError;
+ }
+
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ // Update the state table values
+ scriptManager->deserialize(saveFile);
+
+ delete saveFile;
+ if (header.thumbnail)
+ delete header.thumbnail;
+
+ return Common::kNoError;
+}
+
+bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+ uint32 tag = in->readUint32BE();
+ // Check if it's original savegame than fill header structure
+ if (tag == MKTAG('Z', 'N', 'S', 'G')) {
+ header.saveYear = 0;
+ header.saveMonth = 0;
+ header.saveDay = 0;
+ header.saveHour = 0;
+ header.saveMinutes = 0;
+ header.saveName = "Original Save";
+ header.thumbnail = NULL;
+ header.version = SAVE_ORIGINAL;
+ in->seek(-4, SEEK_CUR);
+ return true;
+ }
+ if (tag != SAVEGAME_ID) {
+ warning("File is not a ZVision save file. Aborting load");
+ return false;
+ }
+
+ // Read in the version
+ header.version = in->readByte();
+
+ // Check that the save version isn't newer than this binary
+ if (header.version > SAVE_VERSION) {
+ uint tempVersion = header.version;
+ GUI::MessageDialog dialog(
+ Common::String::format(
+ "This save file uses version %u, but this engine only "
+ "supports up to version %d. You will need an updated version "
+ "of the engine to use this save file.", tempVersion, SAVE_VERSION
+ ),
+ "OK");
+ dialog.runModal();
+ }
+
+ // Read in the save name
+ header.saveName.clear();
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0')
+ header.saveName += ch;
+
+ // Get the thumbnail
+ header.thumbnail = Graphics::loadThumbnail(*in);
+ if (!header.thumbnail)
+ return false;
+
+ // Read in save date/time
+ header.saveYear = in->readSint16LE();
+ header.saveMonth = in->readSint16LE();
+ header.saveDay = in->readSint16LE();
+ header.saveHour = in->readSint16LE();
+ header.saveMinutes = in->readSint16LE();
+
+ return true;
+}
+
+Common::SeekableReadStream *SaveManager::getSlotFile(uint slot) {
+ Common::SeekableReadStream *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot));
+ if (saveFile == NULL) {
+ // Try to load standard save file
+ Common::String filename;
+ if (_engine->getGameId() == GID_GRANDINQUISITOR)
+ filename = Common::String::format("inqsav%u.sav", slot);
+ else if (_engine->getGameId() == GID_NEMESIS)
+ filename = Common::String::format("nemsav%u.sav", slot);
+
+ saveFile = _engine->getSearchManager()->openFile(filename);
+ if (saveFile == NULL) {
+ Common::File *tmpFile = new Common::File;
+ if (!tmpFile->open(filename)) {
+ delete tmpFile;
+ } else {
+ saveFile = tmpFile;
+ }
+ }
+
+ }
+
+ return saveFile;
+}
+
+void SaveManager::prepareSaveBuffer() {
+ if (_tempSave)
+ delete _tempSave;
+
+ _tempSave = new Common::MemoryWriteStreamDynamic;
+
+ _engine->getScriptManager()->serialize(_tempSave);
+}
+
+void SaveManager::flushSaveBuffer() {
+ if (_tempSave)
+ delete _tempSave;
+
+ _tempSave = NULL;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/file/save_manager.h b/engines/zvision/file/save_manager.h
new file mode 100644
index 0000000000..75841331e7
--- /dev/null
+++ b/engines/zvision/file/save_manager.h
@@ -0,0 +1,106 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_SAVE_MANAGER_H
+#define ZVISION_SAVE_MANAGER_H
+
+#include "common/savefile.h"
+#include "common/memstream.h"
+
+namespace Common {
+class String;
+}
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+struct SaveGameHeader {
+ byte version;
+ Common::String saveName;
+ Graphics::Surface *thumbnail;
+ int saveYear, saveMonth, saveDay;
+ int saveHour, saveMinutes;
+};
+
+class SaveManager {
+public:
+ SaveManager(ZVision *engine) : _engine(engine), _tempSave(NULL) {}
+ ~SaveManager() {
+ flushSaveBuffer();
+ }
+
+private:
+ ZVision *_engine;
+ static const uint32 SAVEGAME_ID;
+
+ enum {
+ SAVE_ORIGINAL = 0,
+ SAVE_VERSION = 1
+ };
+
+ Common::MemoryWriteStreamDynamic *_tempSave;
+
+public:
+ /**
+ * Called every room change. Saves the state of the room just before
+ * we switched rooms. Uses ZVision::generateAutoSaveFileName() to
+ * create the save file name.
+ */
+ void autoSave();
+ /**
+ * Copies the data from the last auto-save into a new save file. We
+ * can't use the current state data because the save menu *IS* a room.
+ * The file is named using ZVision::generateSaveFileName(slot)
+ *
+ * @param slot The save slot this save pertains to. Must be [1, 20]
+ * @param saveName The internal name for this save. This is NOT the name of the actual save file.
+ */
+ void saveGame(uint slot, const Common::String &saveName);
+ void saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream);
+ void saveGameBuffered(uint slot, const Common::String &saveName);
+ /**
+ * Loads the state data from the save file that slot references. Uses
+ * ZVision::generateSaveFileName(slot) to get the save file name.
+ *
+ * @param slot The save slot to load. Must be [1, 20]
+ */
+ Common::Error loadGame(uint slot);
+ Common::Error loadGame(const Common::String &saveName);
+
+ Common::SeekableReadStream *getSlotFile(uint slot);
+ bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header);
+
+ void prepareSaveBuffer();
+ void flushSaveBuffer();
+ bool scummVMSaveLoadDialog(bool isSave);
+private:
+ void writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 6955d62534..8edd67b352 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -4,9 +4,9 @@ MODULE_OBJS := \
core/console.o \
core/clock.o \
core/events.o \
- core/save_manager.o \
detection.o \
file/lzss_read_stream.o \
+ file/save_manager.o \
file/search_manager.o \
file/zfs_archive.o \
graphics/cursors/cursor_manager.o \
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index be2079736e..ebbd09c8b9 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -29,6 +29,7 @@
#include "zvision/graphics/render_manager.h"
#include "zvision/sound/zork_raw.h"
#include "zvision/video/zork_avi_decoder.h"
+#include "zvision/file/save_manager.h"
#include "zvision/scripting/sidefx/timer_node.h"
#include "zvision/scripting/sidefx/music_node.h"
#include "zvision/scripting/sidefx/syncsound_node.h"
@@ -42,7 +43,6 @@
#include "zvision/graphics/effects/fog.h"
#include "zvision/graphics/effects/light.h"
#include "zvision/graphics/effects/wave.h"
-#include "zvision/core/save_manager.h"
#include "zvision/graphics/cursors/cursor_manager.h"
#include "common/file.h"
diff --git a/engines/zvision/scripting/controls/save_control.cpp b/engines/zvision/scripting/controls/save_control.cpp
index b35611feca..3a4dc47fe8 100644
--- a/engines/zvision/scripting/controls/save_control.cpp
+++ b/engines/zvision/scripting/controls/save_control.cpp
@@ -29,7 +29,7 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/text/string_manager.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
#include "common/str.h"
#include "common/stream.h"
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
index 4c1e69072d..2a4aa5fed0 100644
--- a/engines/zvision/scripting/script_manager.cpp
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -27,7 +27,7 @@
#include "zvision/zvision.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/graphics/cursors/cursor_manager.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
#include "zvision/scripting/actions.h"
#include "zvision/scripting/sidefx/timer_node.h"
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index f692969942..11e417d4ac 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -27,7 +27,7 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/graphics/cursors/cursor_manager.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
#include "zvision/text/string_manager.h"
#include "zvision/detection.h"
#include "zvision/scripting/menu.h"
--
cgit v1.2.3
From e4b2913e4ac5584803e65008c44addea05c3892a Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 04:05:48 +0200
Subject: ZVISION: Reorder the detection entries
---
engines/zvision/detection.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index b8d6a74eee..a361239e9e 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -100,28 +100,28 @@ static const ZVisionGameDescription gameDescriptions[] = {
},
{
- // Zork Grand Inquisitor English demo version
+ // Zork Grand Inquisitor English DVD version
{
"zgi",
- "Demo",
- AD_ENTRY1s("SCRIPTS.ZFS", "71a2494fd2fb999347deb13401e9b998", 304239),
+ "DVD",
+ AD_ENTRY1s("SCRIPTS.ZFS", "03157a3399513bfaaf8dc6d5ab798b36", 8433326),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_DEMO,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NONE)
},
GID_GRANDINQUISITOR
},
{
- // Zork Grand Inquisitor English DVD version
+ // Zork Grand Inquisitor English demo version
{
"zgi",
- "DVD",
- AD_ENTRY1s("SCRIPTS.ZFS", "03157a3399513bfaaf8dc6d5ab798b36", 8433326),
+ "Demo",
+ AD_ENTRY1s("SCRIPTS.ZFS", "71a2494fd2fb999347deb13401e9b998", 304239),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_DEMO,
GUIO1(GUIO_NONE)
},
GID_GRANDINQUISITOR
--
cgit v1.2.3
From 2350eca546396775c6e9ac9875ebd59bcc17663f Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 12:04:21 +0200
Subject: ZVISION: Remove some unused actions. Cleanup
---
engines/zvision/scripting/actions.cpp | 53 +++++--------------------
engines/zvision/scripting/actions.h | 26 ------------
engines/zvision/scripting/scr_file_handling.cpp | 6 ++-
3 files changed, 13 insertions(+), 72 deletions(-)
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index ebbd09c8b9..c26a93f529 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -242,23 +242,6 @@ bool ActionDisableControl::execute() {
return true;
}
-//////////////////////////////////////////////////////////////////////////////
-// ActionDisableVenus
-//////////////////////////////////////////////////////////////////////////////
-
-ActionDisableVenus::ActionDisableVenus(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
- _key = 0;
-
- sscanf(line.c_str(), "%d", &_key);
-}
-
-bool ActionDisableVenus::execute() {
- _engine->getScriptManager()->setStateValue(_key, 0);
-
- return true;
-}
-
//////////////////////////////////////////////////////////////////////////////
// ActionDisplayMessage
//////////////////////////////////////////////////////////////////////////////
@@ -295,7 +278,7 @@ bool ActionDissolve::execute() {
}
//////////////////////////////////////////////////////////////////////////////
-// ActionDistort
+// ActionDistort - only used by Zork: Nemesis for the "treatment" puzzle in the Sanitarium (aj30)
//////////////////////////////////////////////////////////////////////////////
ActionDistort::ActionDistort(ZVision *engine, int32 slotkey, const Common::String &line) :
@@ -406,7 +389,7 @@ bool ActionInventory::execute() {
}
//////////////////////////////////////////////////////////////////////////////
-// ActionKill
+// ActionKill - only used by ZGI
//////////////////////////////////////////////////////////////////////////////
ActionKill::ActionKill(ZVision *engine, int32 slotkey, const Common::String &line) :
@@ -735,13 +718,13 @@ bool ActionRegion::execute() {
if (_engine->getScriptManager()->getSideFX(_slotKey))
return true;
- Effect *effct = NULL;
+ Effect *effect = NULL;
switch (_type) {
case 0: {
uint16 centerX, centerY, frames;
double amplitude, waveln, speed;
sscanf(_custom.c_str(), "%hu,%hu,%hu,%lf,%lf,%lf,", ¢erX, ¢erY, &frames, &litude, &waveln, &speed);
- effct = new WaveFx(_engine, _slotKey, _rect, _unk1, frames, centerX, centerY, amplitude, waveln, speed);
+ effect = new WaveFx(_engine, _slotKey, _rect, _unk1, frames, centerX, centerY, amplitude, waveln, speed);
}
break;
case 1: {
@@ -753,7 +736,7 @@ bool ActionRegion::execute() {
int8 minD;
int8 maxD;
EffectMap *_map = _engine->getRenderManager()->makeEffectMap(Common::Point(aX, aY), aD, _rect, &minD, &maxD);
- effct = new LightFx(_engine, _slotKey, _rect, _unk1, _map, atoi(_custom.c_str()), minD, maxD);
+ effect = new LightFx(_engine, _slotKey, _rect, _unk1, _map, atoi(_custom.c_str()), minD, maxD);
}
break;
case 9: {
@@ -769,16 +752,16 @@ bool ActionRegion::execute() {
_rect.setHeight(tempMask.h);
EffectMap *_map = _engine->getRenderManager()->makeEffectMap(tempMask, 0);
- effct = new FogFx(_engine, _slotKey, _rect, _unk1, _map, Common::String(buf));
+ effect = new FogFx(_engine, _slotKey, _rect, _unk1, _map, Common::String(buf));
}
break;
default:
break;
}
- if (effct) {
- _engine->getScriptManager()->addSideFX(new RegionNode(_engine, _slotKey, effct, _delay));
- _engine->getRenderManager()->addEffect(effct);
+ if (effect) {
+ _engine->getScriptManager()->addSideFX(new RegionNode(_engine, _slotKey, effect, _delay));
+ _engine->getRenderManager()->addEffect(effect);
}
return true;
@@ -899,24 +882,6 @@ bool ActionSetScreen::execute() {
return true;
}
-//////////////////////////////////////////////////////////////////////////////
-// ActionSetVenus
-//////////////////////////////////////////////////////////////////////////////
-
-ActionSetVenus::ActionSetVenus(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
- _key = 0;
-
- sscanf(line.c_str(), "%d", &_key);
-}
-
-bool ActionSetVenus::execute() {
- if (_engine->getScriptManager()->getStateValue(_key))
- _engine->getScriptManager()->setStateValue(StateKey_Venus, _key);
-
- return true;
-}
-
//////////////////////////////////////////////////////////////////////////////
// ActionStop
//////////////////////////////////////////////////////////////////////////////
diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h
index 3501372c7f..8d43309b74 100644
--- a/engines/zvision/scripting/actions.h
+++ b/engines/zvision/scripting/actions.h
@@ -124,14 +124,6 @@ private:
uint8 _action;
};
-class ActionDebug : public ResultAction {
-public:
- ActionDebug(ZVision *engine, int32 slotkey, const Common::String &line);
- bool execute();
-
-private:
-};
-
class ActionDelayRender : public ResultAction {
public:
ActionDelayRender(ZVision *engine, int32 slotkey, const Common::String &line);
@@ -150,15 +142,6 @@ private:
uint32 _key;
};
-class ActionDisableVenus : public ResultAction {
-public:
- ActionDisableVenus(ZVision *engine, int32 slotkey, const Common::String &line);
- bool execute();
-
-private:
- int32 _key;
-};
-
class ActionDisplayMessage : public ResultAction {
public:
ActionDisplayMessage(ZVision *engine, int32 slotkey, const Common::String &line);
@@ -397,15 +380,6 @@ private:
Common::String _fileName;
};
-class ActionSetVenus : public ResultAction {
-public:
- ActionSetVenus(ZVision *engine, int32 slotkey, const Common::String &line);
- bool execute();
-
-private:
- int32 _key;
-};
-
class ActionStop : public ResultAction {
public:
ActionStop(ZVision *engine, int32 slotkey, const Common::String &line);
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index 83be3b5ad4..fd5c158fcc 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -235,12 +235,13 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("disable_control", true)) {
actionList.push_back(new ActionDisableControl(_engine, slot, args));
} else if (act.matchString("disable_venus", true)) {
- actionList.push_back(new ActionDisableVenus(_engine, slot, args));
+ // Not used. Purposely left empty
} else if (act.matchString("display_message", true)) {
actionList.push_back(new ActionDisplayMessage(_engine, slot, args));
} else if (act.matchString("dissolve", true)) {
actionList.push_back(new ActionDissolve(_engine));
} else if (act.matchString("distort", true)) {
+ // Only used by Zork: Nemesis for the "treatment" puzzle in the Sanitarium (aj30)
actionList.push_back(new ActionDistort(_engine, slot, args));
} else if (act.matchString("enable_control", true)) {
actionList.push_back(new ActionEnableControl(_engine, slot, args));
@@ -249,6 +250,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("inventory", true)) {
actionList.push_back(new ActionInventory(_engine, slot, args));
} else if (act.matchString("kill", true)) {
+ // Only used by ZGI
actionList.push_back(new ActionKill(_engine, slot, args));
} else if (act.matchString("menu_bar_enable", true)) {
actionList.push_back(new ActionMenuBarEnable(_engine, slot, args));
@@ -278,7 +280,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("set_screen", true)) {
actionList.push_back(new ActionSetScreen(_engine, slot, args));
} else if (act.matchString("set_venus", true)) {
- actionList.push_back(new ActionSetVenus(_engine, slot, args));
+ // Not used. Purposely left empty
} else if (act.matchString("stop", true)) {
actionList.push_back(new ActionStop(_engine, slot, args));
} else if (act.matchString("streamvideo", true)) {
--
cgit v1.2.3
From 4258750f5025e471ba682945e3091fdaa50c7bc9 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 12:07:21 +0200
Subject: ZVISION: Rename _halveDelay to _doubleFPS, to match its config
setting
---
engines/zvision/zvision.cpp | 12 ++++++------
engines/zvision/zvision.h | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 11e417d4ac..e9a4486ded 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -96,7 +96,7 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
_menu(nullptr),
_searchManager(nullptr),
_textRenderer(nullptr),
- _halveDelay(false),
+ _doubleFPS(false),
_audioId(0),
_frameRenderDelay(2),
_keyboardVelocity(0),
@@ -213,7 +213,7 @@ void ZVision::initialize() {
// Create debugger console. It requires GFX to be initialized
_console = new Console(this);
- _halveDelay = ConfMan.getBool("doublefps");
+ _doubleFPS = ConfMan.getBool("doublefps");
}
Common::Error ZVision::run() {
@@ -255,7 +255,7 @@ Common::Error ZVision::run() {
// Ensure non-negative
delay = delay < 0 ? 0 : delay;
- if (_halveDelay) {
+ if (_doubleFPS) {
delay >>= 1;
}
@@ -291,7 +291,7 @@ bool ZVision::askQuestion(const Common::String &str) {
}
}
_system->updateScreen();
- if (_halveDelay)
+ if (_doubleFPS)
_system->delayMillis(33);
else
_system->delayMillis(66);
@@ -319,7 +319,7 @@ void ZVision::delayedMessage(const Common::String &str, uint16 milsecs) {
break;
}
_system->updateScreen();
- if (_halveDelay)
+ if (_doubleFPS)
_system->delayMillis(33);
else
_system->delayMillis(66);
@@ -365,7 +365,7 @@ bool ZVision::canRender() {
void ZVision::updateRotation() {
int16 _velocity = _mouseVelocity + _keyboardVelocity;
- if (_halveDelay)
+ if (_doubleFPS)
_velocity /= 2;
if (_velocity) {
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index e9b8ca4547..d3beae5e61 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -121,7 +121,7 @@ private:
int _frameRenderDelay;
int16 _mouseVelocity;
int16 _keyboardVelocity;
- bool _halveDelay;
+ bool _doubleFPS;
bool _videoIsPlaying;
uint8 _cheatBuffer[KEYBUF_SIZE];
--
cgit v1.2.3
From 5a72eea2bb102bafb6da112ea90ad1f4af11e1f2 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 12:41:36 +0200
Subject: ZVISION: Move some event/rendering code out of the main engine code
---
engines/zvision/core/events.cpp | 37 ++++++-
engines/zvision/graphics/render_manager.cpp | 82 +++++++++++++++-
engines/zvision/graphics/render_manager.h | 8 +-
.../zvision/scripting/controls/save_control.cpp | 7 +-
engines/zvision/zvision.cpp | 108 +--------------------
engines/zvision/zvision.h | 13 ++-
6 files changed, 133 insertions(+), 122 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 227cf213dc..70fd425949 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -39,6 +39,33 @@
namespace ZVision {
+void ZVision::pushKeyToCheatBuf(uint8 key) {
+ for (int i = 0; i < KEYBUF_SIZE - 1; i++)
+ _cheatBuffer[i] = _cheatBuffer[i + 1];
+
+ _cheatBuffer[KEYBUF_SIZE - 1] = key;
+}
+
+bool ZVision::checkCode(const char *code) {
+ int codeLen = strlen(code);
+
+ if (codeLen > KEYBUF_SIZE)
+ return false;
+
+ for (int i = 0; i < codeLen; i++)
+ if (code[i] != _cheatBuffer[KEYBUF_SIZE - codeLen + i] && code[i] != '?')
+ return false;
+
+ return true;
+}
+
+uint8 ZVision::getBufferedKey(uint8 pos) {
+ if (pos >= KEYBUF_SIZE)
+ return 0;
+ else
+ return _cheatBuffer[KEYBUF_SIZE - pos - 1];
+}
+
void ZVision::shortKeys(Common::Event event) {
if (event.kbd.hasFlags(Common::KBD_CTRL)) {
switch (event.kbd.keycode) {
@@ -70,11 +97,11 @@ void ZVision::cheatCodes(uint8 key) {
if (getGameId() == GID_GRANDINQUISITOR) {
if (checkCode("IMNOTDEAF")) {
// Unknown cheat
- showDebugMsg(Common::String::format("IMNOTDEAF cheat or debug, not implemented"));
+ _renderManager->showDebugMsg(Common::String::format("IMNOTDEAF cheat or debug, not implemented"));
}
if (checkCode("3100OPB")) {
- showDebugMsg(Common::String::format("Current location: %c%c%c%c",
+ _renderManager->showDebugMsg(Common::String::format("Current location: %c%c%c%c",
_scriptManager->getStateValue(StateKey_World),
_scriptManager->getStateValue(StateKey_Room),
_scriptManager->getStateValue(StateKey_Node),
@@ -101,7 +128,7 @@ void ZVision::cheatCodes(uint8 key) {
}
if (checkCode("77MASSAVE")) {
- showDebugMsg(Common::String::format("Current location: %c%c%c%c",
+ _renderManager->showDebugMsg(Common::String::format("Current location: %c%c%c%c",
_scriptManager->getStateValue(StateKey_World),
_scriptManager->getStateValue(StateKey_Room),
_scriptManager->getStateValue(StateKey_Node),
@@ -131,13 +158,13 @@ void ZVision::cheatCodes(uint8 key) {
}
if (checkCode("FRAME"))
- showDebugMsg(Common::String::format("FPS: ???, not implemented"));
+ _renderManager->showDebugMsg(Common::String::format("FPS: ???, not implemented"));
if (checkCode("XYZZY"))
_scriptManager->setStateValue(StateKey_DebugCheats, 1 - _scriptManager->getStateValue(StateKey_DebugCheats));
if (checkCode("COMPUTERARCH"))
- showDebugMsg(Common::String::format("COMPUTERARCH: var-viewer not implemented"));
+ _renderManager->showDebugMsg(Common::String::format("COMPUTERARCH: var-viewer not implemented"));
if (_scriptManager->getStateValue(StateKey_DebugCheats) == 1)
if (checkCode("GO????"))
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 07ed6d2e2b..35e3b89b09 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -39,7 +39,7 @@
namespace ZVision {
-RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat)
+RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat, bool doubleFPS)
: _engine(engine),
_system(engine->_system),
_workingWidth(workingWindow.width()),
@@ -51,7 +51,8 @@ RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowH
_backgroundWidth(0),
_backgroundHeight(0),
_backgroundOffset(0),
- _renderTable(_workingWidth, _workingHeight) {
+ _renderTable(_workingWidth, _workingHeight),
+ _doubleFPS(doubleFPS) {
_backgroundSurface.create(_workingWidth, _workingHeight, _pixelFormat);
_effectSurface.create(_workingWidth, _workingHeight, _pixelFormat);
@@ -1013,4 +1014,81 @@ void RenderManager::bkgFill(uint8 r, uint8 g, uint8 b) {
}
#endif
+void RenderManager::timedMessage(const Common::String &str, uint16 milsecs) {
+ uint16 msgid = createSubArea();
+ updateSubArea(msgid, str);
+ processSubs(0);
+ renderSceneToScreen();
+ deleteSubArea(msgid, milsecs);
+}
+
+bool RenderManager::askQuestion(const Common::String &str) {
+ uint16 msgid = createSubArea();
+ updateSubArea(msgid, str);
+ processSubs(0);
+ renderSceneToScreen();
+ _engine->stopClock();
+
+ int result = 0;
+
+ while (result == 0) {
+ Common::Event evnt;
+ while (_engine->getEventManager()->pollEvent(evnt)) {
+ if (evnt.type == Common::EVENT_KEYDOWN) {
+ switch (evnt.kbd.keycode) {
+ case Common::KEYCODE_y:
+ result = 2;
+ break;
+ case Common::KEYCODE_n:
+ result = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ _system->updateScreen();
+ if (_doubleFPS)
+ _system->delayMillis(33);
+ else
+ _system->delayMillis(66);
+ }
+ deleteSubArea(msgid);
+ _engine->startClock();
+ return result == 2;
+}
+
+void RenderManager::delayedMessage(const Common::String &str, uint16 milsecs) {
+ uint16 msgid = createSubArea();
+ updateSubArea(msgid, str);
+ processSubs(0);
+ renderSceneToScreen();
+ _engine->stopClock();
+
+ uint32 stopTime = _system->getMillis() + milsecs;
+ while (_system->getMillis() < stopTime) {
+ Common::Event evnt;
+ while (_engine->getEventManager()->pollEvent(evnt)) {
+ if (evnt.type == Common::EVENT_KEYDOWN &&
+ (evnt.kbd.keycode == Common::KEYCODE_SPACE ||
+ evnt.kbd.keycode == Common::KEYCODE_RETURN ||
+ evnt.kbd.keycode == Common::KEYCODE_ESCAPE))
+ break;
+ }
+ _system->updateScreen();
+ if (_doubleFPS)
+ _system->delayMillis(33);
+ else
+ _system->delayMillis(66);
+ }
+ deleteSubArea(msgid);
+ _engine->startClock();
+}
+
+void RenderManager::showDebugMsg(const Common::String &msg, int16 delay) {
+ uint16 msgid = createSubArea();
+ updateSubArea(msgid, msg);
+ deleteSubArea(msgid, delay);
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index d67ae29a3a..dbaa8fdc50 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -48,7 +48,7 @@ namespace ZVision {
class RenderManager {
public:
- RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat);
+ RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat, bool doubleFPS);
~RenderManager();
private:
@@ -137,6 +137,7 @@ private:
// Visual effects list
EffectsList _effects;
+ bool _doubleFPS;
public:
void initialize();
@@ -334,6 +335,11 @@ public:
// Fill background surface by color
void bkgFill(uint8 r, uint8 g, uint8 b);
#endif
+
+ bool askQuestion(const Common::String &str);
+ void delayedMessage(const Common::String &str, uint16 milsecs);
+ void timedMessage(const Common::String &str, uint16 milsecs);
+ void showDebugMsg(const Common::String &msg, int16 delay = 3000);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/save_control.cpp b/engines/zvision/scripting/controls/save_control.cpp
index 3a4dc47fe8..6cedddffeb 100644
--- a/engines/zvision/scripting/controls/save_control.cpp
+++ b/engines/zvision/scripting/controls/save_control.cpp
@@ -30,6 +30,7 @@
#include "zvision/text/string_manager.h"
#include "zvision/file/save_manager.h"
+#include "zvision/graphics/render_manager.h"
#include "common/str.h"
#include "common/stream.h"
@@ -97,18 +98,18 @@ bool SaveControl::process(uint32 deltaTimeInMillis) {
if (inp->getText().size() > 0) {
bool toSave = true;
if (iter->exist)
- if (!_engine->askQuestion(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEXIST)))
+ if (!_engine->getRenderManager()->askQuestion(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEXIST)))
toSave = false;
if (toSave) {
// FIXME: At this point, the screen shows the save control, so the save game thumbnails will always
// show the save control
_engine->getSaveManager()->saveGameBuffered(iter->saveId, inp->getText());
- _engine->delayedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVED), 2000);
+ _engine->getRenderManager()->delayedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVED), 2000);
_engine->getScriptManager()->changeLocation(_engine->getScriptManager()->getLastMenuLocation());
}
} else {
- _engine->timedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEMPTY), 2000);
+ _engine->getRenderManager()->timedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEMPTY), 2000);
}
} else {
_engine->getSaveManager()->loadGame(iter->saveId);
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index e9a4486ded..575a7af6ab 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -190,7 +190,7 @@ void ZVision::initialize() {
// Create managers
_scriptManager = new ScriptManager(this);
- _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat);
+ _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat, _doubleFPS);
_saveManager = new SaveManager(this);
_stringManager = new StringManager(this);
_cursorManager = new CursorManager(this, _resourcePixelFormat);
@@ -265,77 +265,6 @@ Common::Error ZVision::run() {
return Common::kNoError;
}
-bool ZVision::askQuestion(const Common::String &str) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, str);
- _renderManager->processSubs(0);
- _renderManager->renderSceneToScreen();
- _clock.stop();
-
- int result = 0;
-
- while (result == 0) {
- Common::Event evnt;
- while (_eventMan->pollEvent(evnt)) {
- if (evnt.type == Common::EVENT_KEYDOWN) {
- switch (evnt.kbd.keycode) {
- case Common::KEYCODE_y:
- result = 2;
- break;
- case Common::KEYCODE_n:
- result = 1;
- break;
- default:
- break;
- }
- }
- }
- _system->updateScreen();
- if (_doubleFPS)
- _system->delayMillis(33);
- else
- _system->delayMillis(66);
- }
- _renderManager->deleteSubArea(msgid);
- _clock.start();
- return result == 2;
-}
-
-void ZVision::delayedMessage(const Common::String &str, uint16 milsecs) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, str);
- _renderManager->processSubs(0);
- _renderManager->renderSceneToScreen();
- _clock.stop();
-
- uint32 stopTime = _system->getMillis() + milsecs;
- while (_system->getMillis() < stopTime) {
- Common::Event evnt;
- while (_eventMan->pollEvent(evnt)) {
- if (evnt.type == Common::EVENT_KEYDOWN &&
- (evnt.kbd.keycode == Common::KEYCODE_SPACE ||
- evnt.kbd.keycode == Common::KEYCODE_RETURN ||
- evnt.kbd.keycode == Common::KEYCODE_ESCAPE))
- break;
- }
- _system->updateScreen();
- if (_doubleFPS)
- _system->delayMillis(33);
- else
- _system->delayMillis(66);
- }
- _renderManager->deleteSubArea(msgid);
- _clock.start();
-}
-
-void ZVision::timedMessage(const Common::String &str, uint16 milsecs) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, str);
- _renderManager->processSubs(0);
- _renderManager->renderSceneToScreen();
- _renderManager->deleteSubArea(msgid, milsecs);
-}
-
void ZVision::pauseEngineIntern(bool pause) {
_mixer->pauseAll(pause);
@@ -506,44 +435,11 @@ uint16 ZVision::getMenuBarEnable() {
}
bool ZVision::ifQuit() {
- if (askQuestion(_stringManager->getTextLine(StringManager::ZVISION_STR_EXITPROMT))) {
+ if (_renderManager->askQuestion(_stringManager->getTextLine(StringManager::ZVISION_STR_EXITPROMT))) {
quitGame();
return true;
}
return false;
}
-void ZVision::pushKeyToCheatBuf(uint8 key) {
- for (int i = 0; i < KEYBUF_SIZE - 1; i++)
- _cheatBuffer[i] = _cheatBuffer[i + 1];
-
- _cheatBuffer[KEYBUF_SIZE - 1] = key;
-}
-
-bool ZVision::checkCode(const char *code) {
- int codeLen = strlen(code);
-
- if (codeLen > KEYBUF_SIZE)
- return false;
-
- for (int i = 0; i < codeLen; i++)
- if (code[i] != _cheatBuffer[KEYBUF_SIZE - codeLen + i] && code[i] != '?')
- return false;
-
- return true;
-}
-
-uint8 ZVision::getBufferedKey(uint8 pos) {
- if (pos >= KEYBUF_SIZE)
- return 0;
- else
- return _cheatBuffer[KEYBUF_SIZE - pos - 1];
-}
-
-void ZVision::showDebugMsg(const Common::String &msg, int16 delay) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, msg);
- _renderManager->deleteSubArea(msgid, delay);
-}
-
} // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index d3beae5e61..848b278f69 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -164,6 +164,14 @@ public:
uint8 getZvisionKey(Common::KeyCode scummKeyCode);
+ void startClock() {
+ _clock.start();
+ }
+
+ void stopClock() {
+ _clock.stop();
+ }
+
/**
* Play a video until it is finished. This is a blocking call. It will call
* _clock.stop() when the video starts and _clock.start() when the video finishes.
@@ -181,10 +189,6 @@ public:
Common::String generateSaveFileName(uint slot);
Common::String generateAutoSaveFileName();
- bool askQuestion(const Common::String &str);
- void delayedMessage(const Common::String &str, uint16 milsecs);
- void timedMessage(const Common::String &str, uint16 milsecs);
-
void setRenderDelay(uint);
bool canRender();
@@ -197,7 +201,6 @@ public:
bool ifQuit();
void checkBorders();
- void showDebugMsg(const Common::String &msg, int16 delay = 3000);
// Engine features
bool hasFeature(EngineFeature f) const;
--
cgit v1.2.3
From e8820d26e7d673f96c416f93dd16811107e94cb4 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 12:42:01 +0200
Subject: ZVISION: Fix a warning
---
engines/zvision/scripting/controls/input_control.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index e1e6e6ec9d..4abc0c9e1b 100644
--- a/engines/zvision/scripting/controls/input_control.cpp
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -223,7 +223,7 @@ bool InputControl::process(uint32 deltaTimeInMillis) {
if (needDraw) {
_animation->seekToFrame(_frame);
const Graphics::Surface *srf = _animation->decodeNextFrame();
- uint32 xx = _textRectangle.left + _txtWidth;
+ int16 xx = _textRectangle.left + _txtWidth;
if (xx >= _textRectangle.left + (_textRectangle.width() - (int16)_animation->getWidth()))
xx = _textRectangle.left + _textRectangle.width() - (int16)_animation->getWidth();
_engine->getRenderManager()->blitSurfaceToBkg(*srf, xx, _textRectangle.top);
--
cgit v1.2.3
From eea1ee445fcac7ecc53e31d258aac697d6b242f1 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 13:14:24 +0200
Subject: ZVISION: Move more graphics code out of the main engine code
---
engines/zvision/core/events.cpp | 17 ++-
engines/zvision/graphics/render_manager.cpp | 133 +++++++++++++++++++++++
engines/zvision/graphics/render_manager.h | 4 +
engines/zvision/scripting/actions.cpp | 5 +-
engines/zvision/scripting/script_manager.cpp | 5 +-
engines/zvision/zvision.cpp | 155 +--------------------------
engines/zvision/zvision.h | 17 +--
7 files changed, 167 insertions(+), 169 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 70fd425949..5f29a6879c 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -30,6 +30,7 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/scripting/menu.h"
#include "zvision/sound/zork_raw.h"
+#include "zvision/text/string_manager.h"
#include "common/events.h"
#include "common/system.h"
@@ -70,19 +71,19 @@ void ZVision::shortKeys(Common::Event event) {
if (event.kbd.hasFlags(Common::KBD_CTRL)) {
switch (event.kbd.keycode) {
case Common::KEYCODE_s:
- if (getMenuBarEnable() & kMenubarSave)
+ if (_menu->getEnable() & kMenubarSave)
_scriptManager->changeLocation('g', 'j', 's', 'e', 0);
break;
case Common::KEYCODE_r:
- if (getMenuBarEnable() & kMenubarRestore)
+ if (_menu->getEnable() & kMenubarRestore)
_scriptManager->changeLocation('g', 'j', 'r', 'e', 0);
break;
case Common::KEYCODE_p:
- if (getMenuBarEnable() & kMenubarSettings)
+ if (_menu->getEnable() & kMenubarSettings)
_scriptManager->changeLocation('g', 'j', 'p', 'e', 0);
break;
case Common::KEYCODE_q:
- if (getMenuBarEnable() & kMenubarExit)
+ if (_menu->getEnable() & kMenubarExit)
ifQuit();
break;
default:
@@ -482,4 +483,12 @@ uint8 ZVision::getZvisionKey(Common::KeyCode scummKeyCode) {
return 0;
}
+bool ZVision::ifQuit() {
+ if (_renderManager->askQuestion(_stringManager->getTextLine(StringManager::ZVISION_STR_EXITPROMT))) {
+ quitGame();
+ return true;
+ }
+ return false;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 35e3b89b09..0a48ae6c16 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -1091,4 +1091,137 @@ void RenderManager::showDebugMsg(const Common::String &msg, int16 delay) {
deleteSubArea(msgid, delay);
}
+void RenderManager::updateRotation() {
+ int16 _velocity = _engine->getMouseVelocity() + _engine->getKeyboardVelocity();
+ ScriptManager *scriptManager = _engine->getScriptManager();
+
+ if (_doubleFPS)
+ _velocity /= 2;
+
+ if (_velocity) {
+ RenderTable::RenderState renderState = _renderTable.getRenderState();
+ if (renderState == RenderTable::PANORAMA) {
+ int16 startPosition = scriptManager->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition + (_renderTable.getPanoramaReverse() ? -_velocity : _velocity);
+
+ int16 zeroPoint = _renderTable.getPanoramaZeroPoint();
+ if (startPosition >= zeroPoint && newPosition < zeroPoint)
+ scriptManager->setStateValue(StateKey_Rounds, scriptManager->getStateValue(StateKey_Rounds) - 1);
+ if (startPosition <= zeroPoint && newPosition > zeroPoint)
+ scriptManager->setStateValue(StateKey_Rounds, scriptManager->getStateValue(StateKey_Rounds) + 1);
+
+ int16 screenWidth = getBkgSize().x;
+ if (screenWidth)
+ newPosition %= screenWidth;
+
+ if (newPosition < 0)
+ newPosition += screenWidth;
+
+ setBackgroundPosition(newPosition);
+ } else if (renderState == RenderTable::TILT) {
+ int16 startPosition = scriptManager->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition + _velocity;
+
+ int16 screenHeight = getBkgSize().y;
+ int16 tiltGap = _renderTable.getTiltGap();
+
+ if (newPosition >= (screenHeight - tiltGap))
+ newPosition = screenHeight - tiltGap;
+ if (newPosition <= tiltGap)
+ newPosition = tiltGap;
+
+ setBackgroundPosition(newPosition);
+ }
+ }
+}
+
+void RenderManager::checkBorders() {
+ RenderTable::RenderState renderState = _renderTable.getRenderState();
+ if (renderState == RenderTable::PANORAMA) {
+ int16 startPosition = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition;
+
+ int16 screenWidth = getBkgSize().x;
+
+ if (screenWidth)
+ newPosition %= screenWidth;
+
+ if (newPosition < 0)
+ newPosition += screenWidth;
+
+ if (startPosition != newPosition)
+ setBackgroundPosition(newPosition);
+ } else if (renderState == RenderTable::TILT) {
+ int16 startPosition = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition;
+
+ int16 screenHeight = getBkgSize().y;
+ int16 tiltGap = _renderTable.getTiltGap();
+
+ if (newPosition >= (screenHeight - tiltGap))
+ newPosition = screenHeight - tiltGap;
+ if (newPosition <= tiltGap)
+ newPosition = tiltGap;
+
+ if (startPosition != newPosition)
+ setBackgroundPosition(newPosition);
+ }
+}
+
+void RenderManager::rotateTo(int16 _toPos, int16 _time) {
+ if (_renderTable.getRenderState() != RenderTable::PANORAMA)
+ return;
+
+ if (_time == 0)
+ _time = 1;
+
+ int32 maxX = getBkgSize().x;
+ int32 curX = getCurrentBackgroundOffset();
+ int32 dx = 0;
+
+ if (curX == _toPos)
+ return;
+
+ if (curX > _toPos) {
+ if (curX - _toPos > maxX / 2)
+ dx = (_toPos + (maxX - curX)) / _time;
+ else
+ dx = -(curX - _toPos) / _time;
+ } else {
+ if (_toPos - curX > maxX / 2)
+ dx = -((maxX - _toPos) + curX) / _time;
+ else
+ dx = (_toPos - curX) / _time;
+ }
+
+ _engine->stopClock();
+
+ for (int16 i = 0; i <= _time; i++) {
+ if (i == _time)
+ curX = _toPos;
+ else
+ curX += dx;
+
+ if (curX < 0)
+ curX = maxX - curX;
+ else if (curX >= maxX)
+ curX %= maxX;
+
+ setBackgroundPosition(curX);
+
+ prepareBackground();
+ renderSceneToScreen();
+
+ _system->updateScreen();
+
+ _system->delayMillis(500 / _time);
+ }
+
+ _engine->startClock();
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index dbaa8fdc50..30e51456e9 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -340,6 +340,10 @@ public:
void delayedMessage(const Common::String &str, uint16 milsecs);
void timedMessage(const Common::String &str, uint16 milsecs);
void showDebugMsg(const Common::String &msg, int16 delay = 3000);
+
+ void checkBorders();
+ void rotateTo(int16 to, int16 time);
+ void updateRotation();
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index c26a93f529..7c3463b6d0 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -30,6 +30,7 @@
#include "zvision/sound/zork_raw.h"
#include "zvision/video/zork_avi_decoder.h"
#include "zvision/file/save_manager.h"
+#include "zvision/scripting/menu.h"
#include "zvision/scripting/sidefx/timer_node.h"
#include "zvision/scripting/sidefx/music_node.h"
#include "zvision/scripting/sidefx/syncsound_node.h"
@@ -439,7 +440,7 @@ ActionMenuBarEnable::ActionMenuBarEnable(ZVision *engine, int32 slotkey, const C
}
bool ActionMenuBarEnable::execute() {
- _engine->menuBarEnable(_menus);
+ _engine->getMenuHandler()->setEnable(_menus);
return true;
}
@@ -819,7 +820,7 @@ ActionRotateTo::ActionRotateTo(ZVision *engine, int32 slotkey, const Common::Str
}
bool ActionRotateTo::execute() {
- _engine->rotateTo(_toPos, _time);
+ _engine->getRenderManager()->rotateTo(_toPos, _time);
return true;
}
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
index 2a4aa5fed0..1a2b8362f5 100644
--- a/engines/zvision/scripting/script_manager.cpp
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -29,6 +29,7 @@
#include "zvision/graphics/cursors/cursor_manager.h"
#include "zvision/file/save_manager.h"
#include "zvision/scripting/actions.h"
+#include "zvision/scripting/menu.h"
#include "zvision/scripting/sidefx/timer_node.h"
#include "common/algorithm.h"
@@ -583,7 +584,7 @@ void ScriptManager::ChangeLocationReal() {
_referenceTable.clear();
addPuzzlesToReferenceTable(universe);
- _engine->menuBarEnable(0xFFFF);
+ _engine->getMenuHandler()->setEnable(0xFFFF);
if (_nextLocation.world != _currentLocation.world) {
cleanScriptScope(nodeview);
@@ -652,7 +653,7 @@ void ScriptManager::ChangeLocationReal() {
execScope(nodeview);
}
- _engine->checkBorders();
+ _engine->getRenderManager()->checkBorders();
}
void ScriptManager::serialize(Common::WriteStream *stream) {
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 575a7af6ab..bd215f4f62 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -232,7 +232,7 @@ Common::Error ZVision::run() {
_cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem));
processEvents();
- updateRotation();
+ _renderManager->updateRotation();
_scriptManager->update(deltaTime);
_menu->process(deltaTime);
@@ -244,7 +244,7 @@ Common::Error ZVision::run() {
_renderManager->renderSceneToScreen();
// Update the screen
- if (_frameRenderDelay <= 0) {
+ if (canRender()) {
_system->updateScreen();
} else {
_frameRenderDelay--;
@@ -291,155 +291,4 @@ bool ZVision::canRender() {
return _frameRenderDelay <= 0;
}
-void ZVision::updateRotation() {
- int16 _velocity = _mouseVelocity + _keyboardVelocity;
-
- if (_doubleFPS)
- _velocity /= 2;
-
- if (_velocity) {
- RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
- if (renderState == RenderTable::PANORAMA) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition + (_renderManager->getRenderTable()->getPanoramaReverse() ? -_velocity : _velocity);
-
- int16 zeroPoint = _renderManager->getRenderTable()->getPanoramaZeroPoint();
- if (startPosition >= zeroPoint && newPosition < zeroPoint)
- _scriptManager->setStateValue(StateKey_Rounds, _scriptManager->getStateValue(StateKey_Rounds) - 1);
- if (startPosition <= zeroPoint && newPosition > zeroPoint)
- _scriptManager->setStateValue(StateKey_Rounds, _scriptManager->getStateValue(StateKey_Rounds) + 1);
-
- int16 screenWidth = _renderManager->getBkgSize().x;
- if (screenWidth)
- newPosition %= screenWidth;
-
- if (newPosition < 0)
- newPosition += screenWidth;
-
- _renderManager->setBackgroundPosition(newPosition);
- } else if (renderState == RenderTable::TILT) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition + _velocity;
-
- int16 screenHeight = _renderManager->getBkgSize().y;
- int16 tiltGap = _renderManager->getRenderTable()->getTiltGap();
-
- if (newPosition >= (screenHeight - tiltGap))
- newPosition = screenHeight - tiltGap;
- if (newPosition <= tiltGap)
- newPosition = tiltGap;
-
- _renderManager->setBackgroundPosition(newPosition);
- }
- }
-}
-
-void ZVision::checkBorders() {
- RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
- if (renderState == RenderTable::PANORAMA) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition;
-
- int16 screenWidth = _renderManager->getBkgSize().x;
-
- if (screenWidth)
- newPosition %= screenWidth;
-
- if (newPosition < 0)
- newPosition += screenWidth;
-
- if (startPosition != newPosition)
- _renderManager->setBackgroundPosition(newPosition);
- } else if (renderState == RenderTable::TILT) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition;
-
- int16 screenHeight = _renderManager->getBkgSize().y;
- int16 tiltGap = _renderManager->getRenderTable()->getTiltGap();
-
- if (newPosition >= (screenHeight - tiltGap))
- newPosition = screenHeight - tiltGap;
- if (newPosition <= tiltGap)
- newPosition = tiltGap;
-
- if (startPosition != newPosition)
- _renderManager->setBackgroundPosition(newPosition);
- }
-}
-
-void ZVision::rotateTo(int16 _toPos, int16 _time) {
- if (_renderManager->getRenderTable()->getRenderState() != RenderTable::PANORAMA)
- return;
-
- if (_time == 0)
- _time = 1;
-
- int32 maxX = _renderManager->getBkgSize().x;
- int32 curX = _renderManager->getCurrentBackgroundOffset();
- int32 dx = 0;
-
- if (curX == _toPos)
- return;
-
- if (curX > _toPos) {
- if (curX - _toPos > maxX / 2)
- dx = (_toPos + (maxX - curX)) / _time;
- else
- dx = -(curX - _toPos) / _time;
- } else {
- if (_toPos - curX > maxX / 2)
- dx = -((maxX - _toPos) + curX) / _time;
- else
- dx = (_toPos - curX) / _time;
- }
-
- _clock.stop();
-
- for (int16 i = 0; i <= _time; i++) {
- if (i == _time)
- curX = _toPos;
- else
- curX += dx;
-
- if (curX < 0)
- curX = maxX - curX;
- else if (curX >= maxX)
- curX %= maxX;
-
- _renderManager->setBackgroundPosition(curX);
-
- _renderManager->prepareBackground();
- _renderManager->renderSceneToScreen();
-
- _system->updateScreen();
-
- _system->delayMillis(500 / _time);
- }
-
- _clock.start();
-}
-
-void ZVision::menuBarEnable(uint16 menus) {
- if (_menu)
- _menu->setEnable(menus);
-}
-
-uint16 ZVision::getMenuBarEnable() {
- if (_menu)
- return _menu->getEnable();
- return 0;
-}
-
-bool ZVision::ifQuit() {
- if (_renderManager->askQuestion(_stringManager->getTextLine(StringManager::ZVISION_STR_EXITPROMT))) {
- quitGame();
- return true;
- }
- return false;
-}
-
} // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 848b278f69..dc1ac1b8cb 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -155,12 +155,21 @@ public:
MidiManager *getMidiManager() const {
return _midiManager;
}
+ MenuHandler *getMenuHandler() const {
+ return _menu;
+ }
Common::RandomSource *getRandomSource() const {
return _rnd;
}
ZVisionGameId getGameId() const {
return _gameDescription->gameId;
}
+ int16 getKeyboardVelocity() const {
+ return _keyboardVelocity;
+ }
+ int16 getMouseVelocity() const {
+ return _mouseVelocity;
+ }
uint8 getZvisionKey(Common::KeyCode scummKeyCode);
@@ -184,8 +193,6 @@ public:
void playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect = Common::Rect(0, 0, 0, 0), bool skippable = true, Subtitle *sub = NULL);
Video::VideoDecoder *loadAnimation(const Common::String &fileName);
- void rotateTo(int16 to, int16 time);
-
Common::String generateSaveFileName(uint slot);
Common::String generateAutoSaveFileName();
@@ -195,13 +202,8 @@ public:
void loadSettings();
void saveSettings();
- void menuBarEnable(uint16 menus);
- uint16 getMenuBarEnable();
-
bool ifQuit();
- void checkBorders();
-
// Engine features
bool hasFeature(EngineFeature f) const;
bool canLoadGameStateCurrently();
@@ -218,7 +220,6 @@ private:
void processEvents();
void onMouseMove(const Common::Point &pos);
- void updateRotation();
void registerDefaultSettings();
void shortKeys(Common::Event);
--
cgit v1.2.3
From e5f0ee2271f4a43ff05b82380ab22eade9763702 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 18:22:18 +0200
Subject: ZVISION: Implement auto-saving
---
engines/zvision/detection.cpp | 5 +++++
engines/zvision/file/save_manager.cpp | 14 +++++---------
engines/zvision/file/save_manager.h | 10 +++++++---
engines/zvision/scripting/script_manager.cpp | 4 ----
engines/zvision/zvision.cpp | 8 ++++----
engines/zvision/zvision.h | 1 -
6 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index a361239e9e..4fcb5c040b 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -308,6 +308,11 @@ SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, in
if (successfulRead) {
SaveStateDescriptor desc(slot, header.saveName);
+ // Do not allow save slot 0 (used for auto-saving) to be deleted or
+ // overwritten.
+ desc.setDeletableFlag(slot != 0);
+ desc.setWriteProtectedFlag(slot == 0);
+
desc.setThumbnail(header.thumbnail);
if (header.version > 0) {
diff --git a/engines/zvision/file/save_manager.cpp b/engines/zvision/file/save_manager.cpp
index 05df834497..042fafd38e 100644
--- a/engines/zvision/file/save_manager.cpp
+++ b/engines/zvision/file/save_manager.cpp
@@ -87,6 +87,8 @@ void SaveManager::saveGame(uint slot, const Common::String &saveName) {
file->finalize();
delete file;
+
+ _lastSaveTime = g_system->getMillis();
}
void SaveManager::saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream) {
@@ -99,6 +101,8 @@ void SaveManager::saveGame(uint slot, const Common::String &saveName, Common::Me
file->finalize();
delete file;
+
+ _lastSaveTime = g_system->getMillis();
}
void SaveManager::saveGameBuffered(uint slot, const Common::String &saveName) {
@@ -109,15 +113,7 @@ void SaveManager::saveGameBuffered(uint slot, const Common::String &saveName) {
}
void SaveManager::autoSave() {
- Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName());
-
- writeSaveGameHeader(file, "auto");
-
- _engine->getScriptManager()->serialize(file);
-
- // Cleanup
- file->finalize();
- delete file;
+ saveGame(0, "Auto save");
}
void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName) {
diff --git a/engines/zvision/file/save_manager.h b/engines/zvision/file/save_manager.h
index 75841331e7..fc8db67566 100644
--- a/engines/zvision/file/save_manager.h
+++ b/engines/zvision/file/save_manager.h
@@ -48,13 +48,18 @@ struct SaveGameHeader {
class SaveManager {
public:
- SaveManager(ZVision *engine) : _engine(engine), _tempSave(NULL) {}
+ SaveManager(ZVision *engine) : _engine(engine), _tempSave(NULL), _lastSaveTime(0) {}
~SaveManager() {
flushSaveBuffer();
}
+ uint32 getLastSaveTime() const {
+ return _lastSaveTime;
+ }
+
private:
ZVision *_engine;
+ uint32 _lastSaveTime;
static const uint32 SAVEGAME_ID;
enum {
@@ -67,8 +72,7 @@ private:
public:
/**
* Called every room change. Saves the state of the room just before
- * we switched rooms. Uses ZVision::generateAutoSaveFileName() to
- * create the save file name.
+ * the room changes.
*/
void autoSave();
/**
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
index 1a2b8362f5..d0ebb18944 100644
--- a/engines/zvision/scripting/script_manager.cpp
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -569,10 +569,6 @@ void ScriptManager::ChangeLocationReal() {
} else {
if (_currentLocation.world == 'g' && _currentLocation.room == 'j')
_engine->getSaveManager()->flushSaveBuffer();
- else {
- // Auto save
- //_engine->getSaveManager()->autoSave();
- }
}
setStateValue(StateKey_World, _nextLocation.world);
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index bd215f4f62..b3fc02ee15 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -259,6 +259,10 @@ Common::Error ZVision::run() {
delay >>= 1;
}
+ if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) {
+ _saveManager->autoSave();
+ }
+
_system->delayMillis(delay);
}
@@ -279,10 +283,6 @@ Common::String ZVision::generateSaveFileName(uint slot) {
return Common::String::format("%s.%03u", _targetName.c_str(), slot);
}
-Common::String ZVision::generateAutoSaveFileName() {
- return Common::String::format("%s.auto", _targetName.c_str());
-}
-
void ZVision::setRenderDelay(uint delay) {
_frameRenderDelay = delay;
}
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index dc1ac1b8cb..6664d0cd5d 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -194,7 +194,6 @@ public:
Video::VideoDecoder *loadAnimation(const Common::String &fileName);
Common::String generateSaveFileName(uint slot);
- Common::String generateAutoSaveFileName();
void setRenderDelay(uint);
bool canRender();
--
cgit v1.2.3
From 2becc76d5c16d15d5a7a6733b40f7c59e7391c12 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 19:56:37 +0200
Subject: ZVISION: Correct the script names of the location-specific cheats
---
engines/zvision/core/events.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 5f29a6879c..4438474078 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -119,9 +119,9 @@ void ZVision::cheatCodes(uint8 key) {
}
// There are 3 more cheats in script files:
- // - "EAT ME": gjcr.scr
- // - "WHOAMI": hp1e.scr
- // - "HUISOK": uh1f.scr
+ // - "WHOAMI": gjcr.scr
+ // - "HUISOK": hp1e.scr
+ // - "EAT ME": uh1f.scr
} else if (getGameId() == GID_NEMESIS) {
if (checkCode("CHLOE")) {
_scriptManager->changeLocation('t', 'm', '2', 'g', 0);
--
cgit v1.2.3
From db37cfb1b04fb6d1fb21ef3bd3c0b90128bf4d89 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 22:30:32 +0200
Subject: ZVISION: Remove duplicate blitting code for images and animations
---
engines/zvision/graphics/render_manager.cpp | 67 +++++-----------------
engines/zvision/graphics/render_manager.h | 11 +---
engines/zvision/scripting/actions.cpp | 12 ++++
.../zvision/scripting/sidefx/animation_node.cpp | 10 +---
engines/zvision/text/text.cpp | 7 ++-
5 files changed, 36 insertions(+), 71 deletions(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 0a48ae6c16..7bbde81e4c 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -104,7 +104,8 @@ void RenderManager::renderSceneToScreen() {
post = (*it)->draw(_currentBackgroundImage.getSubArea(rect));
else
post = (*it)->draw(_effectSurface.getSubArea(rect));
- blitSurfaceToSurface(*post, _effectSurface, screenSpaceLocation.left, screenSpaceLocation.top);
+ Common::Rect empty;
+ blitSurfaceToSurface(*post, empty, _effectSurface, screenSpaceLocation.left, screenSpaceLocation.top);
screenSpaceLocation.clip(windowRect);
if (_backgroundSurfaceDirtyRect .isEmpty()) {
_backgroundSurfaceDirtyRect = screenSpaceLocation;
@@ -511,30 +512,12 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
delete srcAdapted;
}
-void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y) {
+void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, int32 colorkey) {
Common::Rect empt;
- blitSurfaceToSurface(src, empt, dst, x, y);
-}
-
-void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y, uint32 colorkey) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, dst, x, y, colorkey);
-}
-
-void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y);
- Common::Rect dirty(src.w, src.h);
- dirty.translate(x, y);
- if (_backgroundDirtyRect.isEmpty())
- _backgroundDirtyRect = dirty;
+ if (colorkey >= 0)
+ blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y, colorkey);
else
- _backgroundDirtyRect.extend(dirty);
-}
-
-void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, uint32 colorkey) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y, colorkey);
+ blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y);
Common::Rect dirty(src.w, src.h);
dirty.translate(x, y);
if (_backgroundDirtyRect.isEmpty())
@@ -543,23 +526,10 @@ void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y,
_backgroundDirtyRect.extend(dirty);
}
-void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect) {
- if (src.w == _dstRect.width() && src.h == _dstRect.height())
- blitSurfaceToBkg(src, _dstRect.left, _dstRect.top);
- else {
- Graphics::Surface *tmp = new Graphics::Surface;
- tmp->create(_dstRect.width(), _dstRect.height(), src.format);
- scaleBuffer(src.getPixels(), tmp->getPixels(), src.w, src.h, src.format.bytesPerPixel, _dstRect.width(), _dstRect.height());
- blitSurfaceToBkg(*tmp, _dstRect.left, _dstRect.top);
- tmp->free();
- delete tmp;
- }
-}
-
-void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, uint32 colorkey) {
- if (src.w == _dstRect.width() && src.h == _dstRect.height())
+void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, int32 colorkey) {
+ if (src.w == _dstRect.width() && src.h == _dstRect.height()) {
blitSurfaceToBkg(src, _dstRect.left, _dstRect.top, colorkey);
- else {
+ } else {
Graphics::Surface *tmp = new Graphics::Surface;
tmp->create(_dstRect.width(), _dstRect.height(), src.format);
scaleBuffer(src.getPixels(), tmp->getPixels(), src.w, src.h, src.format.bytesPerPixel, _dstRect.width(), _dstRect.height());
@@ -569,20 +539,12 @@ void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const C
}
}
-void RenderManager::blitSurfaceToMenu(const Graphics::Surface &src, int x, int y) {
+void RenderManager::blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, int32 colorkey) {
Common::Rect empt;
- blitSurfaceToSurface(src, empt, _menuSurface, x, y);
- Common::Rect dirty(src.w, src.h);
- dirty.translate(x, y);
- if (_menuSurfaceDirtyRect.isEmpty())
- _menuSurfaceDirtyRect = dirty;
+ if (colorkey >= 0)
+ blitSurfaceToSurface(src, empt, _menuSurface, x, y, colorkey);
else
- _menuSurfaceDirtyRect.extend(dirty);
-}
-
-void RenderManager::blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, uint32 colorkey) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, _menuSurface, x, y, colorkey);
+ blitSurfaceToSurface(src, empt, _menuSurface, x, y);
Common::Rect dirty(src.w, src.h);
dirty.translate(x, y);
if (_menuSurfaceDirtyRect.isEmpty())
@@ -803,7 +765,8 @@ void RenderManager::processSubs(uint16 deltatime) {
Graphics::Surface *rndr = new Graphics::Surface();
rndr->create(sub->r.width(), sub->r.height(), _engine->_resourcePixelFormat);
_engine->getTextRenderer()->drawTxtInOneLine(sub->txt, *rndr);
- blitSurfaceToSurface(*rndr, _subtitleSurface, sub->r.left - _subtitleArea.left + _workingWindow.left, sub->r.top - _subtitleArea.top + _workingWindow.top);
+ Common::Rect empty;
+ blitSurfaceToSurface(*rndr, empty, _subtitleSurface, sub->r.left - _subtitleArea.left + _workingWindow.left, sub->r.top - _subtitleArea.top + _workingWindow.top);
rndr->free();
delete rndr;
}
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index 30e51456e9..a7e49b7758 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -230,20 +230,15 @@ public:
// Blitting surface-to-surface methods
void blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int x, int y);
void blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y, uint32 colorkey);
- void blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y);
- void blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y, uint32 colorkey);
// Blitting surface-to-background methods
- void blitSurfaceToBkg(const Graphics::Surface &src, int x, int y);
- void blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, uint32 colorkey);
+ void blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, int32 colorkey = -1);
// Blitting surface-to-background methods with scale
- void blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect);
- void blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, uint32 colorkey);
+ void blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, int32 colorkey = -1);
// Blitting surface-to-menu methods
- void blitSurfaceToMenu(const Graphics::Surface &src, int x, int y);
- void blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, uint32 colorkey);
+ void blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, int32 colorkey = -1);
// Subtitles methods
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 7c3463b6d0..a91476760d 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -566,6 +566,12 @@ ActionPreloadAnimation::ActionPreloadAnimation(ZVision *engine, int32 slotkey, c
// The two %*u are usually 0 and dont seem to have a use
sscanf(line.c_str(), "%24s %*u %*u %d %d", fileName, &_mask, &_framerate);
+ // Mask 0 means "no transparency" in this case. Since we use a common blitting
+ // code for images and animations, we set it to -1 to avoid confusion with
+ // color 0, which is used as a mask in some images
+ if (_mask == 0)
+ _mask = -1;
+
_fileName = Common::String(fileName);
}
@@ -628,6 +634,12 @@ ActionPlayAnimation::ActionPlayAnimation(ZVision *engine, int32 slotkey, const C
"%24s %u %u %u %u %u %u %d %*u %*u %d %d",
fileName, &_x, &_y, &_x2, &_y2, &_start, &_end, &_loopCount, &_mask, &_framerate);
+ // Mask 0 means "no transparency" in this case. Since we use a common blitting
+ // code for images and animations, we set it to -1 to avoid confusion with
+ // color 0, which is used as a mask in some images
+ if (_mask == 0)
+ _mask = -1;
+
_fileName = Common::String(fileName);
}
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index b966aa9cb8..7759758f56 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -154,17 +154,11 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) {
Graphics::Surface *transposed = RenderManager::tranposeSurface(frame);
- if (_mask > 0)
- _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
- else
- _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top);
+ _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
transposed->free();
delete transposed;
} else {
- if (_mask > 0)
- _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
- else
- _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top);
+ _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
}
}
}
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index f28ba6ade3..a5ed044424 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -462,15 +462,16 @@ void TextRenderer::drawTxtInOneLine(const Common::String &text, Graphics::Surfac
j++;
}
dx = 0;
+ Common::Rect empty;
for (int32 jj = 0; jj < j; jj++) {
if (TxtJustify[i] == TXT_JUSTIFY_LEFT)
- _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], dst, dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
+ _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], empty, dst, dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
else if (TxtJustify[i] == TXT_JUSTIFY_CENTER)
- _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], dst, ((dst.w - width) / 2) + dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
+ _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], empty, dst, ((dst.w - width) / 2) + dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
else if (TxtJustify[i] == TXT_JUSTIFY_RIGHT)
- _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], dst, dst.w - width + dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
+ _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], empty, dst, dst.w - width + dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
dx += TxtSurfaces[i][jj]->w;
}
--
cgit v1.2.3
From a9701d04c17b6f565e5602f12546bfe7aa2848af Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 22:35:02 +0200
Subject: ZVISION: Remove duplicate image loading code
---
engines/zvision/graphics/render_manager.cpp | 14 ++------------
engines/zvision/graphics/render_manager.h | 6 ++----
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 7bbde81e4c..73483f2309 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -568,28 +568,18 @@ Graphics::Surface *RenderManager::getBkgRect(Common::Rect &rect) {
return srf;
}
-Graphics::Surface *RenderManager::loadImage(Common::String &file) {
+Graphics::Surface *RenderManager::loadImage(Common::String file) {
Graphics::Surface *tmp = new Graphics::Surface;
readImageToSurface(file, *tmp);
return tmp;
}
-Graphics::Surface *RenderManager::loadImage(const char *file) {
- Common::String str = Common::String(file);
- return loadImage(str);
-}
-
-Graphics::Surface *RenderManager::loadImage(Common::String &file, bool transposed) {
+Graphics::Surface *RenderManager::loadImage(Common::String file, bool transposed) {
Graphics::Surface *tmp = new Graphics::Surface;
readImageToSurface(file, *tmp, transposed);
return tmp;
}
-Graphics::Surface *RenderManager::loadImage(const char *file, bool transposed) {
- Common::String str = Common::String(file);
- return loadImage(str, transposed);
-}
-
void RenderManager::prepareBackground() {
_backgroundDirtyRect.clip(_backgroundWidth, _backgroundHeight);
RenderTable::RenderState state = _renderTable.getRenderState();
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index a7e49b7758..d9a6c88896 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -263,10 +263,8 @@ public:
Graphics::Surface *getBkgRect(Common::Rect &rect);
// Load image into new surface
- Graphics::Surface *loadImage(const char *file);
- Graphics::Surface *loadImage(Common::String &file);
- Graphics::Surface *loadImage(const char *file, bool transposed);
- Graphics::Surface *loadImage(Common::String &file, bool transposed);
+ Graphics::Surface *loadImage(Common::String file);
+ Graphics::Surface *loadImage(Common::String file, bool transposed);
// Clear whole/area of menu surface
void clearMenuSurface();
--
cgit v1.2.3
From 85142cd0d7fb6e24fc45b2c61611f848b8c4a102 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 22:48:58 +0200
Subject: ZVISION: Remove duplicate subtitle code
---
engines/zvision/graphics/render_manager.cpp | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 73483f2309..4f7b16c833 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -698,18 +698,9 @@ uint16 RenderManager::createSubArea(const Common::Rect &area) {
}
uint16 RenderManager::createSubArea() {
- _subid++;
-
- OneSubtitle sub;
- sub.redraw = false;
- sub.timer = -1;
- sub.todelete = false;
- sub.r = Common::Rect(_subtitleArea.left, _subtitleArea.top, _subtitleArea.right, _subtitleArea.bottom);
- sub.r.translate(-_workingWindow.left, -_workingWindow.top);
-
- _subsList[_subid] = sub;
-
- return _subid;
+ Common::Rect r(_subtitleArea.left, _subtitleArea.top, _subtitleArea.right, _subtitleArea.bottom);
+ r.translate(-_workingWindow.left, -_workingWindow.top);
+ return createSubArea(r);
}
void RenderManager::deleteSubArea(uint16 id) {
--
cgit v1.2.3
From 19ce38d40e9f273335b06a62bcb0d3643602080c Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 22:51:33 +0200
Subject: ZVISION: Turn off subtitles, if requested
---
engines/zvision/graphics/render_manager.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 4f7b16c833..4f26123fc8 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -737,7 +737,7 @@ void RenderManager::processSubs(uint16 deltatime) {
}
}
- if (redraw) {
+ if (redraw && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1) {
_subtitleSurface.fillRect(Common::Rect(_subtitleSurface.w, _subtitleSurface.h), 0);
for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
--
cgit v1.2.3
From f9595b11fc2bef08d84a00b81f9b2884f77897b0 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 26 Dec 2014 23:18:54 +0200
Subject: ZVISION: Add an FPS timer (accessible with F10, or the "FRAME" cheat)
---
engines/zvision/core/events.cpp | 18 +++++++++++++-----
engines/zvision/zvision.cpp | 19 ++++++++++++++++++-
engines/zvision/zvision.h | 7 +++++++
3 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 4438474078..7804130e2a 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -158,15 +158,18 @@ void ZVision::cheatCodes(uint8 key) {
}
}
- if (checkCode("FRAME"))
- _renderManager->showDebugMsg(Common::String::format("FPS: ???, not implemented"));
+ if (checkCode("FRAME")) {
+ Common::String fpsStr = Common::String::format("FPS: %d", getFPS());
+ _renderManager->showDebugMsg(fpsStr);
+ }
+
+ if (checkCode("COMPUTERARCH"))
+ _renderManager->showDebugMsg("COMPUTERARCH: var-viewer not implemented");
+ // This cheat essentially toggles the GOxxxx cheat below
if (checkCode("XYZZY"))
_scriptManager->setStateValue(StateKey_DebugCheats, 1 - _scriptManager->getStateValue(StateKey_DebugCheats));
- if (checkCode("COMPUTERARCH"))
- _renderManager->showDebugMsg(Common::String::format("COMPUTERARCH: var-viewer not implemented"));
-
if (_scriptManager->getStateValue(StateKey_DebugCheats) == 1)
if (checkCode("GO????"))
_scriptManager->changeLocation(getBufferedKey(3),
@@ -240,6 +243,11 @@ void ZVision::processEvents() {
_scriptManager->getStateValue(StateKey_KbdRotateSpeed)) * 2;
break;
+ case Common::KEYCODE_F10: {
+ Common::String fpsStr = Common::String::format("FPS: %d", getFPS());
+ _renderManager->showDebugMsg(fpsStr);
+ }
+ break;
default:
break;
}
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index b3fc02ee15..615574bbcd 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -101,7 +101,9 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
_frameRenderDelay(2),
_keyboardVelocity(0),
_mouseVelocity(0),
- _videoIsPlaying(false) {
+ _videoIsPlaying(false),
+ _renderedFrameCount(0),
+ _fps(0) {
debug(1, "ZVision::ZVision");
@@ -130,6 +132,8 @@ ZVision::~ZVision() {
delete _rnd;
delete _midiManager;
+ getTimerManager()->removeTimerProc(&fpsTimerCallback);
+
// Remove all of our debug levels
DebugMan.clearAllDebugChannels();
}
@@ -214,6 +218,9 @@ void ZVision::initialize() {
// Create debugger console. It requires GFX to be initialized
_console = new Console(this);
_doubleFPS = ConfMan.getBool("doublefps");
+
+ // Initialize FPS timer callback
+ getTimerManager()->installTimerProc(&fpsTimerCallback, 1000000, this, "zvisionFPS");
}
Common::Error ZVision::run() {
@@ -246,6 +253,7 @@ Common::Error ZVision::run() {
// Update the screen
if (canRender()) {
_system->updateScreen();
+ _renderedFrameCount++;
} else {
_frameRenderDelay--;
}
@@ -291,4 +299,13 @@ bool ZVision::canRender() {
return _frameRenderDelay <= 0;
}
+void ZVision::fpsTimerCallback(void *refCon) {
+ ((ZVision *)refCon)->fpsTimer();
+}
+
+void ZVision::fpsTimer() {
+ _fps = _renderedFrameCount;
+ _renderedFrameCount = 0;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 6664d0cd5d..5482060cd0 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -119,6 +119,8 @@ private:
Common::Event _event;
int _frameRenderDelay;
+ int _renderedFrameCount;
+ int _fps;
int16 _mouseVelocity;
int16 _keyboardVelocity;
bool _doubleFPS;
@@ -197,6 +199,11 @@ public:
void setRenderDelay(uint);
bool canRender();
+ static void fpsTimerCallback(void *refCon);
+ void fpsTimer();
+ int getFPS() const {
+ return _fps;
+ }
void loadSettings();
void saveSettings();
--
cgit v1.2.3
From eb46e837969f2f650b5debaa387e63127b83db6c Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 27 Dec 2014 00:00:07 +0200
Subject: ZVISION: Quit with an error message dialog if no font files are found
---
engines/zvision/zvision.cpp | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 615574bbcd..fe8e129800 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -46,8 +46,8 @@
#include "common/system.h"
#include "common/file.h"
+#include "gui/message.h"
#include "engines/util.h"
-
#include "audio/mixer.h"
namespace ZVision {
@@ -230,6 +230,22 @@ Common::Error ZVision::run() {
if (ConfMan.hasKey("save_slot"))
_saveManager->loadGame(ConfMan.getInt("save_slot"));
+ // Before starting, make absolutely sure that the user has copied the needed fonts
+ if (!Common::File::exists("arial.ttf") && !Common::File::exists("FreeSans.ttf")) {
+ GUI::MessageDialog dialog(
+ "Before playing this game, you'll need to copy the required "
+ "fonts in ScummVM's extras directory, or the game directory. "
+ "On Windows, you'll need the following font files from the Windows "
+ "font directory: Times New Roman, Century Schoolbook, Garamond, "
+ "Courier New and Arial. Alternatively, you can download the GNU "
+ "FreeFont package. You'll need all the fonts from that package, "
+ "i.e. FreeMono, FreeSans and FreeSerif."
+ );
+ dialog.runModal();
+ quitGame();
+ return Common::kUnknownError;
+ }
+
// Main loop
while (!shouldQuit()) {
_clock.update();
--
cgit v1.2.3
From fd34456bb8bcbf39667df50eb6d14a9f4fbe7087 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 27 Dec 2014 01:02:51 +0200
Subject: ZVISION: Delete the render manager after the script manager on quit
This is necessary, as the script manager may include references to the
render manager, such as side effects in Zork: Nemesis. Fixes a crash on
engine exit when the current scene contains such effects
---
engines/zvision/zvision.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index fe8e129800..7c26eba030 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -127,8 +127,8 @@ ZVision::~ZVision() {
delete _cursorManager;
delete _stringManager;
delete _saveManager;
- delete _renderManager;
delete _scriptManager;
+ delete _renderManager; // should be deleted after the script manager
delete _rnd;
delete _midiManager;
--
cgit v1.2.3
From 192c3df6a1b65a5e08b5fd0e2a82792393240378 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 27 Dec 2014 02:20:51 +0200
Subject: CREDITS: Update the credits for the ZVISION engine
---
AUTHORS | 2 ++
devtools/credits.pl | 2 ++
gui/credits.h | 2 ++
3 files changed, 6 insertions(+)
diff --git a/AUTHORS b/AUTHORS
index 8e90a625c9..3e8c65e5e2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -261,6 +261,8 @@ ScummVM Team
ZVision:
Adrian Astley
+ Filippos Karapetis
+ Anton Yarcev
Backend Teams
-------------
diff --git a/devtools/credits.pl b/devtools/credits.pl
index e919c0b8ba..69eede756d 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -791,6 +791,8 @@ begin_credits("Credits");
begin_section("ZVision");
add_person("Adrian Astley", "RichieSams", "");
+ add_person("Filippos Karapetis", "[md5]", "");
+ add_person("Anton Yarcev", "Marisa-Chan", "");
end_section();
end_section();
diff --git a/gui/credits.h b/gui/credits.h
index 0610609983..c7d9199db9 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -324,6 +324,8 @@ static const char *credits[] = {
"",
"C1""ZVision",
"C0""Adrian Astley",
+"C0""Filippos Karapetis",
+"C0""Anton Yarcev",
"",
"",
"C1""Backend Teams",
--
cgit v1.2.3
From 569c06b5105c7bae0a72d4abc72cf5db51541702 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sat, 27 Dec 2014 11:10:14 +0100
Subject: SCI: Fix warning
---
engines/sci/engine/state.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index c07dc925e0..527c8f0ae0 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -205,7 +205,7 @@ static kLanguage charToLanguage(const char c) {
Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage requestedLanguage, kLanguage *secondaryLanguage, uint16 *languageSplitter) const {
kLanguage foundLanguage = K_LANG_NONE;
- const byte *textPtr = (byte *)str.c_str();
+ const byte *textPtr = (const byte *)str.c_str();
byte curChar = 0;
byte curChar2 = 0;
--
cgit v1.2.3
From ba40b3ea4905716fc8dd6f01bfec6d414b6b9a58 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 27 Dec 2014 14:27:37 +0200
Subject: ZVISION: Clean up the game settings
---
engines/zvision/detection.cpp | 66 ++++++++++++++++++++++--------------
engines/zvision/zvision.cpp | 78 ++++++++++++++++++++++++++++++-------------
2 files changed, 95 insertions(+), 49 deletions(-)
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index 4fcb5c040b..c613278fec 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -55,6 +55,10 @@ static const PlainGameDescriptor zVisionGames[] = {
namespace ZVision {
+#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
+#define GAMEOPTION_DOUBLE_FPS GUIO_GAMEOPTIONS2
+#define GAMEOPTION_ENABLE_VENUS GUIO_GAMEOPTIONS3
+
static const ZVisionGameDescription gameDescriptions[] = {
{
@@ -66,7 +70,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS)
},
GID_NEMESIS
},
@@ -80,7 +84,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS)
},
GID_NEMESIS
},
@@ -94,7 +98,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS)
},
GID_GRANDINQUISITOR
},
@@ -108,7 +112,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS)
},
GID_GRANDINQUISITOR
},
@@ -122,7 +126,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS)
},
GID_GRANDINQUISITOR
},
@@ -140,23 +144,43 @@ static const char *directoryGlobs[] = {
0
};
-static const ExtraGuiOption ZVisionExtraGuiOption = {
- _s("Use original save/load screens"),
- _s("Use the original save/load screens, instead of the ScummVM ones"),
- "originalsaveload",
- false
-};
+static const ADExtraGuiOptionsMap optionsList[] = {
+ {
+ GAMEOPTION_ORIGINAL_SAVELOAD,
+ {
+ _s("Use original save/load screens"),
+ _s("Use the original save/load screens, instead of the ScummVM ones"),
+ "originalsaveload",
+ false
+ }
+ },
-static const ExtraGuiOption ZVisionExtraGuiOption2 = {
- _s("Double FPS"),
- _s("Halve the update delay"),
- "doublefps",
- false
+ {
+ GAMEOPTION_DOUBLE_FPS,
+ {
+ _s("Double FPS"),
+ _s("Halve the update delay"),
+ "doublefps",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_ENABLE_VENUS,
+ {
+ _s("Enable Venus"),
+ _s("Enable the Venus help system"),
+ "venusenabled",
+ true
+ }
+ },
+
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
};
class ZVisionMetaEngine : public AdvancedMetaEngine {
public:
- ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), zVisionGames) {
+ ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), zVisionGames, optionsList) {
_maxScanDepth = 2;
_directoryGlobs = directoryGlobs;
_singleid = "zvision";
@@ -172,7 +196,6 @@ public:
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
- virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const;
SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
void removeSaveState(const char *target, int slot) const;
@@ -223,13 +246,6 @@ bool ZVisionMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADG
return gd != 0;
}
-const ExtraGuiOptions ZVisionMetaEngine::getExtraGuiOptions(const Common::String &target) const {
- ExtraGuiOptions options;
- options.push_back(ZVisionExtraGuiOption);
- options.push_back(ZVisionExtraGuiOption2);
- return options;
-}
-
SaveStateList ZVisionMetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
ZVision::SaveGameHeader header;
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 7c26eba030..5f4924d7cf 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -57,25 +57,29 @@ namespace ZVision {
struct zvisionIniSettings {
const char *name;
int16 slot;
- int16 deflt;
+ int16 defaultValue; // -1: use the bool value
+ bool defaultBoolValue;
+ bool allowEditing;
} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
- {"ZVision_KeyboardTurnSpeed", StateKey_KbdRotateSpeed, 5},
- {"ZVision_PanaRotateSpeed", StateKey_RotateSpeed, 540},
- {"ZVision_QSoundEnabled", StateKey_Qsound, 1},
- {"ZVision_VenusEnabled", StateKey_VenusEnable, 1},
- {"ZVision_HighQuality", StateKey_HighQuality, 1},
- {"ZVision_Platform", StateKey_Platform, 0},
- {"ZVision_InstallLevel", StateKey_InstallLevel, 0},
- {"ZVision_CountryCode", StateKey_CountryCode, 0},
- {"ZVision_CPU", StateKey_CPU, 1},
- {"ZVision_MovieCursor", StateKey_MovieCursor, 1},
- {"ZVision_NoAnimWhileTurning", StateKey_NoTurnAnim, 0},
- {"ZVision_Win958", StateKey_WIN958, 0},
- {"ZVision_ShowErrorDialogs", StateKey_ShowErrorDlg, 0},
- {"ZVision_ShowSubtitles", StateKey_Subtitles, 1},
- {"ZVision_DebugCheats", StateKey_DebugCheats, 0},
- {"ZVision_JapaneseFonts", StateKey_JapanFonts, 0},
- {"ZVision_Brightness", StateKey_Brightness, 0}
+ // Hardcoded settings
+ {"qsoundenabled", StateKey_Qsound, 1, false, false},
+ {"highquality", StateKey_HighQuality, 1, false, false},
+ {"platform", StateKey_Platform, 0, false, false},
+ {"installlevel", StateKey_InstallLevel, 0, false, false},
+ {"countrycode", StateKey_CountryCode, 0, false, false},
+ {"cpu", StateKey_CPU, 1, false, false},
+ {"moviecursor", StateKey_MovieCursor, 1, false, false},
+ {"noanimwhileturning", StateKey_NoTurnAnim, 0, false, false},
+ {"win958", StateKey_WIN958, 0, false, false},
+ {"showerrordialogs", StateKey_ShowErrorDlg, 0, false, false},
+ {"japanesefonts", StateKey_JapanFonts, 0, false, false},
+ {"brightness", StateKey_Brightness, 0, false, false},
+ {"debugcheats", StateKey_DebugCheats, 1, false, false},
+ // Editable settings
+ {"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
+ {"panarotatespeed", StateKey_RotateSpeed, 540, false, true},
+ {"venusenabled", StateKey_VenusEnable, -1, true, true},
+ {"subtitles", StateKey_Subtitles, -1, true, true},
};
ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
@@ -139,14 +143,33 @@ ZVision::~ZVision() {
}
void ZVision::registerDefaultSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++)
- ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].deflt);
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultValue);
+ else
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultBoolValue);
+ }
+ }
+
+ ConfMan.registerDefault("originalsaveload", false);
ConfMan.registerDefault("doublefps", false);
}
void ZVision::loadSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++)
- _scriptManager->setStateValue(settingsKeys[i].slot, ConfMan.getInt(settingsKeys[i].name));
+ int16 value = 0;
+ bool boolValue = false;
+
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].defaultValue >= 0) {
+ value = (settingsKeys[i].allowEditing) ? ConfMan.getInt(settingsKeys[i].name) : settingsKeys[i].defaultValue;
+ } else {
+ boolValue = value = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
+ value = (boolValue) ? 1 : 0;
+ }
+
+ _scriptManager->setStateValue(settingsKeys[i].slot, value);
+ }
if (getGameId() == GID_NEMESIS)
_scriptManager->setStateValue(StateKey_ExecScopeStyle, 1);
@@ -155,8 +178,15 @@ void ZVision::loadSettings() {
}
void ZVision::saveSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++)
- ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
+ else
+ ConfMan.setBool(settingsKeys[i].name, (_scriptManager->getStateValue(settingsKeys[i].slot) == 1));
+ }
+ }
+
ConfMan.flushToDisk();
}
--
cgit v1.2.3
From e862172460640188363873b9fa1fb46a3f4c7f78 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 27 Dec 2014 14:29:17 +0200
Subject: ZVISION: Add some advanced engine features, and document the engine
---
engines/zvision/zvision.cpp | 10 ++++++++++
engines/zvision/zvision.h | 14 ++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 5f4924d7cf..03103553cc 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -345,6 +345,16 @@ bool ZVision::canRender() {
return _frameRenderDelay <= 0;
}
+GUI::Debugger *ZVision::getDebugger() {
+ return _console;
+}
+
+void ZVision::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _scriptManager->setStateValue(StateKey_Subtitles, ConfMan.getBool("subtitles") ? 1 : 0);
+}
+
void ZVision::fpsTimerCallback(void *refCon) {
((ZVision *)refCon)->fpsTimer();
}
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 5482060cd0..ad22ddaaa2 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -41,6 +41,17 @@ namespace Video {
class VideoDecoder;
}
+/**
+ * This is the namespace of the ZVision engine.
+ *
+ * Status of this engine: complete
+ *
+ * Games using this engine:
+ * - Zork Nemesis: The Forbidden Lands
+ * - Zork: Grand Inquisitor
+ *
+ */
+
namespace ZVision {
struct ZVisionGameDescription;
@@ -205,6 +216,9 @@ public:
return _fps;
}
+ GUI::Debugger *getDebugger();
+ void syncSoundSettings();
+
void loadSettings();
void saveSettings();
--
cgit v1.2.3
From 39eab59388c6dc43d1f2c72ee708807ef1bdb198 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sat, 27 Dec 2014 15:31:43 +0100
Subject: ACCESS: Rewrite sound queueing (WIP)
---
engines/access/amazon/amazon_logic.cpp | 52 ++++++++++++++++++----------------
engines/access/events.cpp | 2 ++
engines/access/sound.cpp | 50 ++++++++++++++++++++------------
engines/access/sound.h | 5 +++-
4 files changed, 66 insertions(+), 43 deletions(-)
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index 4a313e8880..c045377f8a 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -341,15 +341,12 @@ void Opening::doTitle() {
_vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
delete spriteData;
- _vm->_sound->playSound(1);
-
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(0, 4);
_vm->_sound->playSound(1);
_vm->_buffer2.copyFrom(*_vm->_screen);
_vm->_buffer1.copyFrom(*_vm->_screen);
- _vm->_sound->playSound(1);
const int COUNTDOWN[6] = { 2, 0x80, 1, 0x7d, 0, 0x87 };
for (_pCount = 0; _pCount < 3 && !_vm->shouldQuit(); ++_pCount) {
@@ -508,40 +505,47 @@ void Opening::doTent() {
_vm->_screen->forceFadeIn();
_vm->_video->setVideo(_vm->_screen, Common::Point(126, 73), FileIdent(2, 1), 10);
+ int previousFrame = -1;
while (!_vm->shouldQuit() && !_vm->_video->_videoEnd) {
_vm->_video->playVideo();
- if ((_vm->_video->_videoFrame == 32) || (_vm->_video->_videoFrame == 34))
- _vm->_sound->playSound(4);
- else if (_vm->_video->_videoFrame == 36) {
- if (step != 2) {
- _vm->_sound->playSound(2);
- step = 2;
- }
- } else if (_vm->_video->_videoFrame == 18) {
- if (step != 1) {
- _vm->_midi->newMusic(73, 1);
- _vm->_midi->newMusic(11, 0);
- step = 1;
- _vm->_sound->playSound(1);
+ if (previousFrame != _vm->_video->_videoFrame) {
+ previousFrame = _vm->_video->_videoFrame;
+
+ if ((_vm->_video->_videoFrame == 32) || (_vm->_video->_videoFrame == 34))
+ _vm->_sound->playSound(4);
+ else if (_vm->_video->_videoFrame == 36) {
+ if (step != 2) {
+ _vm->_sound->playSound(2);
+ step = 2;
+ }
+ } else if (_vm->_video->_videoFrame == 18) {
+ if (step != 1) {
+ _vm->_midi->newMusic(73, 1);
+ _vm->_midi->newMusic(11, 0);
+ step = 1;
+ _vm->_sound->playSound(1);
+ }
}
}
-
_vm->_events->pollEventsAndWait();
}
_vm->_sound->playSound(5);
_vm->_video->setVideo(_vm->_screen, Common::Point(43, 11), FileIdent(2, 2), 10);
+ previousFrame = -1;
while (!_vm->shouldQuit() && !_vm->_video->_videoEnd) {
_vm->_video->playVideo();
- if (_vm->_video->_videoFrame == 26) {
- _vm->_sound->playSound(5);
- } else if (_vm->_video->_videoFrame == 15) {
- if (step !=3) {
- _vm->_sound->playSound(3);
- step = 3;
+ if (previousFrame != _vm->_video->_videoFrame) {
+ previousFrame = _vm->_video->_videoFrame;
+ if (_vm->_video->_videoFrame == 26) {
+ _vm->_sound->playSound(5);
+ } else if (_vm->_video->_videoFrame == 15) {
+ if (step !=3) {
+ _vm->_sound->playSound(3);
+ step = 3;
+ }
}
}
-
_vm->_events->pollEventsAndWait();
}
diff --git a/engines/access/events.cpp b/engines/access/events.cpp
index 0867b09765..6ffe67acfb 100644
--- a/engines/access/events.cpp
+++ b/engines/access/events.cpp
@@ -140,6 +140,8 @@ void EventsManager::pollEvents(bool skipTimers) {
if (checkForNextTimerUpdate() && !skipTimers)
nextTimer();
+ _vm->_sound->checkSoundQueue();
+
_wheelUp = _wheelDown = false;
Common::Event event;
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index a7d96dac9a..82199a8286 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -22,7 +22,6 @@
#include "common/algorithm.h"
#include "audio/mixer.h"
-#include "audio/audiostream.h"
#include "audio/decoders/raw.h"
#include "audio/decoders/wave.h"
#include "access/access.h"
@@ -44,7 +43,19 @@ void SoundManager::clearSounds() {
for (uint i = 0; i < _soundTable.size(); ++i)
delete _soundTable[i]._res;
+
_soundTable.clear();
+
+ if (_mixer->isSoundHandleActive(_effectsHandle))
+ _mixer->stopHandle(_effectsHandle);
+
+ if (_queue.size())
+ _queue.remove_at(0);
+
+ while (_queue.size()) {
+ delete _queue[0];
+ _queue.remove_at(0);
+ }
}
void SoundManager::queueSound(int idx, int fileNum, int subfile) {
@@ -77,19 +88,14 @@ void SoundManager::playSound(Resource *res, int priority) {
debugC(1, kDebugSound, "playSound");
byte *resourceData = res->data();
- Audio::SoundHandle audioHandle;
- Audio::RewindableAudioStream *audioStream = 0;
assert(res->_size >= 32);
- // HACK: Simulates queueing for the rare sounds played one after the other
- while (_mixer->hasActiveChannelOfType(Audio::Mixer::kSFXSoundType))
- ;
-
if (READ_BE_UINT32(resourceData) == MKTAG('R','I','F','F')) {
// CD version uses WAVE-files
Common::SeekableReadStream *waveStream = new Common::MemoryReadStream(resourceData, res->_size, DisposeAfterUse::NO);
- audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
+ Audio::RewindableAudioStream *audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
+ _queue.push_back(audioStream);
} else if (READ_BE_UINT32(resourceData) == MKTAG('S', 'T', 'E', 'V')) {
// sound files have a fixed header of 32 bytes in total
@@ -130,22 +136,30 @@ void SoundManager::playSound(Resource *res, int priority) {
return;
}
- audioStream = Audio::makeRawStream(resourceData + 32, sampleSize, sampleRate, 0);
+ Audio::RewindableAudioStream *audioStream = Audio::makeRawStream(resourceData + 32, sampleSize, sampleRate, 0);
+ _queue.push_back(audioStream);
} else
error("Unknown format");
- audioHandle = Audio::SoundHandle();
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &audioHandle,
- audioStream, -1, _mixer->kMaxChannelVolume, 0,
+ if (!_mixer->isSoundHandleActive(_effectsHandle))
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
+ _queue[0], -1, _mixer->kMaxChannelVolume, 0,
DisposeAfterUse::NO);
+}
+
+void SoundManager::checkSoundQueue() {
+ debugC(5, kDebugSound, "checkSoundQueue");
+
+ if (_queue.empty() || _mixer->isSoundHandleActive(_effectsHandle))
+ return;
+
+ _queue.remove_at(0);
- /*
- Audio::QueuingAudioStream *audioStream = Audio::makeQueuingAudioStream(22050, false);
- audioStream->queueBuffer(data, size, DisposeAfterUse::YES, 0);
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, audioStream, -1,
- Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, false);
- */
+ if (_queue.size())
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
+ _queue[0], -1, _mixer->kMaxChannelVolume, 0,
+ DisposeAfterUse::YES);
}
void SoundManager::loadSounds(Common::Array &sounds) {
diff --git a/engines/access/sound.h b/engines/access/sound.h
index d0f4584fac..c276648477 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -24,6 +24,7 @@
#define ACCESS_SOUND_H
#include "common/scummsys.h"
+#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "access/files.h"
#include "audio/midiplayer.h"
@@ -47,7 +48,8 @@ class SoundManager {
private:
AccessEngine *_vm;
Audio::Mixer *_mixer;
- Audio::SoundHandle _soundHandle;
+ Audio::SoundHandle _effectsHandle;
+ Common::Array _queue;
void clearSounds();
@@ -63,6 +65,7 @@ public:
void queueSound(int idx, int fileNum, int subfile);
void playSound(int soundIndex);
+ void checkSoundQueue();
Resource *loadSound(int fileNum, int subfile);
void loadSounds(Common::Array &sounds);
--
cgit v1.2.3
From 1016838bd5e556a4882f2b07e993ea9e78d12f7f Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 27 Dec 2014 16:33:43 +0200
Subject: ZVISION: Add support for disabling animations while turning
Also, clean up and document game configuration options, and add a TODO
for QSound support
---
engines/zvision/detection.cpp | 27 ++++++++++++++------
.../zvision/scripting/sidefx/animation_node.cpp | 25 +++++++++++++------
engines/zvision/scripting/sidefx/distort_node.cpp | 1 -
engines/zvision/zvision.cpp | 29 +++++++++++-----------
4 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index c613278fec..1eaff83413 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -55,9 +55,10 @@ static const PlainGameDescriptor zVisionGames[] = {
namespace ZVision {
-#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
-#define GAMEOPTION_DOUBLE_FPS GUIO_GAMEOPTIONS2
-#define GAMEOPTION_ENABLE_VENUS GUIO_GAMEOPTIONS3
+#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
+#define GAMEOPTION_DOUBLE_FPS GUIO_GAMEOPTIONS2
+#define GAMEOPTION_ENABLE_VENUS GUIO_GAMEOPTIONS3
+#define GAMEOPTION_DISABLE_ANIM_WHILE_TURNING GUIO_GAMEOPTIONS4
static const ZVisionGameDescription gameDescriptions[] = {
@@ -70,7 +71,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS)
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
},
GID_NEMESIS
},
@@ -84,7 +85,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS)
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
},
GID_NEMESIS
},
@@ -98,7 +99,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS)
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
},
GID_GRANDINQUISITOR
},
@@ -112,7 +113,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS)
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
},
GID_GRANDINQUISITOR
},
@@ -126,7 +127,7 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS)
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
},
GID_GRANDINQUISITOR
},
@@ -175,6 +176,16 @@ static const ADExtraGuiOptionsMap optionsList[] = {
}
},
+ {
+ GAMEOPTION_DISABLE_ANIM_WHILE_TURNING,
+ {
+ _s("Disable animation while turning"),
+ _s("Disable animation while turning in panoramic mode"),
+ "noanimwhileturning",
+ false
+ }
+ },
+
AD_EXTRA_GUI_OPTIONS_TERMINATOR
};
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 7759758f56..3dd80f3699 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -75,6 +75,17 @@ AnimationNode::~AnimationNode() {
}
bool AnimationNode::process(uint32 deltaTimeInMillis) {
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ RenderManager *renderManager = _engine->getRenderManager();
+ RenderTable::RenderState renderState = renderManager->getRenderTable()->getRenderState();
+ bool isPanorama = (renderState == RenderTable::PANORAMA);
+ int16 velocity = _engine->getMouseVelocity() + _engine->getKeyboardVelocity();
+
+ // Do not update animation nodes in panoramic mode while turning, if the user
+ // has set this option
+ if (scriptManager->getStateValue(StateKey_NoTurnAnim) == 1 && isPanorama && velocity)
+ return false;
+
PlayNodes::iterator it = _playList.begin();
if (it != _playList.end()) {
playnode *nod = &(*it);
@@ -93,7 +104,7 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
nod->_delay = _frmDelay;
if (nod->slot)
- _engine->getScriptManager()->setStateValue(nod->slot, 1);
+ scriptManager->setStateValue(nod->slot, 1);
} else {
nod->_curFrame++;
@@ -102,7 +113,7 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (nod->loop == 0) {
if (nod->slot >= 0)
- _engine->getScriptManager()->setStateValue(nod->slot, 2);
+ scriptManager->setStateValue(nod->slot, 2);
if (nod->_scaled) {
nod->_scaled->free();
delete nod->_scaled;
@@ -121,7 +132,7 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (frame) {
uint32 dstw;
uint32 dsth;
- if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) {
+ if (isPanorama) {
dstw = nod->pos.height();
dsth = nod->pos.width();
} else {
@@ -148,17 +159,17 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
nod->_scaled->create(dstw, dsth, frame->format);
}
- _engine->getRenderManager()->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
+ renderManager->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
frame = nod->_scaled;
}
- if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) {
+ if (isPanorama) {
Graphics::Surface *transposed = RenderManager::tranposeSurface(frame);
- _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
+ renderManager->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
transposed->free();
delete transposed;
} else {
- _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
+ renderManager->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
}
}
}
diff --git a/engines/zvision/scripting/sidefx/distort_node.cpp b/engines/zvision/scripting/sidefx/distort_node.cpp
index 0d5c8b1ed5..7d25adc031 100644
--- a/engines/zvision/scripting/sidefx/distort_node.cpp
+++ b/engines/zvision/scripting/sidefx/distort_node.cpp
@@ -65,7 +65,6 @@ DistortNode::~DistortNode() {
}
bool DistortNode::process(uint32 deltaTimeInMillis) {
-
float updTime = deltaTimeInMillis / (1000.0 / 60.0);
if (_incr)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 03103553cc..a28ad862d9 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -62,22 +62,23 @@ struct zvisionIniSettings {
bool allowEditing;
} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
// Hardcoded settings
- {"qsoundenabled", StateKey_Qsound, 1, false, false},
- {"highquality", StateKey_HighQuality, 1, false, false},
- {"platform", StateKey_Platform, 0, false, false},
- {"installlevel", StateKey_InstallLevel, 0, false, false},
- {"countrycode", StateKey_CountryCode, 0, false, false},
- {"cpu", StateKey_CPU, 1, false, false},
- {"moviecursor", StateKey_MovieCursor, 1, false, false},
- {"noanimwhileturning", StateKey_NoTurnAnim, 0, false, false},
- {"win958", StateKey_WIN958, 0, false, false},
- {"showerrordialogs", StateKey_ShowErrorDlg, 0, false, false},
- {"japanesefonts", StateKey_JapanFonts, 0, false, false},
- {"brightness", StateKey_Brightness, 0, false, false},
- {"debugcheats", StateKey_DebugCheats, 1, false, false},
+ //{"platform", StateKey_Platform, 0, false, false}, // 0 = Windows, 1 = DOS, 2 = DOS, unused
+ //{"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, unused
+ //{"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, unused
+ //{"cpu", StateKey_CPU, 1, false, false}, // always 1 = Pentium (0 is 486), unused
+ //{"win958", StateKey_WIN958, 0, false, false}, // unused, probably Windows version flag
+ //{"showerrordialogs", StateKey_ShowErrorDlg, 0, false, false}, // unused
+ //{"japanesefonts", StateKey_JapanFonts, 0, false, false},
+ //{"brightness", StateKey_Brightness, 0, false, false},
+ //{"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
+ //{"highquality", StateKey_HighQuality, 0, false, false}, // performance related, always high
+ //{"moviecursor", StateKey_MovieCursor, 0, false, false}, // show mouse cursor in movies, unused
+ {"qsoundenabled", StateKey_Qsound, 1, false, false}, // 1 = enable QSound - TODO: not supported yet
+ {"debugcheats", StateKey_DebugCheats, 1, false, false}, // always start with the GOxxxx cheat enabled
// Editable settings
{"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
{"panarotatespeed", StateKey_RotateSpeed, 540, false, true},
+ {"noanimwhileturning", StateKey_NoTurnAnim, -1, false, true}, // toggle playing animations during pana rotation
{"venusenabled", StateKey_VenusEnable, -1, true, true},
{"subtitles", StateKey_Subtitles, -1, true, true},
};
@@ -164,7 +165,7 @@ void ZVision::loadSettings() {
if (settingsKeys[i].defaultValue >= 0) {
value = (settingsKeys[i].allowEditing) ? ConfMan.getInt(settingsKeys[i].name) : settingsKeys[i].defaultValue;
} else {
- boolValue = value = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
+ boolValue = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
value = (boolValue) ? 1 : 0;
}
--
cgit v1.2.3
From b3712cc877482e150a3532fa0f21f5c03dc839f1 Mon Sep 17 00:00:00 2001
From: Ori Avtalion
Date: Sat, 27 Dec 2014 16:36:41 +0200
Subject: ZVISION: Remove dead code (uint is always > 0)
---
engines/zvision/video/rlf_decoder.cpp | 5 -----
1 file changed, 5 deletions(-)
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index 260f912ade..1478822d00 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -164,11 +164,6 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
if ((uint)_curFrame == frame)
return true;
- if (frame < 0) {
- _curFrame = 0;
- return false;
- }
-
int closestFrame = _curFrame;
int distance = (int)frame - _curFrame;
--
cgit v1.2.3
From 6fe9bdf6c6f63320e351c348970c2864af708c42 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sat, 27 Dec 2014 16:05:23 +0100
Subject: ACCESS: Fix speech
---
engines/access/access.cpp | 6 ++++--
engines/access/sound.cpp | 4 ++++
engines/access/sound.h | 1 +
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 67255ff5ea..080a8ef975 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -227,7 +227,8 @@ void AccessEngine::speakText(ASurface *s, const Common::String &msg) {
_sound->playSound(0);
_scripts->cmdFreeSound();
- _events->pollEvents();
+ while(_sound->isSFXPlaying() && !shouldQuit())
+ _events->pollEvents();
if (_events->isKeyMousePressed()) {
_sndSubFile += soundsLeft;
@@ -258,7 +259,8 @@ void AccessEngine::speakText(ASurface *s, const Common::String &msg) {
_sound->playSound(0);
_scripts->cmdFreeSound();
- _events->pollEvents();
+ while(_sound->isSFXPlaying() && !shouldQuit())
+ _events->pollEvents();
if (_events->_leftButton) {
_events->debounceLeft();
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index 82199a8286..cfc8b7a64c 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -162,6 +162,10 @@ void SoundManager::checkSoundQueue() {
DisposeAfterUse::YES);
}
+bool SoundManager::isSFXPlaying() {
+ return _mixer->isSoundHandleActive(_effectsHandle);
+}
+
void SoundManager::loadSounds(Common::Array &sounds) {
debugC(1, kDebugSound, "loadSounds");
diff --git a/engines/access/sound.h b/engines/access/sound.h
index c276648477..3646c2cc16 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -66,6 +66,7 @@ public:
void playSound(int soundIndex);
void checkSoundQueue();
+ bool isSFXPlaying();
Resource *loadSound(int fileNum, int subfile);
void loadSounds(Common::Array &sounds);
--
cgit v1.2.3
From 3c3ff0a3aab13b876e0425c365402ff334743282 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sat, 27 Dec 2014 16:46:33 +0100
Subject: ACCESS: Remove two useless variables
---
engines/access/scripts.cpp | 2 +-
engines/access/sound.cpp | 2 --
engines/access/sound.h | 2 --
3 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index 074c781352..1bd24894d7 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -794,7 +794,7 @@ void Scripts::cmdFreeSound() {
charLoop();
_vm->_events->pollEvents();
- } while (!_vm->shouldQuit() && sound._playingSound);
+ } while (!_vm->shouldQuit() && sound.isSFXPlaying());
// Free the sounds
while (sound._soundTable.size() > 0) {
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index cfc8b7a64c..fc574dc083 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -30,8 +30,6 @@
namespace Access {
SoundManager::SoundManager(AccessEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
- _playingSound = false;
- _isVoice = false;
}
SoundManager::~SoundManager() {
diff --git a/engines/access/sound.h b/engines/access/sound.h
index 3646c2cc16..384e9ac615 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -56,8 +56,6 @@ private:
void playSound(Resource *res, int priority);
public:
Common::Array _soundTable;
- bool _playingSound;
- bool _isVoice;
public:
SoundManager(AccessEngine *vm, Audio::Mixer *mixer);
~SoundManager();
--
cgit v1.2.3
From 6a7834a05ed880cba32f0adb87950179c4ec404c Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sat, 27 Dec 2014 16:55:07 +0100
Subject: ACCESS: Rename loadSoundTable
---
engines/access/amazon/amazon_logic.cpp | 4 ++--
engines/access/amazon/amazon_scripts.cpp | 2 +-
engines/access/sound.cpp | 4 ++--
engines/access/sound.h | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index c045377f8a..82f0edfa6e 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -317,8 +317,8 @@ void Opening::doTitle() {
_vm->_events->hideCursor();
if (!_vm->isDemo()) {
- _vm->_sound->queueSound(0, 98, 30);
- _vm->_sound->queueSound(1, 98, 8);
+ _vm->_sound->loadSoundTable(0, 98, 30);
+ _vm->_sound->loadSoundTable(1, 98, 8);
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(0, 3);
diff --git a/engines/access/amazon/amazon_scripts.cpp b/engines/access/amazon/amazon_scripts.cpp
index 0b2ddbc854..92acb3686d 100644
--- a/engines/access/amazon/amazon_scripts.cpp
+++ b/engines/access/amazon/amazon_scripts.cpp
@@ -95,7 +95,7 @@ void AmazonScripts::mWhile1() {
_vm->_oldRects.clear();
_sequence = 2200;
- _vm->_sound->queueSound(0, 14, 15);
+ _vm->_sound->loadSoundTable(0, 14, 15);
do {
cLoop();
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index fc574dc083..53b611b65b 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -56,8 +56,8 @@ void SoundManager::clearSounds() {
}
}
-void SoundManager::queueSound(int idx, int fileNum, int subfile) {
- debugC(1, kDebugSound, "queueSound(%d, %d, %d)", idx, fileNum, subfile);
+void SoundManager::loadSoundTable(int idx, int fileNum, int subfile) {
+ debugC(1, kDebugSound, "loadSoundTable(%d, %d, %d)", idx, fileNum, subfile);
Resource *soundResource;
diff --git a/engines/access/sound.h b/engines/access/sound.h
index 384e9ac615..7109438f43 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -60,7 +60,7 @@ public:
SoundManager(AccessEngine *vm, Audio::Mixer *mixer);
~SoundManager();
- void queueSound(int idx, int fileNum, int subfile);
+ void loadSoundTable(int idx, int fileNum, int subfile);
void playSound(int soundIndex);
void checkSoundQueue();
--
cgit v1.2.3
From 576bab349c862b16fcca1e9e0fb3fbb52cc6edc4 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sat, 27 Dec 2014 17:21:04 +0100
Subject: ACCESS: Use loadSoundTable instead of push_back in several places
---
engines/access/access.cpp | 9 +++++----
engines/access/amazon/amazon_game.cpp | 4 ++--
engines/access/amazon/amazon_logic.cpp | 12 ++++++------
engines/access/sound.cpp | 4 ++--
engines/access/sound.h | 2 +-
5 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 080a8ef975..7f59ae7ad6 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -222,14 +222,14 @@ void AccessEngine::speakText(ASurface *s, const Common::String &msg) {
_events->clearEvents();
while (!shouldQuit()) {
_sound->freeSounds();
- Resource *sound = _sound->loadSound(_narateFile + 99, _sndSubFile);
- _sound->_soundTable.push_back(SoundEntry(sound, 1));
+ _sound->loadSoundTable(0, _narateFile + 99, _sndSubFile);
_sound->playSound(0);
- _scripts->cmdFreeSound();
while(_sound->isSFXPlaying() && !shouldQuit())
_events->pollEvents();
+ _scripts->cmdFreeSound();
+
if (_events->isKeyMousePressed()) {
_sndSubFile += soundsLeft;
break;
@@ -257,11 +257,12 @@ void AccessEngine::speakText(ASurface *s, const Common::String &msg) {
Resource *res = _sound->loadSound(_narateFile + 99, _sndSubFile);
_sound->_soundTable.push_back(SoundEntry(res, 1));
_sound->playSound(0);
- _scripts->cmdFreeSound();
while(_sound->isSFXPlaying() && !shouldQuit())
_events->pollEvents();
+ _scripts->cmdFreeSound();
+
if (_events->_leftButton) {
_events->debounceLeft();
_sndSubFile += soundsLeft;
diff --git a/engines/access/amazon/amazon_game.cpp b/engines/access/amazon/amazon_game.cpp
index d6b759b308..4c9df7b8ff 100644
--- a/engines/access/amazon/amazon_game.cpp
+++ b/engines/access/amazon/amazon_game.cpp
@@ -528,8 +528,8 @@ void AmazonEngine::startChapter(int chapter) {
_sound->freeSounds();
if (isCD()) {
- _sound->_soundTable.push_back(SoundEntry(_sound->loadSound(115, 0), 1));
- _sound->_soundTable.push_back(SoundEntry(_sound->loadSound(115, 1), 1));
+ _sound->loadSoundTable(0, 115, 0);
+ _sound->loadSoundTable(1, 115, 1);
_sound->playSound(0);
_sound->playSound(1);
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index 82f0edfa6e..6dffb85e5e 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -490,12 +490,12 @@ void Opening::doTent() {
_vm->_screen->setDisplayScan();
_vm->_screen->forceFadeOut();
_vm->_events->hideCursor();
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 39), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 14), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 15), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 16), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 31), 2));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 52), 2));
+ _vm->_sound->loadSoundTable(0, 98, 39);
+ _vm->_sound->loadSoundTable(1, 98, 14);
+ _vm->_sound->loadSoundTable(2, 98, 15);
+ _vm->_sound->loadSoundTable(3, 98, 16);
+ _vm->_sound->loadSoundTable(4, 98, 31, 2);
+ _vm->_sound->loadSoundTable(5, 98, 52, 2);
_vm->_sound->playSound(0);
_vm->_files->_setPaletteFlag = false;
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index 53b611b65b..221b409aa9 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -56,7 +56,7 @@ void SoundManager::clearSounds() {
}
}
-void SoundManager::loadSoundTable(int idx, int fileNum, int subfile) {
+void SoundManager::loadSoundTable(int idx, int fileNum, int subfile, int priority) {
debugC(1, kDebugSound, "loadSoundTable(%d, %d, %d)", idx, fileNum, subfile);
Resource *soundResource;
@@ -67,7 +67,7 @@ void SoundManager::loadSoundTable(int idx, int fileNum, int subfile) {
delete _soundTable[idx]._res;
soundResource = _vm->_files->loadFile(fileNum, subfile);
_soundTable[idx]._res = soundResource;
- _soundTable[idx]._priority = 1;
+ _soundTable[idx]._priority = priority;
}
Resource *SoundManager::loadSound(int fileNum, int subfile) {
diff --git a/engines/access/sound.h b/engines/access/sound.h
index 7109438f43..90f6656e26 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -60,7 +60,7 @@ public:
SoundManager(AccessEngine *vm, Audio::Mixer *mixer);
~SoundManager();
- void loadSoundTable(int idx, int fileNum, int subfile);
+ void loadSoundTable(int idx, int fileNum, int subfile, int priority = 1);
void playSound(int soundIndex);
void checkSoundQueue();
--
cgit v1.2.3
From 99fabffde0c8f88d02bba341cd9d504483b86409 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sat, 27 Dec 2014 20:51:39 +0200
Subject: ZVISION: Clean up settings and initialize the ones used by game
scripts
---
engines/zvision/zvision.cpp | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index a28ad862d9..0d06f3ce90 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -52,7 +52,7 @@
namespace ZVision {
-#define ZVISION_SETTINGS_KEYS_COUNT 17
+#define ZVISION_SETTINGS_KEYS_COUNT 11
struct zvisionIniSettings {
const char *name;
@@ -62,25 +62,18 @@ struct zvisionIniSettings {
bool allowEditing;
} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
// Hardcoded settings
- //{"platform", StateKey_Platform, 0, false, false}, // 0 = Windows, 1 = DOS, 2 = DOS, unused
- //{"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, unused
- //{"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, unused
- //{"cpu", StateKey_CPU, 1, false, false}, // always 1 = Pentium (0 is 486), unused
- //{"win958", StateKey_WIN958, 0, false, false}, // unused, probably Windows version flag
- //{"showerrordialogs", StateKey_ShowErrorDlg, 0, false, false}, // unused
- //{"japanesefonts", StateKey_JapanFonts, 0, false, false},
- //{"brightness", StateKey_Brightness, 0, false, false},
- //{"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
- //{"highquality", StateKey_HighQuality, 0, false, false}, // performance related, always high
- //{"moviecursor", StateKey_MovieCursor, 0, false, false}, // show mouse cursor in movies, unused
- {"qsoundenabled", StateKey_Qsound, 1, false, false}, // 1 = enable QSound - TODO: not supported yet
- {"debugcheats", StateKey_DebugCheats, 1, false, false}, // always start with the GOxxxx cheat enabled
+ {"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, subtitles are shown for codes 0 - 4, unused
+ {"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
+ {"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, checked by universe.scr
+ {"highquality", StateKey_HighQuality, -1, true, false}, // high panorama quality, unused
+ {"qsoundenabled", StateKey_Qsound, -1, true, false}, // 1 = enable QSound - TODO: not supported yet
+ {"debugcheats", StateKey_DebugCheats, -1, true, false}, // always start with the GOxxxx cheat enabled
// Editable settings
{"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
- {"panarotatespeed", StateKey_RotateSpeed, 540, false, true},
+ {"panarotatespeed", StateKey_RotateSpeed, 540, false, true}, // checked by universe.scr
{"noanimwhileturning", StateKey_NoTurnAnim, -1, false, true}, // toggle playing animations during pana rotation
{"venusenabled", StateKey_VenusEnable, -1, true, true},
- {"subtitles", StateKey_Subtitles, -1, true, true},
+ {"subtitles", StateKey_Subtitles, -1, true, true}
};
ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
--
cgit v1.2.3
From 58f328b9af50d66bf8d1be1b19e6059f706ef226 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sat, 27 Dec 2014 22:22:28 +0100
Subject: ZVISION: Slightly clarify font error message
---
engines/zvision/zvision.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 0d06f3ce90..88cc1e2fea 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -258,12 +258,12 @@ Common::Error ZVision::run() {
if (!Common::File::exists("arial.ttf") && !Common::File::exists("FreeSans.ttf")) {
GUI::MessageDialog dialog(
"Before playing this game, you'll need to copy the required "
- "fonts in ScummVM's extras directory, or the game directory. "
+ "fonts into ScummVM's extras directory, or into the game directory. "
"On Windows, you'll need the following font files from the Windows "
"font directory: Times New Roman, Century Schoolbook, Garamond, "
"Courier New and Arial. Alternatively, you can download the GNU "
"FreeFont package. You'll need all the fonts from that package, "
- "i.e. FreeMono, FreeSans and FreeSerif."
+ "i.e., FreeMono, FreeSans and FreeSerif."
);
dialog.runModal();
quitGame();
--
cgit v1.2.3
From 02eada1d0ddd5f5c179ca39840bb7f73286df6e1 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sat, 27 Dec 2014 23:12:54 +0100
Subject: ZVISION: Fix Zork AVI audio on BE systems
---
engines/zvision/video/zork_avi_decoder.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp
index 67fab0a114..5618250d79 100644
--- a/engines/zvision/video/zork_avi_decoder.cpp
+++ b/engines/zvision/video/zork_avi_decoder.cpp
@@ -45,8 +45,14 @@ void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *s
RawChunkStream::RawChunk chunk = decoder->readNextChunk(stream);
delete stream;
- if (chunk.data)
- _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_STEREO);
+ if (chunk.data) {
+ byte flags = Audio::FLAG_16BITS | Audio::FLAG_STEREO;
+#ifdef SCUMM_LITTLE_ENDIAN
+ // RawChunkStream produces native endianness int16
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+ _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, flags);
+ }
} else {
AVIAudioTrack::queueSound(stream);
}
--
cgit v1.2.3
From 5791f600e9b9808714b40a63acd09b5657c855f5 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sat, 27 Dec 2014 23:35:35 +0100
Subject: ZVISION: Fix TGZ images on BE systems
---
engines/zvision/graphics/render_manager.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 4f26123fc8..a178c97639 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -209,13 +209,17 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
isTGZ = true;
// TGZ files have a header and then Bitmap data that is compressed with LZSS
- uint32 decompressedSize = file.readSint32LE();
+ uint32 decompressedSize = file.readSint32LE() / 2;
imageWidth = file.readSint32LE();
imageHeight = file.readSint32LE();
LzssReadStream lzssStream(&file);
buffer = (uint16 *)(new uint16[decompressedSize]);
- lzssStream.read(buffer, decompressedSize);
+ lzssStream.read(buffer, 2 * decompressedSize);
+#ifndef SCUMMVM_LITTLE_ENDIAN
+ for (uint32 i = 0; i < decompressedSize; ++i)
+ buffer[i] = FROM_LE_16(buffer[i]);
+#endif
} else {
isTGZ = false;
--
cgit v1.2.3
From cd595cb0ea65b5bd8b79cb7af35457d032d82e98 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sat, 27 Dec 2014 23:35:47 +0100
Subject: ZVISION: Fix cursors on BE systems
---
engines/zvision/graphics/cursors/cursor.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/engines/zvision/graphics/cursors/cursor.cpp b/engines/zvision/graphics/cursors/cursor.cpp
index eb25e92860..1b471d88b8 100644
--- a/engines/zvision/graphics/cursors/cursor.cpp
+++ b/engines/zvision/graphics/cursors/cursor.cpp
@@ -60,6 +60,12 @@ ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
_surface.create(_width, _height, engine->_resourcePixelFormat);
uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
assert(bytesRead == dataSize);
+
+#ifndef SCUMMVM_LITTLE_ENDIAN
+ int16 *buffer = (int16 *)_surface.getPixels();
+ for (uint32 i = 0; i < dataSize / 2; ++i)
+ buffer[i] = FROM_LE_16(buffer[i]);
+#endif
}
ZorkCursor::ZorkCursor(const ZorkCursor &other) {
--
cgit v1.2.3
From 4931aee954704a7ee984ce8cee85bdbec3ddb640 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sat, 27 Dec 2014 23:51:59 +0100
Subject: ZVISION: Fix typo
---
engines/zvision/graphics/cursors/cursor.cpp | 2 +-
engines/zvision/graphics/render_manager.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/engines/zvision/graphics/cursors/cursor.cpp b/engines/zvision/graphics/cursors/cursor.cpp
index 1b471d88b8..f32c68645d 100644
--- a/engines/zvision/graphics/cursors/cursor.cpp
+++ b/engines/zvision/graphics/cursors/cursor.cpp
@@ -61,7 +61,7 @@ ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
assert(bytesRead == dataSize);
-#ifndef SCUMMVM_LITTLE_ENDIAN
+#ifndef SCUMM_LITTLE_ENDIAN
int16 *buffer = (int16 *)_surface.getPixels();
for (uint32 i = 0; i < dataSize / 2; ++i)
buffer[i] = FROM_LE_16(buffer[i]);
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index a178c97639..033d099042 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -216,7 +216,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
LzssReadStream lzssStream(&file);
buffer = (uint16 *)(new uint16[decompressedSize]);
lzssStream.read(buffer, 2 * decompressedSize);
-#ifndef SCUMMVM_LITTLE_ENDIAN
+#ifndef SCUMM_LITTLE_ENDIAN
for (uint32 i = 0; i < decompressedSize; ++i)
buffer[i] = FROM_LE_16(buffer[i]);
#endif
--
cgit v1.2.3
From c823a6e825a6474c75f1ddecfcb67a602393fae6 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sat, 27 Dec 2014 23:52:18 +0100
Subject: ZVISION: Fix cmdRawToWav on BE systems
---
engines/zvision/core/console.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index c7592c8d9d..b5e542d777 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -138,6 +138,10 @@ bool Console::cmdRawToWav(int argc, const char **argv) {
output.writeUint32LE(file.size() * 2);
int16 *buffer = new int16[file.size()];
audioStream->readBuffer(buffer, file.size());
+#ifndef SCUMM_LITTLE_ENDIAN
+ for (int i = 0; i < file.size(); ++i)
+ buffer[i] = TO_LE_16(buffer[i]);
+#endif
output.write(buffer, file.size() * 2);
delete[] buffer;
--
cgit v1.2.3
From 329c9386c6db79b3c52fbd6712f3ae1718d04c1f Mon Sep 17 00:00:00 2001
From: Martin Kiewitz
Date: Sun, 28 Dec 2014 00:22:30 +0100
Subject: SCI: improve kPortrait debug support + fix
---
engines/sci/graphics/portrait.cpp | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp
index 959c0f6817..3311f47022 100644
--- a/engines/sci/graphics/portrait.cpp
+++ b/engines/sci/graphics/portrait.cpp
@@ -230,7 +230,7 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
debugPrint[raveResource->size] = 0; // set terminating NUL
debug("kPortrait: using actor %s", _resourceName.c_str());
debug("kPortrait (noun %d, verb %d, cond %d, seq %d)", noun, verb, cond, seq);
- debug("kPortrait: %s", debugPrint);
+ debug("kPortrait: rave data is '%s'", debugPrint);
}
#endif
@@ -301,7 +301,11 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
}
#ifdef DEBUG_PORTRAIT
- debug("kPortrait: %d: %x", raveTicks, raveID);
+ if (raveID & 0x0ff) {
+ debug("kPortrait: rave '%c%c' after %d ticks", raveID >> 8, raveID & 0x0ff, raveTicks);
+ } else if (raveID) {
+ debug("kPortrait: rave '%c' after %d ticks", raveID >> 8, raveTicks);
+ }
#endif
timerPosition += raveTicks;
@@ -325,10 +329,9 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
// Tick = 0xFF is the terminator for the data
timerPositionWithin = timerPosition;
raveLipSyncTicks = *raveLipSyncData++;
-#ifdef DEBUG_PORTRAIT
- debug("kPortrait: waiting %d", raveLipSyncTicks);
-#endif
while ( (raveLipSyncData < _lipSyncDataOffsetTableEnd) && (raveLipSyncTicks != 0xFF) ) {
+ if (raveLipSyncTicks)
+ raveLipSyncTicks--; // 1 -> wait 0 ticks, 2 -> wait 1 tick, etc.
timerPositionWithin += raveLipSyncTicks;
do {
@@ -343,7 +346,11 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
raveLipSyncBitmapNr = *raveLipSyncData++;
#ifdef DEBUG_PORTRAIT
- debug("kPortrait: showing bitmap %d", raveLipSyncBitmapNr);
+ if (!raveLipSyncTicks) {
+ debug("kPortrait: showing frame %d", raveLipSyncBitmapNr);
+ } else {
+ debug("kPortrait: showing frame %d after %d ticks", raveLipSyncBitmapNr, raveLipSyncTicks);
+ }
#endif
// bitmap nr within sync data is base 1, we need base 0
--
cgit v1.2.3
From d0ac19062526e5617d08b587e64aee00fd395876 Mon Sep 17 00:00:00 2001
From: Matthew Hoops
Date: Sun, 28 Dec 2014 04:43:22 -0500
Subject: ZVISION: Use VideoDecoder facilities better in AnimationNode
setEndFrame() will ensure the audio stops when it is supposed to. Also removes the hack of retrieving the frame rate through the getDuration()'s timestamp return value.
Thanks to md5 for testing
---
.../zvision/scripting/sidefx/animation_node.cpp | 99 ++++++++++++----------
engines/zvision/scripting/sidefx/animation_node.h | 2 +-
2 files changed, 54 insertions(+), 47 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 3dd80f3699..1657a6e0ec 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -40,19 +40,18 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S
_animation(NULL) {
_animation = engine->loadAnimation(fileName);
+ _animation->start();
- if (fileName.hasSuffix(".rlf"))
- _frmDelay = _animation->getTimeToNextFrame();
- else
- _frmDelay = Common::Rational(1000, _animation->getDuration().framerate()).toInt();
+ if (frate > 0) {
+ _frmDelayOverride = (int32)(1000.0 / frate);
- if (frate > 0)
- _frmDelay = 1000.0 / frate;
-
- // WORKAROUND: We do not allow the engine to delay more than 66 msec
- // per frame (15fps max)
- if (_frmDelay > 66)
- _frmDelay = 66;
+ // WORKAROUND: We do not allow the engine to delay more than 66 msec
+ // per frame (15fps max)
+ if (_frmDelayOverride > 66)
+ _frmDelayOverride = 66;
+ } else {
+ _frmDelayOverride = 0;
+ }
}
AnimationNode::~AnimationNode() {
@@ -90,44 +89,52 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (it != _playList.end()) {
playnode *nod = &(*it);
- nod->_delay -= deltaTimeInMillis;
- if (nod->_delay <= 0) {
- nod->_delay += _frmDelay;
-
- const Graphics::Surface *frame = NULL;
-
- if (nod->_curFrame == -1) { // Start of new playlist node
- nod->_curFrame = nod->start;
-
- _animation->seekToFrame(nod->_curFrame);
- frame = _animation->decodeNextFrame();
-
- nod->_delay = _frmDelay;
- if (nod->slot)
- scriptManager->setStateValue(nod->slot, 1);
- } else {
- nod->_curFrame++;
-
- if (nod->_curFrame > nod->stop) {
- nod->loop--;
-
- if (nod->loop == 0) {
- if (nod->slot >= 0)
- scriptManager->setStateValue(nod->slot, 2);
- if (nod->_scaled) {
- nod->_scaled->free();
- delete nod->_scaled;
- }
- _playList.erase(it);
- return _DisposeAfterUse;
- }
-
- nod->_curFrame = nod->start;
- _animation->seekToFrame(nod->_curFrame);
+ if (nod->_curFrame == -1) {
+ // The node is just beginning playback
+ nod->_curFrame = nod->start;
+
+ _animation->seekToFrame(nod->start);
+ _animation->setEndFrame(nod->stop);
+
+ nod->_delay = deltaTimeInMillis; // Force the frame to draw
+ if (nod->slot)
+ scriptManager->setStateValue(nod->slot, 1);
+ } else if (_animation->endOfVideo()) {
+ // The node has reached the end; check if we need to loop
+ nod->loop--;
+
+ if (nod->loop == 0) {
+ if (nod->slot >= 0)
+ scriptManager->setStateValue(nod->slot, 2);
+ if (nod->_scaled) {
+ nod->_scaled->free();
+ delete nod->_scaled;
}
+ _playList.erase(it);
+ return _DisposeAfterUse;
+ }
- frame = _animation->decodeNextFrame();
+ nod->_curFrame = nod->start;
+ _animation->seekToFrame(nod->start);
+ }
+
+ // Check if we need to draw a frame
+ bool needsUpdate = false;
+ if (_frmDelayOverride == 0) {
+ // If not overridden, use the VideoDecoder's check
+ needsUpdate = _animation->needsUpdate();
+ } else {
+ // Otherwise, implement our own timing
+ nod->_delay -= deltaTimeInMillis;
+
+ if (nod->_delay <= 0) {
+ nod->_delay += _frmDelayOverride;
+ needsUpdate = true;
}
+ }
+
+ if (needsUpdate) {
+ const Graphics::Surface *frame = _animation->decodeNextFrame();
if (frame) {
uint32 dstw;
diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/sidefx/animation_node.h
index 368f0291fd..64270ebc79 100644
--- a/engines/zvision/scripting/sidefx/animation_node.h
+++ b/engines/zvision/scripting/sidefx/animation_node.h
@@ -64,7 +64,7 @@ private:
bool _DisposeAfterUse;
Video::VideoDecoder *_animation;
- int32 _frmDelay;
+ int32 _frmDelayOverride;
public:
bool process(uint32 deltaTimeInMillis);
--
cgit v1.2.3
From 46cd10c5255a7c99620a335094d5af3ccf5a2092 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 28 Dec 2014 11:35:53 +0100
Subject: ACCESS: Fix DisposeAfterUse flags in sound code (thanks to fuzzie)
---
engines/access/sound.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index 221b409aa9..da267bdc4c 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -134,7 +134,7 @@ void SoundManager::playSound(Resource *res, int priority) {
return;
}
- Audio::RewindableAudioStream *audioStream = Audio::makeRawStream(resourceData + 32, sampleSize, sampleRate, 0);
+ Audio::RewindableAudioStream *audioStream = Audio::makeRawStream(resourceData + 32, sampleSize, sampleRate, 0, DisposeAfterUse::NO);
_queue.push_back(audioStream);
} else
@@ -143,7 +143,7 @@ void SoundManager::playSound(Resource *res, int priority) {
if (!_mixer->isSoundHandleActive(_effectsHandle))
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
_queue[0], -1, _mixer->kMaxChannelVolume, 0,
- DisposeAfterUse::NO);
+ DisposeAfterUse::YES);
}
void SoundManager::checkSoundQueue() {
--
cgit v1.2.3
From 78b2c87d510f1ad83e8915e15b7e345a2512d99a Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sun, 28 Dec 2014 15:27:55 +0200
Subject: ZVISION: Document some more controls
---
engines/zvision/scripting/control.cpp | 1 +
engines/zvision/scripting/controls/fist_control.h | 2 +-
engines/zvision/scripting/controls/hotmov_control.h | 2 +-
engines/zvision/scripting/controls/lever_control.h | 1 +
engines/zvision/scripting/controls/paint_control.h | 2 +-
engines/zvision/scripting/controls/safe_control.h | 1 +
engines/zvision/scripting/controls/titler_control.h | 2 +-
engines/zvision/scripting/scr_file_handling.cpp | 15 +++++++++------
8 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/engines/zvision/scripting/control.cpp b/engines/zvision/scripting/control.cpp
index 127f35ef12..81123eb99b 100644
--- a/engines/zvision/scripting/control.cpp
+++ b/engines/zvision/scripting/control.cpp
@@ -72,6 +72,7 @@ void Control::parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &
renderTable->generateRenderTable();
}
+// Only used in Zork Nemesis, handles tilt controls (ZGI doesn't have a tilt view)
void Control::parseTiltControl(ZVision *engine, Common::SeekableReadStream &stream) {
RenderTable *renderTable = engine->getRenderManager()->getRenderTable();
renderTable->setRenderState(RenderTable::TILT);
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
index bad2daa6d5..a41d8511ea 100644
--- a/engines/zvision/scripting/controls/fist_control.h
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -34,7 +34,7 @@ namespace Video {
namespace ZVision {
-// Only used in Zork Nemesis, it handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
+// Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
class FistControl : public Control {
public:
FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/hotmov_control.h b/engines/zvision/scripting/controls/hotmov_control.h
index 640fab00c0..01c83b5837 100644
--- a/engines/zvision/scripting/controls/hotmov_control.h
+++ b/engines/zvision/scripting/controls/hotmov_control.h
@@ -34,7 +34,7 @@ namespace Video {
namespace ZVision {
-// Only used in Zork Nemesis, it handles movies where the player needs to click on something (mj7g, vw3g)
+// Only used in Zork Nemesis, handles movies where the player needs to click on something (mj7g, vw3g)
class HotMovControl : public Control {
public:
HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h
index fdf4a649dc..8787234c51 100644
--- a/engines/zvision/scripting/controls/lever_control.h
+++ b/engines/zvision/scripting/controls/lever_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, handles draggable levers (te2e, tm7e, tp2e, tt2e, tz2e)
class LeverControl : public Control {
public:
LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/paint_control.h b/engines/zvision/scripting/controls/paint_control.h
index 0e5b59b821..8c01f0e68a 100644
--- a/engines/zvision/scripting/controls/paint_control.h
+++ b/engines/zvision/scripting/controls/paint_control.h
@@ -32,7 +32,7 @@
namespace ZVision {
-// Only used in Zork Nemesis, it's the painting puzzle screen in Lucien's room in Irondune (ch4g)
+// Only used in Zork Nemesis, handles the painting puzzle screen in Lucien's room in Irondune (ch4g)
class PaintControl : public Control {
public:
PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/safe_control.h b/engines/zvision/scripting/controls/safe_control.h
index 6e1095e304..2577ff4f79 100644
--- a/engines/zvision/scripting/controls/safe_control.h
+++ b/engines/zvision/scripting/controls/safe_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, handles the safe in the Asylum (ac4g)
class SafeControl : public Control {
public:
SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/titler_control.h b/engines/zvision/scripting/controls/titler_control.h
index 86bb398b3c..dd96e4a846 100644
--- a/engines/zvision/scripting/controls/titler_control.h
+++ b/engines/zvision/scripting/controls/titler_control.h
@@ -32,7 +32,7 @@
namespace ZVision {
-// Only used in Zork Nemesis - it's the death screen with the Restore/Exit buttons
+// Only used in Zork Nemesis, handles the death screen with the Restore/Exit buttons
class TitlerControl : public Control {
public:
TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index fd5c158fcc..4e8c8a6b33 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -349,29 +349,32 @@ Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadS
Control::parsePanoramaControl(_engine, stream);
return NULL;
} else if (controlType.equalsIgnoreCase("tilt")) {
+ // Only used in Zork Nemesis, handles tilt controls (ZGI doesn't have a tilt view)
Control::parseTiltControl(_engine, stream);
return NULL;
- } else if (controlType.equalsIgnoreCase("lever")) {
- return new LeverControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("slot")) {
return new SlotControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("input")) {
return new InputControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("save")) {
return new SaveControl(_engine, key, stream);
+ } else if (controlType.equalsIgnoreCase("lever")) {
+ // Only used in Zork Nemesis, handles draggable levers (te2e, tm7e, tp2e, tt2e, tz2e)
+ return new LeverControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("safe")) {
+ // Only used in Zork Nemesis, handles the safe in the Asylum (ac4g)
return new SafeControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("hotmovie")) {
- // Only used in Zork Nemesis, it handles movies where the player needs to click on something (mj7g, vw3g)
+ // Only used in Zork Nemesis, handles movies where the player needs to click on something (mj7g, vw3g)
return new HotMovControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("fist")) {
- // Only used in Zork Nemesis, it handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
+ // Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
return new FistControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("paint")) {
- // Only used in Zork Nemesis, it's the painting puzzle screen in Lucien's room in Irondune (ch4g)
+ // Only used in Zork Nemesis, handles the painting puzzle screen in Lucien's room in Irondune (ch4g)
return new PaintControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("titler")) {
- // Only used in Zork Nemesis - it's the death screen with the Restore/Exit buttons (cjde)
+ // Only used in Zork Nemesis, handles the death screen with the Restore/Exit buttons (cjde)
return new TitlerControl(_engine, key, stream);
}
return NULL;
--
cgit v1.2.3
From dd347dec83e0d074585cdfd99aa93a17da94ccd4 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sun, 28 Dec 2014 16:57:00 +0200
Subject: DEBUGGER: Extend the md5 and md5mac commands to handle any chunk
length
This will be useful in matching the MD5 checksums with what the
advanced detector returns
---
gui/debugger.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 42 insertions(+), 14 deletions(-)
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 216bd626fe..466681e89d 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -522,11 +522,25 @@ struct ArchiveMemberLess {
bool Debugger::cmdMd5(int argc, const char **argv) {
if (argc < 2) {
- debugPrintf("md5 \n");
+ debugPrintf("md5 [-n length] \n");
} else {
+ uint32 length = 0;
+ uint paramOffset = 0;
+
+ // If the user supplied an -n parameter, set the bytes to read
+ if (!strcmp(argv[1], "-n")) {
+ // Make sure that we have at least two more parameters
+ if (argc < 4) {
+ debugPrintf("md5 [-n length] \n");
+ return true;
+ }
+ length = atoi(argv[2]);
+ paramOffset = 2;
+ }
+
// Assume that spaces are part of a single filename.
- Common::String filename = argv[1];
- for (int i = 2; i < argc; i++) {
+ Common::String filename = argv[1 + paramOffset];
+ for (int i = 2 + paramOffset; i < argc; i++) {
filename = filename + " " + argv[i];
}
Common::ArchiveMemberList list;
@@ -536,9 +550,9 @@ bool Debugger::cmdMd5(int argc, const char **argv) {
} else {
sort(list.begin(), list.end(), ArchiveMemberLess());
for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
- Common::ReadStream *stream = (*iter)->createReadStream();
- Common::String md5 = Common::computeStreamMD5AsString(*stream, 0);
- debugPrintf("%s %s\n", md5.c_str(), (*iter)->getDisplayName().c_str());
+ Common::SeekableReadStream *stream = (*iter)->createReadStream();
+ Common::String md5 = Common::computeStreamMD5AsString(*stream, length);
+ debugPrintf("%s %s %d\n", md5.c_str(), (*iter)->getDisplayName().c_str(), stream->size());
delete stream;
}
}
@@ -548,11 +562,25 @@ bool Debugger::cmdMd5(int argc, const char **argv) {
bool Debugger::cmdMd5Mac(int argc, const char **argv) {
if (argc < 2) {
- debugPrintf("md5mac \n");
+ debugPrintf("md5mac [-n length] \n");
} else {
+ uint32 length = 0;
+ uint paramOffset = 0;
+
+ // If the user supplied an -n parameter, set the bytes to read
+ if (!strcmp(argv[1], "-n")) {
+ // Make sure that we have at least two more parameters
+ if (argc < 4) {
+ debugPrintf("md5mac [-n length] \n");
+ return true;
+ }
+ length = atoi(argv[2]);
+ paramOffset = 2;
+ }
+
// Assume that spaces are part of a single filename.
- Common::String filename = argv[1];
- for (int i = 2; i < argc; i++) {
+ Common::String filename = argv[1 + paramOffset];
+ for (int i = 2 + paramOffset; i < argc; i++) {
filename = filename + " " + argv[i];
}
Common::MacResManager macResMan;
@@ -568,13 +596,13 @@ bool Debugger::cmdMd5Mac(int argc, const char **argv) {
} else {
// The resource fork is probably the most relevant one.
if (macResMan.hasResFork()) {
- Common::String md5 = macResMan.computeResForkMD5AsString(0);
- debugPrintf("%s %s (resource)\n", md5.c_str(), macResMan.getBaseFileName().c_str());
+ Common::String md5 = macResMan.computeResForkMD5AsString(length);
+ debugPrintf("%s %s (resource) %d\n", md5.c_str(), macResMan.getBaseFileName().c_str(), macResMan.getResForkDataSize());
}
if (macResMan.hasDataFork()) {
- Common::ReadStream *stream = macResMan.getDataFork();
- Common::String md5 = Common::computeStreamMD5AsString(*stream, 0);
- debugPrintf("%s %s (data)\n", md5.c_str(), macResMan.getBaseFileName().c_str());
+ Common::SeekableReadStream *stream = macResMan.getDataFork();
+ Common::String md5 = Common::computeStreamMD5AsString(*stream, length);
+ debugPrintf("%s %s (data) %d\n", md5.c_str(), macResMan.getBaseFileName().c_str(), stream->size());
}
}
macResMan.close();
--
cgit v1.2.3
From 39ab507b864d2637d65c1fb7fe3c01003036f78c Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 28 Dec 2014 16:15:03 +0100
Subject: ACCESS: MM - Change detection for the floppy version, add detection
for the demo
---
engines/access/detection_tables.h | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/engines/access/detection_tables.h b/engines/access/detection_tables.h
index 88a64470c5..124f5fcf0d 100644
--- a/engines/access/detection_tables.h
+++ b/engines/access/detection_tables.h
@@ -75,7 +75,22 @@ static const AccessGameDescription gameDescriptions[] = {
{
"martian",
nullptr,
- AD_ENTRY1s("r00.ap", "af98db5ee7f9ef86c6b1f43187a3691b", 31),
+ AD_ENTRY1s("r01.ap", "c081daca9b0cfd710157cf946e343df6", 39352),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_MartianMemorandum,
+ 0
+ },
+
+ {
+ // Martian Memorandum
+ {
+ "martian",
+ "Demo",
+ AD_ENTRY1s("r01.rm", "c2facf9c43047211289044ee39a2322a", 2313),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
--
cgit v1.2.3
From 7e62eb4261455cf908e2f26b0e41cbfbd2292d16 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 28 Dec 2014 16:35:02 +0100
Subject: ACCESS: MM - Load character table
---
engines/access/char.cpp | 6 +++
engines/access/martian/martian_resources.cpp | 62 ++++++++++++++--------------
engines/access/martian/martian_resources.h | 2 +-
3 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/engines/access/char.cpp b/engines/access/char.cpp
index 5bc6707509..49b8c2b082 100644
--- a/engines/access/char.cpp
+++ b/engines/access/char.cpp
@@ -79,6 +79,12 @@ CharManager::CharManager(AccessEngine *vm) : Manager(vm) {
_charTable.push_back(CharEntry(Amazon::CHARTBL[i]));
}
break;
+
+ case GType_MartianMemorandum:
+ for (int i = 0; i < 27; ++i)
+ _charTable.push_back(CharEntry(Martian::CHARTBL_MM[i]));
+ break;
+
default:
error("Unknown game");
}
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index d2b5dfd5d0..2e8a4c30f3 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -436,12 +436,12 @@ const char *const ROOM_DESCR[] = {
const int ROOM_NUMB = 48;
-const byte CHAR_TABLE0[] = {
+const byte MMCHAR_0[] = {
0x02, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
};
-const byte CHAR_TABLE2[] = {
+const byte MMCHAR_2[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x32, 0x33, 0x00, 0x01, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x00, 0x00, 0x00, 0x33,
@@ -454,13 +454,13 @@ const byte CHAR_TABLE2[] = {
0x00, 0x12, 0x00, 0x33, 0x00, 0x0a, 0x00, 0x33, 0x00, 0x13,
0x00, 0xff, 0xff,
};
-const byte CHAR_TABLE3[] = {
+const byte MMCHAR_3[] = {
0x02, 0x31, 0x00, 0x03, 0x00, 0x35, 0x00, 0x37, 0x00, 0x02,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x4b, 0x37, 0x00, 0x01, 0x00,
0xff, 0x37, 0x00, 0x03, 0x00, 0x37, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE4[] = {
+const byte MMCHAR_4[] = {
0x01, 0x31, 0x00, 0x0a, 0x00, 0x36, 0x00, 0x35, 0x00, 0x02,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x49, 0x35, 0x00, 0x01, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0x35, 0x00, 0x00, 0x00, 0x35,
@@ -473,7 +473,7 @@ const byte CHAR_TABLE4[] = {
0x00, 0x13, 0x00, 0x35, 0x00, 0x0b, 0x00, 0x35, 0x00, 0x14,
0x00, 0xff, 0xff,
};
-const byte CHAR_TABLE5[] = {
+const byte MMCHAR_5[] = {
0x01, 0x31, 0x00, 0x08, 0x00, 0x37, 0x00, 0x34, 0x00, 0x02,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x48, 0x34, 0x00, 0x01, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0x34, 0x00, 0x00, 0x00, 0x43,
@@ -490,31 +490,31 @@ const byte CHAR_TABLE5[] = {
0x00, 0x0f, 0x00, 0x43, 0x00, 0x0d, 0x00, 0x34, 0x00, 0x10,
0x00, 0xff, 0xff,
};
-const byte CHAR_TABLE6[] = {
+const byte MMCHAR_6[] = {
0x02, 0x31, 0x00, 0x03, 0x00, 0x38, 0x00, 0x44, 0x00, 0x03,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x4e, 0x44, 0x00, 0x01, 0x00,
0xff, 0x44, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE7[] = {
+const byte MMCHAR_7[] = {
0x02, 0x31, 0x00, 0x01, 0x00, 0x39, 0x00, 0x38, 0x00, 0x02,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x4c, 0x38, 0x00, 0x01, 0x00,
0xff, 0x38, 0x00, 0x03, 0x00, 0x38, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE8[] = {
+const byte MMCHAR_8[] = {
0x03, 0xff, 0xff, 0xff, 0xff, 0x3a, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x3b, 0x00, 0x01, 0x00,
0xff, 0x3b, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE9[] = {
+const byte MMCHAR_9[] = {
0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x59, 0x4a, 0x00, 0x01, 0x00,
0xff, 0x4a, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE10[] = {
+const byte MMCHAR_10[] = {
0x01, 0x31, 0x00, 0x0a, 0x00, 0x3c, 0x00, 0x36, 0x00, 0x02,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x4a, 0x36, 0x00, 0x01, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0x36, 0x00, 0x00, 0x00, 0x36,
@@ -532,19 +532,19 @@ const byte CHAR_TABLE10[] = {
0x00, 0x36, 0x00, 0x11, 0x00, 0x36, 0x00, 0x21, 0x00, 0x36,
0x00, 0x12, 0x00, 0x36, 0x00, 0x22, 0x00, 0xff, 0xff,
};
-const byte CHAR_TABLE11[] = {
+const byte MMCHAR_11[] = {
0x03, 0xff, 0xff, 0xff, 0xff, 0x3d, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x55, 0x45, 0x00, 0x01, 0x00,
0xff, 0x45, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE12[] = {
+const byte MMCHAR_12[] = {
0x03, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0x00, 0x01, 0x00,
0xff, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE13[] = {
+const byte MMCHAR_13[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x46, 0x00, 0x02,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x56, 0x46, 0x00, 0x01, 0x00,
0xff, 0x46, 0x00, 0x03, 0x00, 0x46, 0x00, 0x00, 0x00, 0x46,
@@ -557,7 +557,7 @@ const byte CHAR_TABLE13[] = {
0x00, 0x14, 0x00, 0x46, 0x00, 0x0c, 0x00, 0x46, 0x00, 0x15,
0x00, 0xff, 0xff,
};
-const byte CHAR_TABLE15[] = {
+const byte MMCHAR_15[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x57, 0x47, 0x00, 0x01, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x47,
@@ -565,43 +565,43 @@ const byte CHAR_TABLE15[] = {
0x00, 0x47, 0x00, 0x06, 0x00, 0x47, 0x00, 0x04, 0x00, 0x47,
0x00, 0x07, 0x00, 0xff, 0xff,
};
-const byte CHAR_TABLE16[] = {
+const byte MMCHAR_16[] = {
0x03, 0xff, 0xff, 0xff, 0xff, 0x42, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x54, 0x41, 0x00, 0x01, 0x00,
0xff, 0x41, 0x00, 0x02, 0x00, 0x41, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE18[] = {
+const byte MMCHAR_18[] = {
0x02, 0x31, 0x00, 0x07, 0x00, 0x44, 0x00, 0x3c, 0x00, 0x03,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x50, 0x3c, 0x00, 0x01, 0x00,
0xff, 0x3c, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE19[] = {
+const byte MMCHAR_19[] = {
0x02, 0x31, 0x00, 0x07, 0x00, 0x45, 0x00, 0x3d, 0x00, 0x03,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x51, 0x3d, 0x00, 0x01, 0x00,
0xff, 0x3d, 0x00, 0x02, 0x00, 0x3d, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE20[] = {
+const byte MMCHAR_20[] = {
0x02, 0x31, 0x00, 0x02, 0x00, 0x46, 0x00, 0x48, 0x00, 0x02,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x58, 0x48, 0x00, 0x01, 0x00,
0xff, 0x48, 0x00, 0x03, 0x00, 0x48, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE21[] = {
+const byte MMCHAR_21[] = {
0x02, 0x31, 0x00, 0x07, 0x00, 0x47, 0x00, 0x3e, 0x00, 0x03,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x52, 0x3e, 0x00, 0x01, 0x00,
0xff, 0x3e, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE23[] = {
+const byte MMCHAR_23[] = {
0x02, 0x31, 0x00, 0x08, 0x00, 0x49, 0x00, 0x3f, 0x00, 0x03,
0x00, 0x80, 0x00, 0xf7, 0x00, 0x53, 0x3f, 0x00, 0x01, 0x00,
0xff, 0x3f, 0x00, 0x02, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff,
0xff,
};
-const byte CHAR_TABLE24[] = {
+const byte MMCHAR_24[] = {
0x02, 0x32, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x47, 0x32, 0x00, 0x02, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0x32, 0x00, 0x01, 0x00, 0x32,
@@ -612,13 +612,13 @@ const byte CHAR_TABLE24[] = {
0x00, 0x08, 0x00, 0x32, 0x00, 0x0f, 0x00, 0x32, 0x00, 0x09,
0x00, 0x32, 0x00, 0x10, 0x00, 0xff, 0xff
};
-const byte CHAR_TABLE25[] = {
+const byte MMCHAR_25[] = {
0x02, 0x39, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x39, 0x00, 0x00, 0x00, 0x39, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF
};
-const byte CHAR_TABLE26[] = {
+const byte MMCHAR_26[] = {
0x01, 0x3a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x3a, 0x00, 0x02, 0x00,
0xff, 0x3a, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x42,
@@ -638,7 +638,7 @@ const byte CHAR_TABLE26[] = {
0x00, 0x3a, 0x00, 0x14, 0x00, 0x42, 0x00, 0x11, 0x00, 0x3a,
0x00, 0x15, 0x00, 0xff, 0xff
};
-const byte CHAR_TABLE27[] = {
+const byte MMCHAR_27[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x58, 0x49, 0x00, 0x01, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0x49, 0x00, 0x00, 0x00, 0x49,
@@ -650,13 +650,13 @@ const byte CHAR_TABLE27[] = {
0x00, 0x49, 0x00, 0x10, 0x00, 0x49, 0x00, 0x09, 0x00, 0x49,
0x00, 0x11, 0x00, 0xff, 0xff,
};
-const byte *const CHAR_TABLE[] = {
- CHAR_TABLE0, nullptr, CHAR_TABLE2, CHAR_TABLE3, CHAR_TABLE4, CHAR_TABLE5,
- CHAR_TABLE6, CHAR_TABLE7, CHAR_TABLE8, CHAR_TABLE9, CHAR_TABLE10,
- CHAR_TABLE11, CHAR_TABLE12, CHAR_TABLE13, nullptr, CHAR_TABLE15,
- CHAR_TABLE16, nullptr, CHAR_TABLE18, CHAR_TABLE19, CHAR_TABLE20,
- CHAR_TABLE21, nullptr, CHAR_TABLE23, CHAR_TABLE24, CHAR_TABLE25,
- CHAR_TABLE26, CHAR_TABLE27
+const byte *const CHARTBL_MM[] = {
+ MMCHAR_0, nullptr, MMCHAR_2, MMCHAR_3, MMCHAR_4, MMCHAR_5,
+ MMCHAR_6, MMCHAR_7, MMCHAR_8, MMCHAR_9, MMCHAR_10,
+ MMCHAR_11, MMCHAR_12, MMCHAR_13, nullptr, MMCHAR_15,
+ MMCHAR_16, nullptr, MMCHAR_18, MMCHAR_19, MMCHAR_20,
+ MMCHAR_21, nullptr, MMCHAR_23, MMCHAR_24, MMCHAR_25,
+ MMCHAR_26, MMCHAR_27
};
// TODO: Fix that array
diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h
index a52967d42a..ce8b62801c 100644
--- a/engines/access/martian/martian_resources.h
+++ b/engines/access/martian/martian_resources.h
@@ -41,7 +41,7 @@ extern const byte *const ROOM_TABLE[];
extern const char *const ROOM_DESCR[];
extern const int ROOM_NUMB;
-extern const byte *const CHAR_TABLE[];
+extern const byte *const CHARTBL_MM[];
extern const int COMBO_TABLE[54][4];
--
cgit v1.2.3
From 6590898e6c1e46210e0c49a12874e02d1ad46d6f Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 28 Dec 2014 17:08:07 +0100
Subject: ACCESS: MM - Fix character loading by using a dummy character to
replace missing ones
---
engines/access/martian/martian_resources.cpp | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index 2e8a4c30f3..9f98824de8 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -650,13 +650,15 @@ const byte MMCHAR_27[] = {
0x00, 0x49, 0x00, 0x10, 0x00, 0x49, 0x00, 0x09, 0x00, 0x49,
0x00, 0x11, 0x00, 0xff, 0xff,
};
+
+// HACK: MMCHAR_0 has been used to replace the missing CHAR: 1, 14, 17 and 22
const byte *const CHARTBL_MM[] = {
- MMCHAR_0, nullptr, MMCHAR_2, MMCHAR_3, MMCHAR_4, MMCHAR_5,
- MMCHAR_6, MMCHAR_7, MMCHAR_8, MMCHAR_9, MMCHAR_10,
- MMCHAR_11, MMCHAR_12, MMCHAR_13, nullptr, MMCHAR_15,
- MMCHAR_16, nullptr, MMCHAR_18, MMCHAR_19, MMCHAR_20,
- MMCHAR_21, nullptr, MMCHAR_23, MMCHAR_24, MMCHAR_25,
- MMCHAR_26, MMCHAR_27
+ MMCHAR_0, MMCHAR_0, MMCHAR_2, MMCHAR_3, MMCHAR_4,
+ MMCHAR_5, MMCHAR_6, MMCHAR_7, MMCHAR_8, MMCHAR_9,
+ MMCHAR_10, MMCHAR_11, MMCHAR_12, MMCHAR_13, MMCHAR_0,
+ MMCHAR_15, MMCHAR_16, MMCHAR_0, MMCHAR_18, MMCHAR_19,
+ MMCHAR_20, MMCHAR_21, MMCHAR_0, MMCHAR_23, MMCHAR_24,
+ MMCHAR_25, MMCHAR_26, MMCHAR_27
};
// TODO: Fix that array
--
cgit v1.2.3
From c0a8a360833a7330b75f771fdb762568e48a9e37 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 28 Dec 2014 17:21:16 +0100
Subject: ACCESS: MM - Implement some game logic
---
engines/access/martian/martian_game.cpp | 76 +++++++++++++++++++++++++++------
engines/access/martian/martian_game.h | 4 ++
2 files changed, 68 insertions(+), 12 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index 6392206209..6722120211 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -37,25 +37,77 @@ MartianEngine::MartianEngine(OSystem *syst, const AccessGameDescription *gameDes
MartianEngine::~MartianEngine() {
}
+void MartianEngine::initObjects() {
+ _room = new MartianRoom(this);
+ _scripts = new MartianScripts(this);
+}
+
+void MartianEngine::configSelect() {
+ // No implementation required in MM
+}
+
+void MartianEngine::initVariables() {
+ warning("TODO: initVariables");
+
+ // Set player room and position
+ _player->_roomNumber = 7;
+
+ _inventory->_startInvItem = 0;
+ _inventory->_startInvBox = 0;
+ Common::fill(&_objectsTable[0], &_objectsTable[100], (SpriteResource *)nullptr);
+ _player->_playerOff = false;
+
+ // Setup timers
+ const int TIMER_DEFAULTS[] = { 4, 10, 8, 1, 1, 1, 1, 2 };
+ for (int i = 0; i < 32; ++i) {
+ TimerEntry te;
+ te._initTm = te._timer = (i < 8) ? TIMER_DEFAULTS[i] : 1;
+ te._flag = 1;
+
+ _timers.push_back(te);
+ }
+
+ _player->_playerX = _player->_rawPlayer.x = TRAVEL_POS[_player->_roomNumber][0];
+ _player->_playerY = _player->_rawPlayer.y = TRAVEL_POS[_player->_roomNumber][1];
+ _room->_selectCommand = -1;
+ _events->setNormalCursor(CURSOR_CROSSHAIRS);
+ _mouseMode = 0;
+ _numAnimTimers = 0;
+}
+
void MartianEngine::playGame() {
- // Do introduction
- doIntroduction();
- if (shouldQuit())
- return;
+ // Initialize Amazon game-specific objects
+ initObjects();
// Setup the game
setupGame();
+ configSelect();
- _screen->clearScreen();
- _screen->setPanel(0);
- _screen->forceFadeOut();
+ if (_loadSaveSlot == -1) {
+ // Do introduction
+ doIntroduction();
+ if (shouldQuit())
+ return;
+ }
- _events->showCursor();
+ do {
+ _restartFl = false;
+ _screen->clearScreen();
+ _screen->setPanel(0);
+ _screen->forceFadeOut();
+ _events->showCursor();
- // Setup and execute the room
- _room = new MartianRoom(this);
- _scripts = new MartianScripts(this);
- _room->doRoom();
+ initVariables();
+
+ // If there's a pending savegame to load, load it
+ if (_loadSaveSlot != -1) {
+ loadGameState(_loadSaveSlot);
+ _loadSaveSlot = -1;
+ }
+
+ // Execute the room
+ _room->doRoom();
+ } while (_restartFl);
}
void MartianEngine::doIntroduction() {
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
index a83b67a288..812aa37ed1 100644
--- a/engines/access/martian/martian_game.h
+++ b/engines/access/martian/martian_game.h
@@ -53,6 +53,10 @@ private:
*/
void setupGame();
+ void initObjects();
+ void configSelect();
+ void initVariables();
+
protected:
/**
* Play the game
--
cgit v1.2.3
From 587b1ad69c200ee5b5c987328a65bd8092d9ea4f Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Sun, 28 Dec 2014 18:42:18 +0200
Subject: ZVISION: The fist control is only used in one location
---
engines/zvision/scripting/controls/fist_control.h | 2 +-
engines/zvision/scripting/scr_file_handling.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
index a41d8511ea..74e8f8d8a5 100644
--- a/engines/zvision/scripting/controls/fist_control.h
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -34,7 +34,7 @@ namespace Video {
namespace ZVision {
-// Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
+// Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td9e)
class FistControl : public Control {
public:
FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index 4e8c8a6b33..227c43557c 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -368,7 +368,7 @@ Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadS
// Only used in Zork Nemesis, handles movies where the player needs to click on something (mj7g, vw3g)
return new HotMovControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("fist")) {
- // Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td60, td90, td9e)
+ // Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td9e)
return new FistControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("paint")) {
// Only used in Zork Nemesis, handles the painting puzzle screen in Lucien's room in Irondune (ch4g)
--
cgit v1.2.3
From f1d6ba7085be53cb641f71ef726dadf3f075b311 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 28 Dec 2014 23:35:14 +0100
Subject: ACCESS: Remove useless variable
---
engines/access/player.cpp | 1 -
engines/access/player.h | 1 -
2 files changed, 2 deletions(-)
diff --git a/engines/access/player.cpp b/engines/access/player.cpp
index bcd553c6dc..e47daf532c 100644
--- a/engines/access/player.cpp
+++ b/engines/access/player.cpp
@@ -48,7 +48,6 @@ Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() {
_playerSprites1 = nullptr;
_manPal1 = nullptr;
_frameNumber = 0;
- _monData = nullptr;
_rawTempL = 0;
_rawXTemp = 0;
_rawYTempL = 0;
diff --git a/engines/access/player.h b/engines/access/player.h
index 26caec681f..329cc15ed2 100644
--- a/engines/access/player.h
+++ b/engines/access/player.h
@@ -84,7 +84,6 @@ public:
Direction _playerDirection;
SpriteResource *_playerSprites;
// Fields in original Player structure
- byte *_monData;
int _walkOffRight[PLAYER_DATA_COUNT];
int _walkOffLeft[PLAYER_DATA_COUNT];
int _walkOffUp[PLAYER_DATA_COUNT];
--
cgit v1.2.3
From 6d55998b40f62518959f849922919b6b0562981e Mon Sep 17 00:00:00 2001
From: Matthew Hoops
Date: Sun, 28 Dec 2014 21:19:27 -0500
Subject: ZVISION: Make the rest of the controls properly use VideoDecoder
timing
The hacky use of getDuration() to retrieve the framerate() is gone
Thanks to md5 for testing (and for filling in a few gaps since I was coding in the blind ;))
---
.../zvision/scripting/controls/fist_control.cpp | 53 +++++++---------------
engines/zvision/scripting/controls/fist_control.h | 5 --
.../zvision/scripting/controls/hotmov_control.cpp | 53 +++++++++-------------
.../zvision/scripting/controls/hotmov_control.h | 4 --
.../zvision/scripting/controls/input_control.cpp | 19 ++------
.../zvision/scripting/controls/safe_control.cpp | 53 ++++++----------------
engines/zvision/scripting/controls/safe_control.h | 7 ---
7 files changed, 58 insertions(+), 136 deletions(-)
diff --git a/engines/zvision/scripting/controls/fist_control.cpp b/engines/zvision/scripting/controls/fist_control.cpp
index 34a64b4298..4a8e8b1bbd 100644
--- a/engines/zvision/scripting/controls/fist_control.cpp
+++ b/engines/zvision/scripting/controls/fist_control.cpp
@@ -46,10 +46,6 @@ FistControl::FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream
_order = 0;
_fistnum = 0;
- _frameCur = -1;
- _frameEnd = -1;
- _frameTime = 0;
- _lastRenderedFrame = -1;
_animationId = 0;
clearFistArray(_fistsUp);
@@ -95,41 +91,23 @@ FistControl::~FistControl() {
_entries.clear();
}
-void FistControl::renderFrame(uint frameNumber) {
- if ((int32)frameNumber == _lastRenderedFrame)
- return;
-
- _lastRenderedFrame = frameNumber;
-
- const Graphics::Surface *frameData;
-
- if (_animation) {
- _animation->seekToFrame(frameNumber);
- frameData = _animation->decodeNextFrame();
- if (frameData)
- _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _anmRect);
- }
-}
-
bool FistControl::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- if (_frameCur >= 0 && _frameEnd >= 0)
- if (_frameCur <= _frameEnd) {
- _frameTime -= deltaTimeInMillis;
-
- if (_frameTime <= 0) {
- _frameTime = 1000.0 / _animation->getDuration().framerate();
-
- renderFrame(_frameCur);
-
- _frameCur++;
+ if (_animation && _animation->isPlaying()) {
+ if (_animation->endOfVideo()) {
+ _animation->stop();
+ _engine->getScriptManager()->setStateValue(_animationId, 2);
+ return false;
+ }
- if (_frameCur > _frameEnd)
- _engine->getScriptManager()->setStateValue(_animationId, 2);
- }
+ if (_animation->needsUpdate()) {
+ const Graphics::Surface *frameData = _animation->decodeNextFrame();
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _anmRect);
}
+ }
return false;
}
@@ -160,9 +138,12 @@ bool FistControl::onMouseUp(const Common::Point &screenSpacePos, const Common::P
for (int i = 0; i < _numEntries; i++)
if (_entries[i]._bitsStrt == oldStatus && _entries[i]._bitsEnd == _fiststatus) {
- _frameCur = _entries[i]._anmStrt;
- _frameEnd = _entries[i]._anmEnd;
- _frameTime = 0;
+ if (_animation) {
+ _animation->stop();
+ _animation->seekToFrame(_entries[i]._anmStrt);
+ _animation->setEndFrame(_entries[i]._anmEnd);
+ _animation->start();
+ }
_engine->getScriptManager()->setStateValue(_animationId, 1);
_engine->getScriptManager()->setStateValue(_soundKey, _entries[i]._sound);
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
index 74e8f8d8a5..d7cbcb1f71 100644
--- a/engines/zvision/scripting/controls/fist_control.h
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -64,10 +64,6 @@ private:
Video::VideoDecoder *_animation;
Common::Rect _anmRect;
int32 _soundKey;
- int32 _frameCur;
- int32 _frameEnd;
- int32 _frameTime;
- int32 _lastRenderedFrame;
int32 _animationId;
public:
@@ -76,7 +72,6 @@ public:
bool process(uint32 deltaTimeInMillis);
private:
- void renderFrame(uint frameNumber);
void readDescFile(const Common::String &fileName);
void clearFistArray(Common::Array< Common::Array > &arr);
uint32 readBits(const char *str);
diff --git a/engines/zvision/scripting/controls/hotmov_control.cpp b/engines/zvision/scripting/controls/hotmov_control.cpp
index e77272ec73..182447a990 100644
--- a/engines/zvision/scripting/controls/hotmov_control.cpp
+++ b/engines/zvision/scripting/controls/hotmov_control.cpp
@@ -41,10 +41,7 @@ HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadSt
: Control(engine, key, CONTROL_HOTMOV) {
_animation = NULL;
_cycle = 0;
- _curFrame = -1;
- _lastRenderedFrame = -1;
_frames.clear();
- _frameTime = 0;
_cyclesCount = 0;
_framesCount = 0;
@@ -78,6 +75,7 @@ HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadSt
sscanf(values.c_str(), "%s", filename);
values = Common::String(filename);
_animation = _engine->loadAnimation(values);
+ _animation->start();
} else if (param.matchString("venus_id", true)) {
_venusId = atoi(values.c_str());
}
@@ -95,41 +93,26 @@ HotMovControl::~HotMovControl() {
_frames.clear();
}
-void HotMovControl::renderFrame(uint frameNumber) {
- if ((int)frameNumber == _lastRenderedFrame)
- return;
-
- _lastRenderedFrame = frameNumber;
-
- const Graphics::Surface *frameData;
-
- if (_animation) {
- _animation->seekToFrame(frameNumber);
- frameData = _animation->decodeNextFrame();
- if (frameData)
- _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
- }
-}
-
bool HotMovControl::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
if (_cycle < _cyclesCount) {
- _frameTime -= deltaTimeInMillis;
+ if (_animation && _animation->endOfVideo()) {
+ _cycle++;
- if (_frameTime <= 0) {
- _curFrame++;
- if (_curFrame >= _framesCount) {
- _curFrame = 0;
- _cycle++;
- }
- if (_cycle != _cyclesCount)
- renderFrame(_curFrame);
- else
+ if (_cycle == _cyclesCount) {
_engine->getScriptManager()->setStateValue(_key, 2);
+ return false;
+ }
+
+ _animation->rewind();
+ }
- _frameTime = 1000.0 / _animation->getDuration().framerate();
+ if (_animation && _animation->needsUpdate()) {
+ const Graphics::Surface *frameData = _animation->decodeNextFrame();
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
}
}
@@ -140,8 +123,11 @@ bool HotMovControl::onMouseMove(const Common::Point &screenSpacePos, const Commo
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
+ if (!_animation)
+ return false;
+
if (_cycle < _cyclesCount) {
- if (_frames[_curFrame].contains(backgroundImageSpacePos)) {
+ if (_frames[_animation->getCurFrame()].contains(backgroundImageSpacePos)) {
_engine->getCursorManager()->changeCursor(CursorIndex_Active);
return true;
}
@@ -154,8 +140,11 @@ bool HotMovControl::onMouseUp(const Common::Point &screenSpacePos, const Common:
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
+ if (!_animation)
+ return false;
+
if (_cycle < _cyclesCount) {
- if (_frames[_curFrame].contains(backgroundImageSpacePos)) {
+ if (_frames[_animation->getCurFrame()].contains(backgroundImageSpacePos)) {
setVenus();
_engine->getScriptManager()->setStateValue(_key, 1);
return true;
diff --git a/engines/zvision/scripting/controls/hotmov_control.h b/engines/zvision/scripting/controls/hotmov_control.h
index 01c83b5837..99d1fd0979 100644
--- a/engines/zvision/scripting/controls/hotmov_control.h
+++ b/engines/zvision/scripting/controls/hotmov_control.h
@@ -42,9 +42,6 @@ public:
private:
int32 _framesCount;
- int32 _frameTime;
- int32 _curFrame;
- int32 _lastRenderedFrame;
int32 _cycle;
int32 _cyclesCount;
Video::VideoDecoder *_animation;
@@ -56,7 +53,6 @@ public:
bool process(uint32 deltaTimeInMillis);
private:
- void renderFrame(uint frameNumber);
void readHsFile(const Common::String &fileName);
};
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index 4abc0c9e1b..47da27fa08 100644
--- a/engines/zvision/scripting/controls/input_control.cpp
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -46,9 +46,7 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre
_enterPressed(false),
_readOnly(false),
_txtWidth(0),
- _animation(NULL),
- _frameDelay(0),
- _frame(-1) {
+ _animation(NULL) {
// Loop until we find the closing brace
Common::String line = stream.readLine();
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
@@ -99,8 +97,7 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre
sscanf(values.c_str(), "%24s %*u", fileName);
_animation = _engine->loadAnimation(fileName);
- _frame = -1;
- _frameDelay = 0;
+ _animation->start();
} else if (param.matchString("focus", true)) {
_focused = true;
_engine->getScriptManager()->setFocusControlKey(_key);
@@ -212,16 +209,10 @@ bool InputControl::process(uint32 deltaTimeInMillis) {
}
if (_animation && !_readOnly && _focused) {
- bool needDraw = true;// = _textChanged;
- _frameDelay -= deltaTimeInMillis;
- if (_frameDelay <= 0) {
- _frame = (_frame + 1) % _animation->getFrameCount();
- _frameDelay = 1000.0 / _animation->getDuration().framerate();
- needDraw = true;
- }
+ if (_animation->endOfVideo())
+ _animation->rewind();
- if (needDraw) {
- _animation->seekToFrame(_frame);
+ if (_animation->needsUpdate()) {
const Graphics::Surface *srf = _animation->decodeNextFrame();
int16 xx = _textRectangle.left + _txtWidth;
if (xx >= _textRectangle.left + (_textRectangle.width() - (int16)_animation->getWidth()))
diff --git a/engines/zvision/scripting/controls/safe_control.cpp b/engines/zvision/scripting/controls/safe_control.cpp
index 71be692431..6ba34106d0 100644
--- a/engines/zvision/scripting/controls/safe_control.cpp
+++ b/engines/zvision/scripting/controls/safe_control.cpp
@@ -49,10 +49,7 @@ SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream
_outerRadiusSqr = 0;
_zeroPointer = 0;
_startPointer = 0;
- _curFrame = -1;
_targetFrame = 0;
- _frameTime = 0;
- _lastRenderedFrame = -1;
// Loop until we find the closing brace
Common::String line = stream.readLine();
@@ -64,6 +61,7 @@ SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream
while (!stream.eos() && !line.contains('}')) {
if (param.matchString("animation", true)) {
_animation = _engine->loadAnimation(values);
+ _animation->start();
} else if (param.matchString("rectangle", true)) {
int x;
int y;
@@ -104,7 +102,9 @@ SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
getParams(line, param, values);
}
- renderFrame(_curState);
+
+ if (_animation)
+ _animation->seekToFrame(_curState);
}
SafeControl::~SafeControl() {
@@ -113,44 +113,20 @@ SafeControl::~SafeControl() {
}
-void SafeControl::renderFrame(uint frameNumber) {
- if (frameNumber == 0) {
- _lastRenderedFrame = frameNumber;
- } else if ((int16)frameNumber < _lastRenderedFrame) {
- _lastRenderedFrame = frameNumber;
- frameNumber = (_statesCount * 2) - frameNumber;
- } else {
- _lastRenderedFrame = frameNumber;
- }
-
- const Graphics::Surface *frameData;
- int x = _rectangle.left;
- int y = _rectangle.top;
-
- _animation->seekToFrame(frameNumber);
- frameData = _animation->decodeNextFrame();
- if (frameData)
- _engine->getRenderManager()->blitSurfaceToBkg(*frameData, x, y);
-}
-
bool SafeControl::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- if (_curFrame != _targetFrame) {
- _frameTime -= deltaTimeInMillis;
-
- if (_frameTime <= 0) {
- if (_curFrame < _targetFrame) {
- _curFrame++;
- renderFrame(_curFrame);
- } else if (_curFrame > _targetFrame) {
- _curFrame--;
- renderFrame(_curFrame);
- }
- _frameTime = 1000.0 / _animation->getDuration().framerate();
- }
+ if (_animation && _animation->getCurFrame() != _targetFrame && _animation->needsUpdate()) {
+ // If we're past the target frame, move back one
+ if (_animation->getCurFrame() > _targetFrame)
+ _animation->seekToFrame(_animation->getCurFrame() - 1);
+
+ const Graphics::Surface *frameData = _animation->decodeNextFrame();
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkg(*frameData, _rectangle.left, _rectangle.top);
}
+
return false;
}
@@ -187,7 +163,8 @@ bool SafeControl::onMouseUp(const Common::Point &screenSpacePos, const Common::P
int16 tmp2 = (m_state + _curState - _zeroPointer + _statesCount - 1) % _statesCount;
- _curFrame = (_curState + _statesCount - _startPointer) % _statesCount;
+ if (_animation)
+ _animation->seekToFrame((_curState + _statesCount - _startPointer) % _statesCount);
_curState = (_statesCount * 2 + tmp2) % _statesCount;
diff --git a/engines/zvision/scripting/controls/safe_control.h b/engines/zvision/scripting/controls/safe_control.h
index 2577ff4f79..3e8c17635c 100644
--- a/engines/zvision/scripting/controls/safe_control.h
+++ b/engines/zvision/scripting/controls/safe_control.h
@@ -52,19 +52,12 @@ private:
int32 _outerRadiusSqr;
int16 _zeroPointer;
int16 _startPointer;
- int16 _curFrame;
int16 _targetFrame;
- int32 _frameTime;
-
- int16 _lastRenderedFrame;
public:
bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
bool process(uint32 deltaTimeInMillis);
-
-private:
- void renderFrame(uint frameNumber);
};
} // End of namespace ZVision
--
cgit v1.2.3
From a33a9ae2e85c7999e9234538a3979d61ca431626 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 29 Dec 2014 07:22:51 +0100
Subject: ACCESS: Split a bit more Player class, add some MM specific code
---
engines/access/access.cpp | 1 +
engines/access/access.h | 1 +
engines/access/amazon/amazon_player.cpp | 2 +-
engines/access/martian/martian_player.cpp | 62 ++++++++++++++++++++++++
engines/access/martian/martian_player.h | 48 +++++++++++++++++++
engines/access/martian/martian_resources.cpp | 5 ++
engines/access/martian/martian_resources.h | 5 ++
engines/access/martian/martian_room.cpp | 70 ++++++++++------------------
engines/access/martian/martian_room.h | 2 -
engines/access/module.mk | 1 +
engines/access/player.cpp | 35 +++++++++++---
engines/access/player.h | 18 ++++---
12 files changed, 186 insertions(+), 64 deletions(-)
create mode 100644 engines/access/martian/martian_player.cpp
create mode 100644 engines/access/martian/martian_player.h
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 6ad1b22408..14aa68c9dc 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -51,6 +51,7 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_destIn = nullptr;
_current = nullptr;
_mouseMode = 0;
+ _playerDataCount = 0;
_currentMan = 0;
_currentManOld = -1;
_converseMode = 0;
diff --git a/engines/access/access.h b/engines/access/access.h
index a082b969c4..8801c1b04f 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -173,6 +173,7 @@ public:
ImageEntryList _images;
int _mouseMode;
+ int _playerDataCount;
int _currentManOld;
int _converseMode;
int _startAboutBox;
diff --git a/engines/access/amazon/amazon_player.cpp b/engines/access/amazon/amazon_player.cpp
index b1ed501fce..2f32db1a9b 100644
--- a/engines/access/amazon/amazon_player.cpp
+++ b/engines/access/amazon/amazon_player.cpp
@@ -48,7 +48,7 @@ void AmazonPlayer::load() {
_downDelta = -2;
_scrollConst = 2;
- for (int i = 0; i < PLAYER_DATA_COUNT; ++i) {
+ for (int i = 0; i < _vm->_playerDataCount; ++i) {
_walkOffRight[i] = OVEROFFR[i];
_walkOffLeft[i] = OVEROFFL[i];
_walkOffUp[i] = OVEROFFU[i];
diff --git a/engines/access/martian/martian_player.cpp b/engines/access/martian/martian_player.cpp
new file mode 100644
index 0000000000..493776e411
--- /dev/null
+++ b/engines/access/martian/martian_player.cpp
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "access/access.h"
+#include "access/room.h"
+#include "access/martian/martian_game.h"
+#include "access/martian/martian_player.h"
+#include "access/martian/martian_resources.h"
+
+namespace Access {
+
+namespace Martian {
+
+MartianPlayer::MartianPlayer(AccessEngine *vm) : Player(vm) {
+ _game = (MartianEngine *)vm;
+}
+
+void MartianPlayer::load() {
+ Player::load();
+
+ // Overwrite game-specific values
+ _playerOffset.x = _vm->_screen->_scaleTable1[20];
+ _playerOffset.y = _vm->_screen->_scaleTable1[52];
+ _leftDelta = -9;
+ _rightDelta = 33;
+ _upDelta = 5;
+ _downDelta = -5;
+ _scrollConst = 5;
+
+ _sideWalkMin = 0;
+ _sideWalkMax = 7;
+ _upWalkMin = 8;
+ _upWalkMax = 14;
+ _downWalkMin = 15;
+ _downWalkMax = 23;
+
+ warning("TODO: Copy texPal into manPal");
+}
+
+} // End of namespace Martian
+
+} // End of namespace Access
diff --git a/engines/access/martian/martian_player.h b/engines/access/martian/martian_player.h
new file mode 100644
index 0000000000..192f2540cc
--- /dev/null
+++ b/engines/access/martian/martian_player.h
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ACCESS_MARTIAN_PLAYER_H
+#define ACCESS_MARTIAN_PLAYER_H
+
+#include "common/scummsys.h"
+#include "access/player.h"
+
+namespace Access {
+
+namespace Martian {
+
+class MartianEngine;
+
+class MartianPlayer : public Player {
+private:
+ MartianEngine *_game;
+public:
+ MartianPlayer(AccessEngine *vm);
+
+ virtual void load();
+};
+
+} // End of namespace Martian
+
+} // End of namespace Access
+
+#endif /* ACCESS_MARTIAN_PLAYER_H */
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index 9f98824de8..78d14b7c86 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -719,6 +719,11 @@ const int COMBO_TABLE[54][4] = {
{ -1, -1, -1, -1 }
};
+const int SIDEOFFR[] = { 4, 0, 7, 10, 3, 1, 2, 13, 0, 0, 0, 0 };
+const int SIDEOFFL[] = { 11, 6, 1, 4, 10, 6, 1, 4, 0, 0, 0, 0 };
+const int SIDEOFFU[] = { 1, 2, 0, 2, 2, 1, 1, 0, 0, 0, 0, 0 };
+const int SIDEOFFD[] = { 2, 0, 1, 1, 0, 1, 1, 1, 2, 0, 0, 0 };
+
} // End of namespace Martian
} // End of namespace Access
diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h
index ce8b62801c..36b4ce3d37 100644
--- a/engines/access/martian/martian_resources.h
+++ b/engines/access/martian/martian_resources.h
@@ -45,6 +45,11 @@ extern const byte *const CHARTBL_MM[];
extern const int COMBO_TABLE[54][4];
+extern const int SIDEOFFR[];
+extern const int SIDEOFFL[];
+extern const int SIDEOFFU[];
+extern const int SIDEOFFD[];
+
} // End of namespace Martian
} // End of namespace Access
diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp
index e9d1b9d8cf..972aada5d6 100644
--- a/engines/access/martian/martian_room.cpp
+++ b/engines/access/martian/martian_room.cpp
@@ -43,72 +43,52 @@ void MartianRoom::loadRoom(int roomNumber) {
}
void MartianRoom::reloadRoom() {
- loadRoom(_vm->_player->_roomNumber);
-
- if (_roomFlag != 1) {
- _vm->_currentMan = _roomFlag;
- _vm->_currentManOld = _roomFlag;
- _vm->_manScaleOff = 0;
-
- switch (_vm->_currentMan) {
- case 0:
- _vm->_player->loadSprites("MAN.LZ");
- break;
+ warning("TODO: Load TEXPAL.COL");
+// _vm->_currentMan = _roomFlag;
+// _vm->_currentManOld = _roomFlag;
+// _vm->_manScaleOff = 0;
- case 2:
- _vm->_player->loadSprites("JMAN.LZ");
- break;
+ _vm->_player->loadSprites("TEX.LZ");
+ warning("TODO: Load TEXPAL.COL");
- case 3:
- _vm->_player->loadSprites("OVERHEAD.LZ");
- _vm->_manScaleOff = 1;
- break;
-
- default:
- break;
- }
- }
+ loadRoom(_vm->_player->_roomNumber);
reloadRoom1();
}
void MartianRoom::reloadRoom1() {
- if (_vm->_player->_roomNumber == 29 || _vm->_player->_roomNumber == 31
- || _vm->_player->_roomNumber == 42 || _vm->_player->_roomNumber == 44) {
- //Resource *spriteData = _vm->_files->loadFile("MAYA.LZ");
- //_vm->_inactive._spritesPtr = new SpriteResource(_vm, spriteData);
- //delete spriteData;
- _vm->_currentCharFlag = false;
- }
-
_selectCommand = -1;
- _vm->_events->setNormalCursor(CURSOR_CROSSHAIRS);
- _vm->_mouseMode = 0;
- _vm->_boxSelect = true;
+
+// CHECKME: Useful?
+// _vm->_events->setNormalCursor(CURSOR_CROSSHAIRS);
+// _vm->_mouseMode = 0;
+// _vm->_boxSelect = true;
+
_vm->_player->_playerOff = false;
- _vm->_screen->fadeOut();
+ _vm->_screen->forceFadeOut();
+ _vm->_events->hideCursor();
_vm->_screen->clearScreen();
+ _vm->_events->showCursor();
roomSet();
+ _vm->_player->load();
- // TODO: Refactor
+ if (_vm->_player->_roomNumber != 47)
+ _vm->_player->calcManScale();
+ _vm->_events->hideCursor();
+ roomMenu();
_vm->_screen->setBufferScan();
setupRoom();
setWallCodes();
buildScreen();
-
- if (!_vm->_screen->_vesaMode) {
- _vm->copyBF2Vid();
- } else if (_vm->_player->_roomNumber != 20 && _vm->_player->_roomNumber != 24
- && _vm->_player->_roomNumber != 33) {
- _vm->_screen->setPalette();
- _vm->copyBF2Vid();
- }
-
+ _vm->copyBF2Vid();
+ warning("TODO: setManPalette");
+ _vm->_events->showCursor();
_vm->_player->_frame = 0;
_vm->_oldRects.clear();
_vm->_newRects.clear();
+ _vm->_events->clearEvents();
}
void MartianRoom::roomSet() {
diff --git a/engines/access/martian/martian_room.h b/engines/access/martian/martian_room.h
index 85529ce8f0..cb2a8c2229 100644
--- a/engines/access/martian/martian_room.h
+++ b/engines/access/martian/martian_room.h
@@ -52,8 +52,6 @@ public:
virtual ~MartianRoom();
- virtual void loadRoomData(const byte *roomData) { warning("TODO - loadRoomData"); }
-
virtual void init4Quads() { }
virtual void roomMenu();
diff --git a/engines/access/module.mk b/engines/access/module.mk
index b6961aeca9..f7cf7f2261 100644
--- a/engines/access/module.mk
+++ b/engines/access/module.mk
@@ -28,6 +28,7 @@ MODULE_OBJS := \
amazon/amazon_room.o \
amazon/amazon_scripts.o \
martian/martian_game.o \
+ martian/martian_player.o \
martian/martian_resources.o \
martian/martian_room.o \
martian/martian_scripts.o
diff --git a/engines/access/player.cpp b/engines/access/player.cpp
index d547aedc1d..1fe58c6a1c 100644
--- a/engines/access/player.cpp
+++ b/engines/access/player.cpp
@@ -26,24 +26,25 @@
#include "access/access.h"
#include "access/resources.h"
#include "access/amazon/amazon_player.h"
+#include "access/martian/martian_player.h"
namespace Access {
Player *Player::init(AccessEngine *vm) {
switch (vm->getGameID()) {
case GType_Amazon:
+ vm->_playerDataCount = 8;
return new Amazon::AmazonPlayer(vm);
+ case GType_MartianMemorandum:
+ vm->_playerDataCount = 10;
+ return new Martian::MartianPlayer(vm);
default:
+ vm->_playerDataCount = 8;
return new Player(vm);
}
}
Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() {
- Common::fill(&_walkOffRight[0], &_walkOffRight[PLAYER_DATA_COUNT], 0);
- Common::fill(&_walkOffLeft[0], &_walkOffLeft[PLAYER_DATA_COUNT], 0);
- Common::fill(&_walkOffUp[0], &_walkOffUp[PLAYER_DATA_COUNT], 0);
- Common::fill(&_walkOffDown[0], &_walkOffDown[PLAYER_DATA_COUNT], 0);
-
_playerSprites = nullptr;
_playerSprites1 = nullptr;
_manPal1 = nullptr;
@@ -73,14 +74,36 @@ Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() {
_playerDirection = NONE;
_xFlag = _yFlag = 0;
_inactiveYOff = 0;
+ _walkOffRight = _walkOffLeft = nullptr;
+ _walkOffUp = _walkOffDown = nullptr;
+ _walkOffUR = _walkOffDR = nullptr;
+ _walkOffUL = _walkOffDL = nullptr;
}
Player::~Player() {
delete _playerSprites;
delete[] _manPal1;
+ delete[] _walkOffRight;
+ delete[] _walkOffLeft;
+ delete[] _walkOffUp;
+ delete[] _walkOffDown;
+ delete[] _walkOffUR;
+ delete[] _walkOffDR;
+ delete[] _walkOffUL;
+ delete[] _walkOffDL;
}
void Player::load() {
+ int dataCount = _vm->_playerDataCount;
+ _walkOffRight = new int[dataCount];
+ _walkOffLeft = new int[dataCount];
+ _walkOffUp = new int[dataCount];
+ _walkOffDown = new int[dataCount];
+ _walkOffUR = new Common::Point[dataCount];
+ _walkOffDR = new Common::Point[dataCount];
+ _walkOffUL = new Common::Point[dataCount];
+ _walkOffDL = new Common::Point[dataCount];
+
_playerOffset.x = _vm->_screen->_scaleTable1[25];
_playerOffset.y = _vm->_screen->_scaleTable1[67];
_leftDelta = -3;
@@ -89,7 +112,7 @@ void Player::load() {
_downDelta = -10;
_scrollConst = 5;
- for (int i = 0; i < PLAYER_DATA_COUNT; ++i) {
+ for (int i = 0; i < dataCount; ++i) {
_walkOffRight[i] = SIDEOFFR[i];
_walkOffLeft[i] = SIDEOFFL[i];
_walkOffUp[i] = SIDEOFFU[i];
diff --git a/engines/access/player.h b/engines/access/player.h
index 26caec681f..1b33ae63ec 100644
--- a/engines/access/player.h
+++ b/engines/access/player.h
@@ -31,8 +31,6 @@
namespace Access {
-#define PLAYER_DATA_COUNT 8
-
enum Direction {
NONE = 0,
UP = 1,
@@ -85,14 +83,14 @@ public:
SpriteResource *_playerSprites;
// Fields in original Player structure
byte *_monData;
- int _walkOffRight[PLAYER_DATA_COUNT];
- int _walkOffLeft[PLAYER_DATA_COUNT];
- int _walkOffUp[PLAYER_DATA_COUNT];
- int _walkOffDown[PLAYER_DATA_COUNT];
- Common::Point _walkOffUR[PLAYER_DATA_COUNT];
- Common::Point _walkOffDR[PLAYER_DATA_COUNT];
- Common::Point _walkOffUL[PLAYER_DATA_COUNT];
- Common::Point _walkOffDL[PLAYER_DATA_COUNT];
+ int *_walkOffRight;
+ int *_walkOffLeft;
+ int *_walkOffUp;
+ int *_walkOffDown;
+ Common::Point *_walkOffUR;
+ Common::Point *_walkOffDR;
+ Common::Point *_walkOffUL;
+ Common::Point *_walkOffDL;
byte _rawTempL;
int _rawXTemp;
byte _rawYTempL;
--
cgit v1.2.3
From 83dd389d255ae63affc3600742d564a8d2cb914c Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 29 Dec 2014 12:13:43 +0200
Subject: CREDITS: Update credits for ZVision again
---
devtools/credits.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 69eede756d..7dc954a6a7 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -792,7 +792,7 @@ begin_credits("Credits");
begin_section("ZVision");
add_person("Adrian Astley", "RichieSams", "");
add_person("Filippos Karapetis", "[md5]", "");
- add_person("Anton Yarcev", "Marisa-Chan", "");
+ add_person("Anton Yarcev", "Zidane", "");
end_section();
end_section();
--
cgit v1.2.3
From f4d5b150f1e4b786f2f6f79a1acd3315da9a8699 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Mon, 29 Dec 2014 12:34:55 +0200
Subject: ZVISION: Show system messages when subtitles are disabled
Thanks to Marisa-Chan for spotting this
---
engines/zvision/graphics/render_manager.cpp | 2 +-
engines/zvision/scripting/sidefx/music_node.cpp | 2 +-
engines/zvision/scripting/sidefx/syncsound_node.cpp | 2 +-
engines/zvision/video/video.cpp | 4 +++-
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 033d099042..1b80b379bf 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -741,7 +741,7 @@ void RenderManager::processSubs(uint16 deltatime) {
}
}
- if (redraw && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1) {
+ if (redraw) {
_subtitleSurface.fillRect(Common::Rect(_subtitleSurface.w, _subtitleSurface.h), 0);
for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
diff --git a/engines/zvision/scripting/sidefx/music_node.cpp b/engines/zvision/scripting/sidefx/music_node.cpp
index 6be08b46dc..0cada6d748 100644
--- a/engines/zvision/scripting/sidefx/music_node.cpp
+++ b/engines/zvision/scripting/sidefx/music_node.cpp
@@ -137,7 +137,7 @@ bool MusicNode::process(uint32 deltaTimeInMillis) {
if (_pantrack || _volume != _newvol)
setVolume(_newvol);
- if (_sub)
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
_sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
}
return false;
diff --git a/engines/zvision/scripting/sidefx/syncsound_node.cpp b/engines/zvision/scripting/sidefx/syncsound_node.cpp
index c1f139694b..eec320bf2e 100644
--- a/engines/zvision/scripting/sidefx/syncsound_node.cpp
+++ b/engines/zvision/scripting/sidefx/syncsound_node.cpp
@@ -76,7 +76,7 @@ bool SyncSoundNode::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getSideFX(_syncto) == NULL)
return stop();
- if (_sub)
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
_sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
}
return false;
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index e67e6570c5..0913b28818 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -29,6 +29,7 @@
#include "zvision/zvision.h"
#include "zvision/core/clock.h"
#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting//script_manager.h"
#include "zvision/text/subtitles.h"
#include "zvision/video/rlf_decoder.h"
#include "zvision/video/zork_avi_decoder.h"
@@ -75,6 +76,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
uint16 y = _workingWindow.top + dst.top;
uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width();
uint16 finalHeight = dst.height() < _workingWindow.height() ? dst.height() : _workingWindow.height();
+ bool showSubs = (_scriptManager->getStateValue(StateKey_Subtitles) == 1);
_clock.stop();
vid.start();
@@ -106,7 +108,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
if (vid.needsUpdate()) {
const Graphics::Surface *frame = vid.decodeNextFrame();
- if (sub)
+ if (sub && showSubs)
sub->process(vid.getCurFrame());
if (frame) {
--
cgit v1.2.3
From bbfff93c6455247d9875003cdfd18c09d0c30e0f Mon Sep 17 00:00:00 2001
From: Johannes Schickel
Date: Mon, 29 Dec 2014 14:56:02 +0100
Subject: GUI: Do not overwrite write protected saves in grid based save
dialog.
This fixes overwriting of, for example, autosaves in the grid based save load
dialog when using "New Save".
---
gui/saveload-dialog.cpp | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp
index 339ec95c50..a333c5fe57 100644
--- a/gui/saveload-dialog.cpp
+++ b/gui/saveload-dialog.cpp
@@ -654,16 +654,25 @@ void SaveLoadChooserGrid::open() {
// In case there was a gap found use the slot.
if (lastSlot + 1 < curSlot) {
- _nextFreeSaveSlot = lastSlot + 1;
- break;
+ // Check that the save slot can be used for user saves.
+ SaveStateDescriptor desc = _metaEngine->querySaveMetaInfos(_target.c_str(), lastSlot + 1);
+ if (!desc.getWriteProtectedFlag()) {
+ _nextFreeSaveSlot = lastSlot + 1;
+ break;
+ }
}
lastSlot = curSlot;
}
// Use the next available slot otherwise.
- if (_nextFreeSaveSlot == -1 && lastSlot + 1 < _metaEngine->getMaximumSaveSlot()) {
- _nextFreeSaveSlot = lastSlot + 1;
+ const int maxSlot = _metaEngine->getMaximumSaveSlot();
+ for (int i = lastSlot; _nextFreeSaveSlot == -1 && i < maxSlot; ++i) {
+ // Check that the save slot can be used for user saves.
+ SaveStateDescriptor desc = _metaEngine->querySaveMetaInfos(_target.c_str(), i + 1);
+ if (!desc.getWriteProtectedFlag()) {
+ _nextFreeSaveSlot = i + 1;
+ }
}
}
--
cgit v1.2.3
From 88cca7c97b5cc648503c0401cd4679da27347792 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 29 Dec 2014 21:01:38 +0100
Subject: ACCESS: MM - Fix Sprite Frame loading
---
engines/access/asurface.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp
index 38af7add00..21bf460516 100644
--- a/engines/access/asurface.cpp
+++ b/engines/access/asurface.cpp
@@ -54,6 +54,12 @@ SpriteResource::~SpriteResource() {
SpriteFrame::SpriteFrame(AccessEngine *vm, Common::SeekableReadStream *stream, int frameSize) {
int xSize = stream->readUint16LE();
int ySize = stream->readUint16LE();
+
+ if (vm->getGameID() == GType_MartianMemorandum) {
+ int size = stream->readUint16LE();
+ if (size != frameSize)
+ warning("Unexpected file difference: framesize %d - size %d %d - unknown %d", frameSize, xSize, ySize, unknown);
+ }
create(xSize, ySize);
// Empty surface
--
cgit v1.2.3
From 053fe65b68d22328f63b1693e06ae19fabb49de3 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 29 Dec 2014 21:01:38 +0100
Subject: ACCESS: MM - Fix Sprite Frame loading
---
engines/access/asurface.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp
index 21bf460516..793e6e9718 100644
--- a/engines/access/asurface.cpp
+++ b/engines/access/asurface.cpp
@@ -58,7 +58,7 @@ SpriteFrame::SpriteFrame(AccessEngine *vm, Common::SeekableReadStream *stream, i
if (vm->getGameID() == GType_MartianMemorandum) {
int size = stream->readUint16LE();
if (size != frameSize)
- warning("Unexpected file difference: framesize %d - size %d %d - unknown %d", frameSize, xSize, ySize, unknown);
+ warning("Unexpected file difference: framesize %d - size %d %d - unknown %d", frameSize, xSize, ySize, size);
}
create(xSize, ySize);
--
cgit v1.2.3
From d192d0b60c574ab6928234ea35f72aace396eda4 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 29 Dec 2014 22:51:15 +0100
Subject: ACCESS: MM - Load TEXPAL
---
engines/access/martian/martian_player.cpp | 2 --
engines/access/martian/martian_player.h | 2 +-
engines/access/martian/martian_room.cpp | 3 +--
engines/access/player.cpp | 17 +++++++++++++++++
engines/access/player.h | 2 ++
5 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/engines/access/martian/martian_player.cpp b/engines/access/martian/martian_player.cpp
index 493776e411..f461751438 100644
--- a/engines/access/martian/martian_player.cpp
+++ b/engines/access/martian/martian_player.cpp
@@ -53,8 +53,6 @@ void MartianPlayer::load() {
_upWalkMax = 14;
_downWalkMin = 15;
_downWalkMax = 23;
-
- warning("TODO: Copy texPal into manPal");
}
} // End of namespace Martian
diff --git a/engines/access/martian/martian_player.h b/engines/access/martian/martian_player.h
index 192f2540cc..63a21a1c24 100644
--- a/engines/access/martian/martian_player.h
+++ b/engines/access/martian/martian_player.h
@@ -37,7 +37,7 @@ private:
MartianEngine *_game;
public:
MartianPlayer(AccessEngine *vm);
-
+ Resource *_texPal;
virtual void load();
};
diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp
index 972aada5d6..dfc0dbcd5e 100644
--- a/engines/access/martian/martian_room.cpp
+++ b/engines/access/martian/martian_room.cpp
@@ -43,13 +43,12 @@ void MartianRoom::loadRoom(int roomNumber) {
}
void MartianRoom::reloadRoom() {
- warning("TODO: Load TEXPAL.COL");
// _vm->_currentMan = _roomFlag;
// _vm->_currentManOld = _roomFlag;
// _vm->_manScaleOff = 0;
+ _vm->_player->loadTexPalette();
_vm->_player->loadSprites("TEX.LZ");
- warning("TODO: Load TEXPAL.COL");
loadRoom(_vm->_player->_roomNumber);
diff --git a/engines/access/player.cpp b/engines/access/player.cpp
index 1fe58c6a1c..41c5b47daf 100644
--- a/engines/access/player.cpp
+++ b/engines/access/player.cpp
@@ -146,10 +146,27 @@ void Player::load() {
}
}
+void Player::loadTexPalette() {
+ Resource *_texPal = _vm->_files->loadFile("TEXPAL.COL");
+ int size = _texPal->_size;
+ _manPal1 = new byte[size];
+ memcpy(_manPal1, _texPal->data(), size);
+}
+
void Player::loadSprites(const Common::String &name) {
freeSprites();
Resource *data = _vm->_files->loadFile(name);
+
+#if 0
+ Common::DumpFile *outFile = new Common::DumpFile();
+ Common::String outName = name + ".dump";
+ outFile->open(outName);
+ outFile->write(data->data(), data->_size);
+ outFile->finalize();
+ outFile->close();
+#endif
+
_playerSprites1 = new SpriteResource(_vm, data);
delete data;
}
diff --git a/engines/access/player.h b/engines/access/player.h
index 1b33ae63ec..1e66a72a95 100644
--- a/engines/access/player.h
+++ b/engines/access/player.h
@@ -124,6 +124,8 @@ public:
virtual void load();
+ void loadTexPalette();
+
void loadSprites(const Common::String &name);
void freeSprites();
--
cgit v1.2.3
From 45280d035afe29dc1f8971eac713ea1fdb64bfb5 Mon Sep 17 00:00:00 2001
From: Marisa-Chan
Date: Mon, 29 Dec 2014 15:30:12 +0600
Subject: ZVISION: Fix font error message condition
---
engines/zvision/zvision.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 88cc1e2fea..10e0aaedc4 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -255,7 +255,7 @@ Common::Error ZVision::run() {
_saveManager->loadGame(ConfMan.getInt("save_slot"));
// Before starting, make absolutely sure that the user has copied the needed fonts
- if (!Common::File::exists("arial.ttf") && !Common::File::exists("FreeSans.ttf")) {
+ if (!Common::File::exists("arial.ttf") && !Common::File::exists("FreeSans.ttf") && !_searchManager->hasFile("arial.ttf") && !_searchManager->hasFile("FreeSans.ttf") ) {
GUI::MessageDialog dialog(
"Before playing this game, you'll need to copy the required "
"fonts into ScummVM's extras directory, or into the game directory. "
--
cgit v1.2.3
From 47b90ef3cde832b6314bbcc0321cb074408d944e Mon Sep 17 00:00:00 2001
From: Marisa-Chan
Date: Wed, 24 Dec 2014 09:31:02 +0600
Subject: ZVISION: Search fonts in game directory (e.g. in game/FONTS/)
---
engines/zvision/text/truetype_font.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
index f64c0ab3bc..85d9fa5a29 100644
--- a/engines/zvision/text/truetype_font.cpp
+++ b/engines/zvision/text/truetype_font.cpp
@@ -108,7 +108,7 @@ bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
Common::File file;
- if (!file.open(newFontName) && !file.open(freeFontName))
+ if (!file.open(newFontName) && !file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, newFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
--
cgit v1.2.3
From 0c4e0673c3a7d17aef7c586251c3990104163bc3 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 30 Dec 2014 03:08:39 +0200
Subject: ZVISION: Further cleanup to the AnimationNode class
---
engines/zvision/scripting/sidefx/animation_node.cpp | 20 ++++++--------------
engines/zvision/scripting/sidefx/animation_node.h | 6 ++----
2 files changed, 8 insertions(+), 18 deletions(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index 1657a6e0ec..a0870bf7c2 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -33,14 +33,13 @@
namespace ZVision {
-AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool DisposeAfterUse)
+AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse)
: SideFX(engine, controlKey, SIDEFX_ANIM),
- _DisposeAfterUse(DisposeAfterUse),
+ _disposeAfterUse(disposeAfterUse),
_mask(mask),
_animation(NULL) {
_animation = engine->loadAnimation(fileName);
- _animation->start();
if (frate > 0) {
_frmDelayOverride = (int32)(1000.0 / frate);
@@ -89,12 +88,10 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (it != _playList.end()) {
playnode *nod = &(*it);
- if (nod->_curFrame == -1) {
+ if (!_animation->isPlaying()) {
// The node is just beginning playback
- nod->_curFrame = nod->start;
-
+ _animation->start();
_animation->seekToFrame(nod->start);
- _animation->setEndFrame(nod->stop);
nod->_delay = deltaTimeInMillis; // Force the frame to draw
if (nod->slot)
@@ -111,10 +108,9 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
delete nod->_scaled;
}
_playList.erase(it);
- return _DisposeAfterUse;
+ return _disposeAfterUse;
}
- nod->_curFrame = nod->start;
_animation->seekToFrame(nod->start);
}
@@ -190,13 +186,9 @@ void AnimationNode::addPlayNode(int32 slot, int x, int y, int x2, int y2, int st
nod.loop = loops;
nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1);
nod.start = startFrame;
- nod.stop = endFrame;
-
- if (nod.stop >= (int)_animation->getFrameCount())
- nod.stop = _animation->getFrameCount() - 1;
+ _animation->setEndFrame(CLIP(endFrame, 0,_animation->getFrameCount() - 1));
nod.slot = slot;
- nod._curFrame = -1;
nod._delay = 0;
nod._scaled = NULL;
_playList.push_back(nod);
diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/sidefx/animation_node.h
index 64270ebc79..1dc0dc71b8 100644
--- a/engines/zvision/scripting/sidefx/animation_node.h
+++ b/engines/zvision/scripting/sidefx/animation_node.h
@@ -41,16 +41,14 @@ class ZVision;
class AnimationNode : public SideFX {
public:
- AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool DisposeAfterUse = true);
+ AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse = true);
~AnimationNode();
struct playnode {
Common::Rect pos;
int32 slot;
int32 start;
- int32 stop;
int32 loop;
- int32 _curFrame;
int32 _delay;
Graphics::Surface *_scaled;
};
@@ -61,7 +59,7 @@ private:
PlayNodes _playList;
int32 _mask;
- bool _DisposeAfterUse;
+ bool _disposeAfterUse;
Video::VideoDecoder *_animation;
int32 _frmDelayOverride;
--
cgit v1.2.3
From 7182b4f704a312427dc701ccc8452331ca66faae Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 30 Dec 2014 03:51:15 +0200
Subject: ZVISION: Initialize the starting frame to -1 in RLF animations
---
engines/zvision/video/rlf_decoder.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index 1478822d00..6e2000f93c 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -56,7 +56,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
_height(0),
_frameTime(0),
_frames(0),
- _curFrame(0),
+ _curFrame(-1),
_frameBufferByteSize(0) {
if (!readHeader()) {
--
cgit v1.2.3
From 6c3af3c2e7b8d2852669c141944964c82a11ce1b Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 30 Dec 2014 03:51:31 +0200
Subject: ZVISION: White space
---
engines/zvision/scripting/sidefx/animation_node.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
index a0870bf7c2..07eda692c1 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/sidefx/animation_node.cpp
@@ -186,7 +186,7 @@ void AnimationNode::addPlayNode(int32 slot, int x, int y, int x2, int y2, int st
nod.loop = loops;
nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1);
nod.start = startFrame;
- _animation->setEndFrame(CLIP(endFrame, 0,_animation->getFrameCount() - 1));
+ _animation->setEndFrame(CLIP(endFrame, 0, _animation->getFrameCount() - 1));
nod.slot = slot;
nod._delay = 0;
--
cgit v1.2.3
From f74ba29753de23bad9a07f531fc4c03ea3375594 Mon Sep 17 00:00:00 2001
From: Torbjörn Andersson
Date: Tue, 30 Dec 2014 03:45:14 +0100
Subject: SCUMM: Enable Day of the Tentacle easter egg
Instead of returning to the launcher, a game may now specify a list
of "chained" games and optional save slots. The first game is popped
from the list and started. Quitting still quits the entire ScummVM.
It seemed like the sensible thing to do.
---
base/main.cpp | 50 +++++++++++++++++++++++++++++++++++++++++----
engines/scumm/saveload.cpp | 2 +-
engines/scumm/script_v6.cpp | 6 +++++-
engines/scumm/scumm.cpp | 44 ++++++++++++++++++++++++++++++++++++---
engines/scumm/scumm.h | 2 +-
5 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/base/main.cpp b/base/main.cpp
index b5de7d94d2..b9bd97dbef 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -523,22 +523,64 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
}
#endif
+ // At this point, we usually return to the launcher. However, the
+ // game may have requested that one or more other games be "chained"
+ // to the current one, with optional save slots to start the games
+ // at. At the time of writing, this is used for the Maniac Mansion
+ // easter egg in Day of the Tentacle.
+
+ Common::String chainedGames, nextGame, saveSlot;
+
+ if (ConfMan.hasKey("chained_games", Common::ConfigManager::kTransientDomain)) {
+ chainedGames = ConfMan.get("chained_games", Common::ConfigManager::kTransientDomain);
+ }
+
// Discard any command line options. It's unlikely that the user
// wanted to apply them to *all* games ever launched.
ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
- // Clear the active config domain
- ConfMan.setActiveDomain("");
+ if (!chainedGames.empty()) {
+ if (chainedGames.contains(',')) {
+ for (uint i = 0; i < chainedGames.size(); i++) {
+ if (chainedGames[i] == ',') {
+ chainedGames.erase(0, i + 1);
+ break;
+ }
+ nextGame += chainedGames[i];
+ }
+ ConfMan.set("chained_games", chainedGames, Common::ConfigManager::kTransientDomain);
+ } else {
+ nextGame = chainedGames;
+ chainedGames.clear();
+ ConfMan.removeKey("chained_games", Common::ConfigManager::kTransientDomain);
+ }
+ if (nextGame.contains(':')) {
+ for (int i = nextGame.size() - 1; i >= 0; i--) {
+ if (nextGame[i] == ':') {
+ nextGame.erase(i);
+ break;
+ }
+ saveSlot = nextGame[i] + saveSlot;
+ }
+ ConfMan.setInt("save_slot", atoi(saveSlot.c_str()), Common::ConfigManager::kTransientDomain);
+ }
+ // Start the next game
+ ConfMan.setActiveDomain(nextGame);
+ } else {
+ // Clear the active config domain
+ ConfMan.setActiveDomain("");
+ }
PluginManager::instance().loadAllPlugins(); // only for cached manager
-
} else {
GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game"));
}
// reset the graphics to default
setupGraphics(system);
- launcherDialog();
+ if (0 == ConfMan.getActiveDomain()) {
+ launcherDialog();
+ }
}
PluginManager::instance().unloadAllPlugins();
PluginManager::destroy();
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 0c0f6be73b..e5673c1803 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -149,7 +149,7 @@ void ScummEngine::requestSave(int slot, const Common::String &name) {
void ScummEngine::requestLoad(int slot) {
_saveLoadSlot = slot;
- _saveTemporaryState = false;
+ _saveTemporaryState = (slot == 100);
_saveLoadFlag = 2; // 2 for load
}
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index d2f4133f74..6c81f17f2f 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -2597,7 +2597,11 @@ void ScummEngine_v6::o6_kernelSetFunctions() {
fadeIn(args[1]);
break;
case 8:
- startManiac();
+ if (startManiac()) {
+ // This is so that the surprised exclamation happens
+ // after we return to the game again, not before.
+ o6_breakHere();
+ }
break;
case 9:
killAllScriptsExceptCurrent();
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 6040344c2c..34ae957951 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2597,9 +2597,47 @@ void ScummEngine_v90he::runBootscript() {
}
#endif
-void ScummEngine::startManiac() {
- debug(0, "stub startManiac()");
- displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' directory inside the Tentacle game directory."));
+bool ScummEngine::startManiac() {
+ Common::String currentPath = ConfMan.get("path");
+ Common::String maniacTarget;
+
+ // Look for a game with a game path pointing to a 'Maniac' directory
+ // as a subdirectory to the current game.
+ Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
+ for (; iter != ConfMan.endGameDomains(); ++iter) {
+ Common::ConfigManager::Domain &dom = iter->_value;
+ Common::String path = dom.getVal("path");
+
+ if (path.hasPrefix(currentPath)) {
+ path.erase(0, currentPath.size() + 1);
+ if (path.equalsIgnoreCase("maniac")) {
+ maniacTarget = dom.getVal("gameid");
+ break;
+ }
+ }
+ }
+
+ if (!maniacTarget.empty()) {
+ // Request a temporary save game to be made.
+ _saveLoadFlag = 1;
+ _saveLoadSlot = 100;
+ _saveTemporaryState = true;
+
+ // Set up the chanined games to Maniac Mansion, and then back
+ // to the current game again with that save slot.
+ ConfMan.set("chained_games", maniacTarget + "," + ConfMan.getActiveDomainName() + ":100", Common::ConfigManager::kTransientDomain);
+
+ // Force a return to the launcher. This will start the first
+ // chained game.
+ Common::EventManager *eventMan = g_system->getEventManager();
+ Common::Event event;
+ event.type = Common::EVENT_RTL;
+ eventMan->pushEvent(event);
+ return true;
+ } else {
+ displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But for that to work, the game files for Maniac Mansion have to be in the 'Maniac' directory inside the Tentacle game directory, and the game has to be added to ScummVM."));
+ return false;
+ }
}
#pragma mark -
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 967909e505..30b4d61880 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -654,7 +654,7 @@ protected:
int getScriptSlot();
void startScene(int room, Actor *a, int b);
- void startManiac();
+ bool startManiac();
public:
void runScript(int script, bool freezeResistant, bool recursive, int *lvarptr, int cycle = 0);
--
cgit v1.2.3
From 68d3ebd57b0313e517032681a119b47956803e71 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 01:10:36 -0600
Subject: ZVISION: Rename some scripting classes to better represent what the
classes are
Also, rename the graphics 'Effect' class in order to avoid naming clashes (and/or coder
confusion) with the newly named ScriptingEffect class.
Lastly, add some documentation for the classes for further clarity.
---
engines/zvision/graphics/effect.h | 83 -------
engines/zvision/graphics/effects/fog.cpp | 2 +-
engines/zvision/graphics/effects/fog.h | 4 +-
engines/zvision/graphics/effects/light.cpp | 2 +-
engines/zvision/graphics/effects/light.h | 4 +-
engines/zvision/graphics/effects/wave.cpp | 2 +-
engines/zvision/graphics/effects/wave.h | 4 +-
engines/zvision/graphics/graphics_effect.h | 83 +++++++
engines/zvision/graphics/render_manager.cpp | 2 +-
engines/zvision/graphics/render_manager.h | 6 +-
engines/zvision/module.mk | 14 +-
engines/zvision/scripting/actions.cpp | 66 +++---
engines/zvision/scripting/control.h | 5 +
.../zvision/scripting/effects/animation_effect.cpp | 213 ++++++++++++++++++
.../zvision/scripting/effects/animation_effect.h | 77 +++++++
.../zvision/scripting/effects/distort_effect.cpp | 104 +++++++++
engines/zvision/scripting/effects/distort_effect.h | 63 ++++++
engines/zvision/scripting/effects/music_effect.cpp | 248 +++++++++++++++++++++
engines/zvision/scripting/effects/music_effect.h | 135 +++++++++++
.../zvision/scripting/effects/region_effect.cpp | 56 +++++
engines/zvision/scripting/effects/region_effect.h | 57 +++++
.../zvision/scripting/effects/syncsound_effect.cpp | 85 +++++++
.../zvision/scripting/effects/syncsound_effect.h | 56 +++++
engines/zvision/scripting/effects/timer_effect.cpp | 81 +++++++
engines/zvision/scripting/effects/timer_effect.h | 59 +++++
.../zvision/scripting/effects/ttytext_effect.cpp | 174 +++++++++++++++
engines/zvision/scripting/effects/ttytext_effect.h | 73 ++++++
engines/zvision/scripting/script_manager.cpp | 8 +-
engines/zvision/scripting/script_manager.h | 10 +-
engines/zvision/scripting/scripting_effect.h | 124 +++++++++++
engines/zvision/scripting/sidefx.h | 114 ----------
.../zvision/scripting/sidefx/animation_node.cpp | 213 ------------------
engines/zvision/scripting/sidefx/animation_node.h | 77 -------
engines/zvision/scripting/sidefx/distort_node.cpp | 104 ---------
engines/zvision/scripting/sidefx/distort_node.h | 63 ------
engines/zvision/scripting/sidefx/music_node.cpp | 248 ---------------------
engines/zvision/scripting/sidefx/music_node.h | 135 -----------
engines/zvision/scripting/sidefx/region_node.cpp | 56 -----
engines/zvision/scripting/sidefx/region_node.h | 57 -----
.../zvision/scripting/sidefx/syncsound_node.cpp | 85 -------
engines/zvision/scripting/sidefx/syncsound_node.h | 56 -----
engines/zvision/scripting/sidefx/timer_node.cpp | 81 -------
engines/zvision/scripting/sidefx/timer_node.h | 59 -----
engines/zvision/scripting/sidefx/ttytext_node.cpp | 174 ---------------
engines/zvision/scripting/sidefx/ttytext_node.h | 73 ------
45 files changed, 1755 insertions(+), 1740 deletions(-)
delete mode 100644 engines/zvision/graphics/effect.h
create mode 100644 engines/zvision/graphics/graphics_effect.h
create mode 100644 engines/zvision/scripting/effects/animation_effect.cpp
create mode 100644 engines/zvision/scripting/effects/animation_effect.h
create mode 100644 engines/zvision/scripting/effects/distort_effect.cpp
create mode 100644 engines/zvision/scripting/effects/distort_effect.h
create mode 100644 engines/zvision/scripting/effects/music_effect.cpp
create mode 100644 engines/zvision/scripting/effects/music_effect.h
create mode 100644 engines/zvision/scripting/effects/region_effect.cpp
create mode 100644 engines/zvision/scripting/effects/region_effect.h
create mode 100644 engines/zvision/scripting/effects/syncsound_effect.cpp
create mode 100644 engines/zvision/scripting/effects/syncsound_effect.h
create mode 100644 engines/zvision/scripting/effects/timer_effect.cpp
create mode 100644 engines/zvision/scripting/effects/timer_effect.h
create mode 100644 engines/zvision/scripting/effects/ttytext_effect.cpp
create mode 100644 engines/zvision/scripting/effects/ttytext_effect.h
create mode 100644 engines/zvision/scripting/scripting_effect.h
delete mode 100644 engines/zvision/scripting/sidefx.h
delete mode 100644 engines/zvision/scripting/sidefx/animation_node.cpp
delete mode 100644 engines/zvision/scripting/sidefx/animation_node.h
delete mode 100644 engines/zvision/scripting/sidefx/distort_node.cpp
delete mode 100644 engines/zvision/scripting/sidefx/distort_node.h
delete mode 100644 engines/zvision/scripting/sidefx/music_node.cpp
delete mode 100644 engines/zvision/scripting/sidefx/music_node.h
delete mode 100644 engines/zvision/scripting/sidefx/region_node.cpp
delete mode 100644 engines/zvision/scripting/sidefx/region_node.h
delete mode 100644 engines/zvision/scripting/sidefx/syncsound_node.cpp
delete mode 100644 engines/zvision/scripting/sidefx/syncsound_node.h
delete mode 100644 engines/zvision/scripting/sidefx/timer_node.cpp
delete mode 100644 engines/zvision/scripting/sidefx/timer_node.h
delete mode 100644 engines/zvision/scripting/sidefx/ttytext_node.cpp
delete mode 100644 engines/zvision/scripting/sidefx/ttytext_node.h
diff --git a/engines/zvision/graphics/effect.h b/engines/zvision/graphics/effect.h
deleted file mode 100644
index 234cd8209d..0000000000
--- a/engines/zvision/graphics/effect.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef EFFECT_H_INCLUDED
-#define EFFECT_H_INCLUDED
-
-#include "common/rect.h"
-#include "common/list.h"
-#include "graphics/surface.h"
-
-#include "zvision/zvision.h"
-
-namespace ZVision {
-
-class ZVision;
-
-class Effect {
-public:
-
- Effect(ZVision *engine, uint32 key, Common::Rect region, bool ported) : _engine(engine), _key(key), _region(region), _ported(ported) {
- _surface.create(_region.width(), _region.height(), _engine->_resourcePixelFormat);
- }
- virtual ~Effect() {}
-
- uint32 getKey() {
- return _key;
- }
-
- Common::Rect getRegion() {
- return _region;
- }
-
- bool isPort() {
- return _ported;
- }
-
- virtual const Graphics::Surface *draw(const Graphics::Surface &srcSubRect) {
- return &_surface;
- }
-
- virtual void update() {}
-
-protected:
- ZVision *_engine;
- uint32 _key;
- Common::Rect _region;
- bool _ported;
- Graphics::Surface _surface;
-
-// Static member functions
-public:
-
-};
-
-struct EffectMapUnit {
- uint32 count;
- bool inEffect;
-};
-
-typedef Common::List EffectMap;
-
-} // End of namespace ZVision
-
-#endif // EFFECT_H_INCLUDED
diff --git a/engines/zvision/graphics/effects/fog.cpp b/engines/zvision/graphics/effects/fog.cpp
index c28bdde330..32a01915d3 100644
--- a/engines/zvision/graphics/effects/fog.cpp
+++ b/engines/zvision/graphics/effects/fog.cpp
@@ -31,7 +31,7 @@
namespace ZVision {
FogFx::FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, const Common::String &clouds):
- Effect(engine, key, region, ported) {
+ GraphicsEffect(engine, key, region, ported) {
_map = Map;
diff --git a/engines/zvision/graphics/effects/fog.h b/engines/zvision/graphics/effects/fog.h
index fe88707bbe..498347609e 100644
--- a/engines/zvision/graphics/effects/fog.h
+++ b/engines/zvision/graphics/effects/fog.h
@@ -23,14 +23,14 @@
#ifndef ZVISION_FOG_H
#define ZVISION_FOG_H
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
namespace ZVision {
class ZVision;
// Used by Zork: Nemesis for the mixing chamber gas effect in the gas puzzle (location tt5e, when the blinds are down)
-class FogFx : public Effect {
+class FogFx : public GraphicsEffect {
public:
FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, const Common::String &clouds);
diff --git a/engines/zvision/graphics/effects/light.cpp b/engines/zvision/graphics/effects/light.cpp
index bf6513292f..39341687f8 100644
--- a/engines/zvision/graphics/effects/light.cpp
+++ b/engines/zvision/graphics/effects/light.cpp
@@ -30,7 +30,7 @@
namespace ZVision {
LightFx::LightFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, int8 delta, int8 minD, int8 maxD):
- Effect(engine, key, region, ported) {
+ GraphicsEffect(engine, key, region, ported) {
_map = Map;
_delta = delta;
_up = true;
diff --git a/engines/zvision/graphics/effects/light.h b/engines/zvision/graphics/effects/light.h
index ae87d66cb3..cd73a585ec 100644
--- a/engines/zvision/graphics/effects/light.h
+++ b/engines/zvision/graphics/effects/light.h
@@ -23,13 +23,13 @@
#ifndef LIGHTFX_H_INCLUDED
#define LIGHTFX_H_INCLUDED
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
namespace ZVision {
class ZVision;
-class LightFx : public Effect {
+class LightFx : public GraphicsEffect {
public:
LightFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, int8 delta, int8 minD = -127, int8 maxD = 127);
diff --git a/engines/zvision/graphics/effects/wave.cpp b/engines/zvision/graphics/effects/wave.cpp
index 1b3aa040e8..cec631611b 100644
--- a/engines/zvision/graphics/effects/wave.cpp
+++ b/engines/zvision/graphics/effects/wave.cpp
@@ -30,7 +30,7 @@
namespace ZVision {
WaveFx::WaveFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, int16 frames, int16 centerX, int16 centerY, float ampl, float waveln, float spd):
- Effect(engine, key, region, ported) {
+ GraphicsEffect(engine, key, region, ported) {
_frame = 0;
_frameCount = frames;
diff --git a/engines/zvision/graphics/effects/wave.h b/engines/zvision/graphics/effects/wave.h
index 2e813ed5b6..8e912372d7 100644
--- a/engines/zvision/graphics/effects/wave.h
+++ b/engines/zvision/graphics/effects/wave.h
@@ -24,13 +24,13 @@
#define WAVEFX_H_INCLUDED
#include "common/array.h"
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
namespace ZVision {
class ZVision;
-class WaveFx : public Effect {
+class WaveFx : public GraphicsEffect {
public:
WaveFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, int16 frames, int16 centerX, int16 centerY, float ampl, float waveln, float spd);
diff --git a/engines/zvision/graphics/graphics_effect.h b/engines/zvision/graphics/graphics_effect.h
new file mode 100644
index 0000000000..bfa266b11d
--- /dev/null
+++ b/engines/zvision/graphics/graphics_effect.h
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 GRAPHICS_EFFECT_H_INCLUDED
+#define GRAPHICS_EFFECT_H_INCLUDED
+
+#include "common/rect.h"
+#include "common/list.h"
+#include "graphics/surface.h"
+
+#include "zvision/zvision.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class GraphicsEffect {
+public:
+
+ GraphicsEffect(ZVision *engine, uint32 key, Common::Rect region, bool ported) : _engine(engine), _key(key), _region(region), _ported(ported) {
+ _surface.create(_region.width(), _region.height(), _engine->_resourcePixelFormat);
+ }
+ virtual ~GraphicsEffect() {}
+
+ uint32 getKey() {
+ return _key;
+ }
+
+ Common::Rect getRegion() {
+ return _region;
+ }
+
+ bool isPort() {
+ return _ported;
+ }
+
+ virtual const Graphics::Surface *draw(const Graphics::Surface &srcSubRect) {
+ return &_surface;
+ }
+
+ virtual void update() {}
+
+protected:
+ ZVision *_engine;
+ uint32 _key;
+ Common::Rect _region;
+ bool _ported;
+ Graphics::Surface _surface;
+
+// Static member functions
+public:
+
+};
+
+struct EffectMapUnit {
+ uint32 count;
+ bool inEffect;
+};
+
+typedef Common::List EffectMap;
+
+} // End of namespace ZVision
+
+#endif // GRAPHICS_EFFECT_H_INCLUDED
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 1b80b379bf..a1cc8ac53c 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -772,7 +772,7 @@ Common::Point RenderManager::getBkgSize() {
return Common::Point(_backgroundWidth, _backgroundHeight);
}
-void RenderManager::addEffect(Effect *_effect) {
+void RenderManager::addEffect(GraphicsEffect *_effect) {
_effects.push_back(_effect);
}
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index d9a6c88896..9002d66b47 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -31,7 +31,7 @@
#include "graphics/surface.h"
-#include "effect.h"
+#include "graphics_effect.h"
class OSystem;
@@ -61,7 +61,7 @@ private:
};
typedef Common::HashMap SubtitleMap;
- typedef Common::List EffectsList;
+ typedef Common::List EffectsList;
private:
ZVision *_engine;
@@ -302,7 +302,7 @@ public:
void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed);
// Add visual effect to effects list
- void addEffect(Effect *_effect);
+ void addEffect(GraphicsEffect *_effect);
// Delete effect(s) by ID (ID equal to slot of action:region that create this effect)
void deleteEffect(uint32 ID);
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 8edd67b352..93fba2879d 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -32,13 +32,13 @@ MODULE_OBJS := \
scripting/menu.o \
scripting/scr_file_handling.o \
scripting/script_manager.o \
- scripting/sidefx/animation_node.o \
- scripting/sidefx/distort_node.o \
- scripting/sidefx/music_node.o \
- scripting/sidefx/region_node.o \
- scripting/sidefx/syncsound_node.o \
- scripting/sidefx/timer_node.o \
- scripting/sidefx/ttytext_node.o \
+ scripting/effects/animation_effect.o \
+ scripting/effects/distort_effect.o \
+ scripting/effects/music_effect.o \
+ scripting/effects/region_effect.o \
+ scripting/effects/syncsound_effect.o \
+ scripting/effects/timer_effect.o \
+ scripting/effects/ttytext_effect.o \
sound/midi.o \
sound/zork_raw.o \
text/string_manager.o \
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index a91476760d..a61fa26223 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -31,16 +31,16 @@
#include "zvision/video/zork_avi_decoder.h"
#include "zvision/file/save_manager.h"
#include "zvision/scripting/menu.h"
-#include "zvision/scripting/sidefx/timer_node.h"
-#include "zvision/scripting/sidefx/music_node.h"
-#include "zvision/scripting/sidefx/syncsound_node.h"
-#include "zvision/scripting/sidefx/animation_node.h"
-#include "zvision/scripting/sidefx/distort_node.h"
-#include "zvision/scripting/sidefx/ttytext_node.h"
-#include "zvision/scripting/sidefx/region_node.h"
+#include "zvision/scripting/effects/timer_effect.h"
+#include "zvision/scripting/effects/music_effect.h"
+#include "zvision/scripting/effects/syncsound_effect.h"
+#include "zvision/scripting/effects/animation_effect.h"
+#include "zvision/scripting/effects/distort_effect.h"
+#include "zvision/scripting/effects/ttytext_effect.h"
+#include "zvision/scripting/effects/region_effect.h"
#include "zvision/scripting/controls/titler_control.h"
#include "zvision/graphics/render_table.h"
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
#include "zvision/graphics/effects/fog.h"
#include "zvision/graphics/effects/light.h"
#include "zvision/graphics/effects/wave.h"
@@ -106,8 +106,8 @@ ActionAttenuate::ActionAttenuate(ZVision *engine, int32 slotkey, const Common::S
}
bool ActionAttenuate::execute() {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_key);
- if (fx && fx->getType() == SideFX::SIDEFX_AUDIO) {
+ ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_key);
+ if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) {
MusicNode *mus = (MusicNode *)fx;
mus->setVolume(255 - (abs(_attenuation) >> 7));
}
@@ -157,8 +157,8 @@ ActionCrossfade::ActionCrossfade(ZVision *engine, int32 slotkey, const Common::S
bool ActionCrossfade::execute() {
if (_keyOne) {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_keyOne);
- if (fx && fx->getType() == SideFX::SIDEFX_AUDIO) {
+ ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_keyOne);
+ if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) {
MusicNode *mus = (MusicNode *)fx;
if (_oneStartVolume >= 0)
mus->setVolume((_oneStartVolume * 255) / 100);
@@ -168,8 +168,8 @@ bool ActionCrossfade::execute() {
}
if (_keyTwo) {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_keyTwo);
- if (fx && fx->getType() == SideFX::SIDEFX_AUDIO) {
+ ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_keyTwo);
+ if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) {
MusicNode *mus = (MusicNode *)fx;
if (_twoStartVolume >= 0)
mus->setVolume((_twoStartVolume * 255) / 100);
@@ -401,28 +401,28 @@ ActionKill::ActionKill(ZVision *engine, int32 slotkey, const Common::String &lin
sscanf(line.c_str(), "%24s", keytype);
if (keytype[0] == '"') {
if (!scumm_stricmp(keytype, "\"ANIM\""))
- _type = SideFX::SIDEFX_ANIM;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_ANIM;
else if (!scumm_stricmp(keytype, "\"AUDIO\""))
- _type = SideFX::SIDEFX_AUDIO;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_AUDIO;
else if (!scumm_stricmp(keytype, "\"DISTORT\""))
- _type = SideFX::SIDEFX_DISTORT;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_DISTORT;
else if (!scumm_stricmp(keytype, "\"PANTRACK\""))
- _type = SideFX::SIDEFX_PANTRACK;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_PANTRACK;
else if (!scumm_stricmp(keytype, "\"REGION\""))
- _type = SideFX::SIDEFX_REGION;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_REGION;
else if (!scumm_stricmp(keytype, "\"TIMER\""))
- _type = SideFX::SIDEFX_TIMER;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_TIMER;
else if (!scumm_stricmp(keytype, "\"TTYTEXT\""))
- _type = SideFX::SIDEFX_TTYTXT;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_TTYTXT;
else if (!scumm_stricmp(keytype, "\"ALL\""))
- _type = SideFX::SIDEFX_ALL;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_ALL;
} else
_key = atoi(keytype);
}
bool ActionKill::execute() {
if (_type)
- _engine->getScriptManager()->killSideFxType((SideFX::SideFXType)_type);
+ _engine->getScriptManager()->killSideFxType((ScriptingEffect::ScriptingEffectType)_type);
else
_engine->getScriptManager()->killSideFx(_key);
return true;
@@ -580,10 +580,10 @@ ActionPreloadAnimation::~ActionPreloadAnimation() {
}
bool ActionPreloadAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_slotKey);
+ AnimationEffect *nod = (AnimationEffect *)_engine->getScriptManager()->getSideFX(_slotKey);
if (!nod) {
- nod = new AnimationNode(_engine, _slotKey, _fileName, _mask, _framerate, false);
+ nod = new AnimationEffect(_engine, _slotKey, _fileName, _mask, _framerate, false);
_engine->getScriptManager()->addSideFX(nod);
} else
nod->stop();
@@ -603,9 +603,9 @@ ActionUnloadAnimation::ActionUnloadAnimation(ZVision *engine, int32 slotkey, con
}
bool ActionUnloadAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_key);
+ AnimationEffect *nod = (AnimationEffect *)_engine->getScriptManager()->getSideFX(_key);
- if (nod && nod->getType() == SideFX::SIDEFX_ANIM)
+ if (nod && nod->getType() == ScriptingEffect::SCRIPTING_EFFECT_ANIM)
_engine->getScriptManager()->deleteSideFx(_key);
return true;
@@ -648,10 +648,10 @@ ActionPlayAnimation::~ActionPlayAnimation() {
}
bool ActionPlayAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_slotKey);
+ AnimationEffect *nod = (AnimationEffect *)_engine->getScriptManager()->getSideFX(_slotKey);
if (!nod) {
- nod = new AnimationNode(_engine, _slotKey, _fileName, _mask, _framerate);
+ nod = new AnimationEffect(_engine, _slotKey, _fileName, _mask, _framerate);
_engine->getScriptManager()->addSideFX(nod);
} else
nod->stop();
@@ -683,7 +683,7 @@ ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(ZVision *engine, int32 sl
}
bool ActionPlayPreloadAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_controlKey);
+ AnimationEffect *nod = (AnimationEffect *)_engine->getScriptManager()->getSideFX(_controlKey);
if (nod)
nod->addPlayNode(_slotKey, _x1, _y1, _x2, _y2, _startFrame, _endFrame, _loopCount);
@@ -731,7 +731,7 @@ bool ActionRegion::execute() {
if (_engine->getScriptManager()->getSideFX(_slotKey))
return true;
- Effect *effect = NULL;
+ GraphicsEffect *effect = NULL;
switch (_type) {
case 0: {
uint16 centerX, centerY, frames;
@@ -982,11 +982,11 @@ ActionSyncSound::ActionSyncSound(ZVision *engine, int32 slotkey, const Common::S
}
bool ActionSyncSound::execute() {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_syncto);
+ ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_syncto);
if (!fx)
return true;
- if (!(fx->getType() & SideFX::SIDEFX_ANIM))
+ if (!(fx->getType() & ScriptingEffect::SCRIPTING_EFFECT_ANIM))
return true;
_engine->getScriptManager()->addSideFX(new SyncSoundNode(_engine, _slotKey, _fileName, _syncto));
diff --git a/engines/zvision/scripting/control.h b/engines/zvision/scripting/control.h
index 803d0cf1ce..108b83fd00 100644
--- a/engines/zvision/scripting/control.h
+++ b/engines/zvision/scripting/control.h
@@ -36,6 +36,11 @@ namespace ZVision {
class ZVision;
+/**
+ * The base class for all Controls.
+ *
+ * Controls are the things that the user interacts with. Ex: A lever on the door
+ */
class Control {
public:
diff --git a/engines/zvision/scripting/effects/animation_effect.cpp b/engines/zvision/scripting/effects/animation_effect.cpp
new file mode 100644
index 0000000000..c3cbc25406
--- /dev/null
+++ b/engines/zvision/scripting/effects/animation_effect.cpp
@@ -0,0 +1,213 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/animation_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+
+#include "graphics/surface.h"
+#include "video/video_decoder.h"
+
+namespace ZVision {
+
+AnimationEffect::AnimationEffect(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse)
+ : ScriptingEffect(engine, controlKey, SCRIPTING_EFFECT_ANIM),
+ _disposeAfterUse(disposeAfterUse),
+ _mask(mask),
+ _animation(NULL) {
+
+ _animation = engine->loadAnimation(fileName);
+
+ if (frate > 0) {
+ _frmDelayOverride = (int32)(1000.0 / frate);
+
+ // WORKAROUND: We do not allow the engine to delay more than 66 msec
+ // per frame (15fps max)
+ if (_frmDelayOverride > 66)
+ _frmDelayOverride = 66;
+ } else {
+ _frmDelayOverride = 0;
+ }
+}
+
+AnimationEffect::~AnimationEffect() {
+ if (_animation)
+ delete _animation;
+
+ _engine->getScriptManager()->setStateValue(_key, 2);
+
+ PlayNodes::iterator it = _playList.begin();
+ if (it != _playList.end()) {
+ _engine->getScriptManager()->setStateValue((*it).slot, 2);
+
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
+ delete(*it)._scaled;
+ }
+ }
+
+ _playList.clear();
+}
+
+bool AnimationEffect::process(uint32 deltaTimeInMillis) {
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ RenderManager *renderManager = _engine->getRenderManager();
+ RenderTable::RenderState renderState = renderManager->getRenderTable()->getRenderState();
+ bool isPanorama = (renderState == RenderTable::PANORAMA);
+ int16 velocity = _engine->getMouseVelocity() + _engine->getKeyboardVelocity();
+
+ // Do not update animation nodes in panoramic mode while turning, if the user
+ // has set this option
+ if (scriptManager->getStateValue(StateKey_NoTurnAnim) == 1 && isPanorama && velocity)
+ return false;
+
+ PlayNodes::iterator it = _playList.begin();
+ if (it != _playList.end()) {
+ playnode *nod = &(*it);
+
+ if (!_animation->isPlaying()) {
+ // The node is just beginning playback
+ _animation->start();
+ _animation->seekToFrame(nod->start);
+
+ nod->_delay = deltaTimeInMillis; // Force the frame to draw
+ if (nod->slot)
+ scriptManager->setStateValue(nod->slot, 1);
+ } else if (_animation->endOfVideo()) {
+ // The node has reached the end; check if we need to loop
+ nod->loop--;
+
+ if (nod->loop == 0) {
+ if (nod->slot >= 0)
+ scriptManager->setStateValue(nod->slot, 2);
+ if (nod->_scaled) {
+ nod->_scaled->free();
+ delete nod->_scaled;
+ }
+ _playList.erase(it);
+ return _disposeAfterUse;
+ }
+
+ _animation->seekToFrame(nod->start);
+ }
+
+ // Check if we need to draw a frame
+ bool needsUpdate = false;
+ if (_frmDelayOverride == 0) {
+ // If not overridden, use the VideoDecoder's check
+ needsUpdate = _animation->needsUpdate();
+ } else {
+ // Otherwise, implement our own timing
+ nod->_delay -= deltaTimeInMillis;
+
+ if (nod->_delay <= 0) {
+ nod->_delay += _frmDelayOverride;
+ needsUpdate = true;
+ }
+ }
+
+ if (needsUpdate) {
+ const Graphics::Surface *frame = _animation->decodeNextFrame();
+
+ if (frame) {
+ uint32 dstw;
+ uint32 dsth;
+ if (isPanorama) {
+ dstw = nod->pos.height();
+ dsth = nod->pos.width();
+ } else {
+ dstw = nod->pos.width();
+ dsth = nod->pos.height();
+ }
+
+ // We only scale down the animation to fit its frame, not up, otherwise we
+ // end up with distorted animations - e.g. the armor visor in location cz1e
+ // in Nemesis (one of the armors inside Irondune), or the planet in location
+ // aa10 in Nemesis (Juperon, outside the asylum). We do allow scaling up only
+ // when a simple 2x filter is requested (e.g. the alchemists and cup sequence
+ // in Nemesis)
+ if (frame->w > dstw || frame->h > dsth || (frame->w == dstw / 2 && frame->h == dsth / 2)) {
+ if (nod->_scaled)
+ if (nod->_scaled->w != dstw || nod->_scaled->h != dsth) {
+ nod->_scaled->free();
+ delete nod->_scaled;
+ nod->_scaled = NULL;
+ }
+
+ if (!nod->_scaled) {
+ nod->_scaled = new Graphics::Surface;
+ nod->_scaled->create(dstw, dsth, frame->format);
+ }
+
+ renderManager->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
+ frame = nod->_scaled;
+ }
+
+ if (isPanorama) {
+ Graphics::Surface *transposed = RenderManager::tranposeSurface(frame);
+ renderManager->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
+ transposed->free();
+ delete transposed;
+ } else {
+ renderManager->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+void AnimationEffect::addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops) {
+ playnode nod;
+ nod.loop = loops;
+ nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1);
+ nod.start = startFrame;
+ _animation->setEndFrame(CLIP(endFrame, 0, _animation->getFrameCount() - 1));
+
+ nod.slot = slot;
+ nod._delay = 0;
+ nod._scaled = NULL;
+ _playList.push_back(nod);
+}
+
+bool AnimationEffect::stop() {
+ PlayNodes::iterator it = _playList.begin();
+ if (it != _playList.end()) {
+ _engine->getScriptManager()->setStateValue((*it).slot, 2);
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
+ delete(*it)._scaled;
+ }
+ }
+
+ _playList.clear();
+
+ // We don't need to delete, it's may be reused
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/animation_effect.h b/engines/zvision/scripting/effects/animation_effect.h
new file mode 100644
index 0000000000..a564b83ff3
--- /dev/null
+++ b/engines/zvision/scripting/effects/animation_effect.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_ANIMATION_NODE_H
+#define ZVISION_ANIMATION_NODE_H
+
+#include "zvision/scripting/scripting_effect.h"
+#include "common/rect.h"
+#include "common/list.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Video {
+ class VideoDecoder;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+class AnimationEffect : public ScriptingEffect {
+public:
+ AnimationEffect(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse = true);
+ ~AnimationEffect();
+
+ struct playnode {
+ Common::Rect pos;
+ int32 slot;
+ int32 start;
+ int32 loop;
+ int32 _delay;
+ Graphics::Surface *_scaled;
+ };
+
+private:
+ typedef Common::List PlayNodes;
+
+ PlayNodes _playList;
+
+ int32 _mask;
+ bool _disposeAfterUse;
+
+ Video::VideoDecoder *_animation;
+ int32 _frmDelayOverride;
+
+public:
+ bool process(uint32 deltaTimeInMillis);
+
+ void addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops = 1);
+
+ bool stop();
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/distort_effect.cpp b/engines/zvision/scripting/effects/distort_effect.cpp
new file mode 100644
index 0000000000..78c4a1b9a8
--- /dev/null
+++ b/engines/zvision/scripting/effects/distort_effect.cpp
@@ -0,0 +1,104 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/distort_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/graphics/render_table.h"
+
+#include "common/stream.h"
+
+namespace ZVision {
+
+DistortNode::DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_DISTORT) {
+
+ _angle = _engine->getRenderManager()->getRenderTable()->getAngle();
+ _linScale = _engine->getRenderManager()->getRenderTable()->getLinscale();
+
+ _speed = speed;
+ _incr = true;
+ _startAngle = startAngle;
+ _endAngle = endAngle;
+ _startLineScale = startLineScale;
+ _endLineScale = endLineScale;
+
+ _curFrame = 1.0;
+
+ _diffAngle = endAngle - startAngle;
+ _diffLinScale = endLineScale - startLineScale;
+
+ _frmSpeed = (float)speed / 15.0;
+ _frames = ceil((5.0 - _frmSpeed * 2.0) / _frmSpeed);
+ if (_frames <= 0)
+ _frames = 1;
+
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+DistortNode::~DistortNode() {
+ setParams(_angle, _linScale);
+}
+
+bool DistortNode::process(uint32 deltaTimeInMillis) {
+ float updTime = deltaTimeInMillis / (1000.0 / 60.0);
+
+ if (_incr)
+ _curFrame += updTime;
+ else
+ _curFrame -= updTime;
+
+ if (_curFrame < 1.0) {
+ _curFrame = 1.0;
+ _incr = true;
+ } else if (_curFrame > _frames) {
+ _curFrame = _frames;
+ _incr = false;
+ }
+
+ float diff = (1.0 / (5.0 - (_curFrame * _frmSpeed))) / (5.0 - _frmSpeed);
+ setParams(_startAngle + diff * _diffAngle, _startLineScale + diff * _diffLinScale);
+
+ return false;
+}
+
+void DistortNode::setParams(float angl, float linScale) {
+ RenderTable *table = _engine->getRenderManager()->getRenderTable();
+ if (table->getRenderState() == RenderTable::PANORAMA) {
+ table->setPanoramaFoV(angl);
+ table->setPanoramaScale(linScale);
+ table->generateRenderTable();
+ _engine->getRenderManager()->markDirty();
+ } else if (table->getRenderState() == RenderTable::TILT) {
+ table->setTiltFoV(angl);
+ table->setTiltScale(linScale);
+ table->generateRenderTable();
+ _engine->getRenderManager()->markDirty();
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/distort_effect.h b/engines/zvision/scripting/effects/distort_effect.h
new file mode 100644
index 0000000000..c64f10e6ff
--- /dev/null
+++ b/engines/zvision/scripting/effects/distort_effect.h
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_DISTORT_NODE_H
+#define ZVISION_DISTORT_NODE_H
+
+#include "zvision/scripting/scripting_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class DistortNode : public ScriptingEffect {
+public:
+ DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale);
+ ~DistortNode();
+
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ int16 _speed;
+ float _startAngle;
+ float _endAngle;
+ float _startLineScale;
+ float _endLineScale;
+
+ float _frmSpeed;
+ float _diffAngle;
+ float _diffLinScale;
+ bool _incr;
+ int16 _frames;
+
+ float _curFrame;
+
+ float _angle;
+ float _linScale;
+
+private:
+ void setParams(float angl, float linScale);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/music_effect.cpp b/engines/zvision/scripting/effects/music_effect.cpp
new file mode 100644
index 0000000000..102f330305
--- /dev/null
+++ b/engines/zvision/scripting/effects/music_effect.cpp
@@ -0,0 +1,248 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/music_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/sound/midi.h"
+#include "zvision/sound/zork_raw.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "audio/decoders/wave.h"
+
+namespace ZVision {
+
+MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, int8 volume)
+ : MusicNodeBASE(engine, key, SCRIPTING_EFFECT_AUDIO) {
+ _loop = loop;
+ _volume = volume;
+ _crossfade = false;
+ _crossfadeTarget = 0;
+ _crossfadeTime = 0;
+ _attenuate = 0;
+ _pantrack = false;
+ _pantrackPosition = 0;
+ _sub = NULL;
+ _stereo = false;
+ _loaded = false;
+
+ Audio::RewindableAudioStream *audioStream = NULL;
+
+ if (filename.contains(".wav")) {
+ Common::File *file = new Common::File();
+ if (_engine->getSearchManager()->openFile(*file, filename)) {
+ audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
+ }
+ } else {
+ audioStream = makeRawZorkStream(filename, _engine);
+ }
+
+ if (audioStream) {
+ _stereo = audioStream->isStereo();
+
+ if (_loop) {
+ Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, _volume);
+ } else {
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, _volume);
+ }
+
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
+
+ // Change filename.raw into filename.sub
+ Common::String subname = filename;
+ subname.setChar('s', subname.size() - 3);
+ subname.setChar('u', subname.size() - 2);
+ subname.setChar('b', subname.size() - 1);
+
+ if (_engine->getSearchManager()->hasFile(subname))
+ _sub = new Subtitle(_engine, subname);
+
+ _loaded = true;
+ }
+}
+
+MusicNode::~MusicNode() {
+ if (_loaded)
+ _engine->_mixer->stopHandle(_handle);
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ if (_sub)
+ delete _sub;
+ debug(1, "MusicNode: %d destroyed\n", _key);
+}
+
+void MusicNode::setPanTrack(int16 pos) {
+ if (!_stereo) {
+ _pantrack = true;
+ _pantrackPosition = pos;
+ setVolume(_volume);
+ }
+}
+
+void MusicNode::unsetPanTrack() {
+ _pantrack = false;
+ setVolume(_volume);
+}
+
+void MusicNode::setFade(int32 time, uint8 target) {
+ _crossfadeTarget = target;
+ _crossfadeTime = time;
+ _crossfade = true;
+}
+
+bool MusicNode::process(uint32 deltaTimeInMillis) {
+ if (!_loaded || ! _engine->_mixer->isSoundHandleActive(_handle))
+ return stop();
+ else {
+ uint8 _newvol = _volume;
+
+ if (_crossfade) {
+ if (_crossfadeTime > 0) {
+ if ((int32)deltaTimeInMillis > _crossfadeTime)
+ deltaTimeInMillis = _crossfadeTime;
+ _newvol += floor(((float)(_crossfadeTarget - _newvol) / (float)_crossfadeTime)) * (float)deltaTimeInMillis;
+ _crossfadeTime -= deltaTimeInMillis;
+ } else {
+ _crossfade = false;
+ _newvol = _crossfadeTarget;
+ }
+ }
+
+ if (_pantrack || _volume != _newvol)
+ setVolume(_newvol);
+
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
+ _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
+ }
+ return false;
+}
+
+void MusicNode::setVolume(uint8 newVolume) {
+ if (!_loaded)
+ return;
+ if (_pantrack) {
+ int curX = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
+ curX -= _pantrackPosition;
+ int32 _width = _engine->getRenderManager()->getBkgSize().x;
+ if (curX < (-_width) / 2)
+ curX += _width;
+ else if (curX >= _width / 2)
+ curX -= _width;
+
+ float norm = (float)curX / ((float)_width / 2.0);
+ float lvl = fabs(norm);
+ if (lvl > 0.5)
+ lvl = (lvl - 0.5) * 1.7;
+ else
+ lvl = 1.0;
+
+ float bal = sin(-norm * 3.1415926) * 127.0;
+
+ if (_engine->_mixer->isSoundHandleActive(_handle)) {
+ _engine->_mixer->setChannelBalance(_handle, bal);
+ _engine->_mixer->setChannelVolume(_handle, newVolume * lvl);
+ }
+ } else {
+ if (_engine->_mixer->isSoundHandleActive(_handle)) {
+ _engine->_mixer->setChannelBalance(_handle, 0);
+ _engine->_mixer->setChannelVolume(_handle, newVolume);
+ }
+ }
+
+ _volume = newVolume;
+}
+
+PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_PANTRACK) {
+ _slot = slot;
+
+ ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(slot);
+ if (fx && fx->getType() == SCRIPTING_EFFECT_AUDIO) {
+ MusicNodeBASE *mus = (MusicNodeBASE *)fx;
+ mus->setPanTrack(pos);
+ }
+}
+
+PanTrackNode::~PanTrackNode() {
+ ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_slot);
+ if (fx && fx->getType() == SCRIPTING_EFFECT_AUDIO) {
+ MusicNodeBASE *mus = (MusicNodeBASE *)fx;
+ mus->unsetPanTrack();
+ }
+}
+
+MusicMidiNode::MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume)
+ : MusicNodeBASE(engine, key, SCRIPTING_EFFECT_AUDIO) {
+ _volume = volume;
+ _prog = program;
+ _noteNumber = note;
+ _pan = 0;
+
+ _chan = _engine->getMidiManager()->getFreeChannel();
+
+ if (_chan >= 0) {
+ _engine->getMidiManager()->setVolume(_chan, _volume);
+ _engine->getMidiManager()->setPan(_chan, _pan);
+ _engine->getMidiManager()->setProgram(_chan, _prog);
+ _engine->getMidiManager()->noteOn(_chan, _noteNumber, _volume);
+ }
+
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+MusicMidiNode::~MusicMidiNode() {
+ if (_chan >= 0) {
+ _engine->getMidiManager()->noteOff(_chan);
+ }
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+}
+
+void MusicMidiNode::setPanTrack(int16 pos) {
+}
+
+void MusicMidiNode::unsetPanTrack() {
+}
+
+void MusicMidiNode::setFade(int32 time, uint8 target) {
+}
+
+bool MusicMidiNode::process(uint32 deltaTimeInMillis) {
+ return false;
+}
+
+void MusicMidiNode::setVolume(uint8 newVolume) {
+ if (_chan >= 0) {
+ _engine->getMidiManager()->setVolume(_chan, newVolume);
+ }
+ _volume = newVolume;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/music_effect.h b/engines/zvision/scripting/effects/music_effect.h
new file mode 100644
index 0000000000..31d538f668
--- /dev/null
+++ b/engines/zvision/scripting/effects/music_effect.h
@@ -0,0 +1,135 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_MUSIC_NODE_H
+#define ZVISION_MUSIC_NODE_H
+
+#include "audio/mixer.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/subtitles.h"
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+class MusicNodeBASE : public ScriptingEffect {
+public:
+ MusicNodeBASE(ZVision *engine, uint32 key, ScriptingEffectType type) : ScriptingEffect(engine, key, type) {}
+ ~MusicNodeBASE() {}
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ virtual bool process(uint32 deltaTimeInMillis) = 0;
+
+ virtual void setVolume(uint8 volume) = 0;
+
+ virtual void setPanTrack(int16 pos) = 0;
+ virtual void unsetPanTrack() = 0;
+
+ virtual void setFade(int32 time, uint8 target) = 0;
+};
+
+class MusicNode : public MusicNodeBASE {
+public:
+ MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, int8 volume);
+ ~MusicNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+
+ void setVolume(uint8 volume);
+
+ void setPanTrack(int16 pos);
+ void unsetPanTrack();
+
+ void setFade(int32 time, uint8 target);
+
+private:
+ bool _pantrack;
+ int32 _pantrackPosition;
+ int32 _attenuate;
+ uint8 _volume;
+ bool _loop;
+ bool _crossfade;
+ uint8 _crossfadeTarget;
+ int32 _crossfadeTime;
+ bool _stereo;
+ Audio::SoundHandle _handle;
+ Subtitle *_sub;
+ bool _loaded;
+};
+
+// Only used by Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well as vr)
+class MusicMidiNode : public MusicNodeBASE {
+public:
+ MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume);
+ ~MusicMidiNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+
+ void setVolume(uint8 volume);
+
+ void setPanTrack(int16 pos);
+ void unsetPanTrack();
+
+ void setFade(int32 time, uint8 target);
+
+private:
+ int8 _chan;
+ int8 _noteNumber;
+ int8 _pan;
+ int8 _volume;
+ int8 _prog;
+};
+
+class PanTrackNode : public ScriptingEffect {
+public:
+ PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos);
+ ~PanTrackNode();
+
+private:
+ uint32 _slot;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/region_effect.cpp b/engines/zvision/scripting/effects/region_effect.cpp
new file mode 100644
index 0000000000..78061cf4de
--- /dev/null
+++ b/engines/zvision/scripting/effects/region_effect.cpp
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/region_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+namespace ZVision {
+
+RegionNode::RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_REGION) {
+ _effect = effect;
+ _delay = delay;
+ _timeLeft = 0;
+}
+
+RegionNode::~RegionNode() {
+ _engine->getRenderManager()->deleteEffect(_key);
+}
+
+bool RegionNode::process(uint32 deltaTimeInMillis) {
+ _timeLeft -= deltaTimeInMillis;
+
+ if (_timeLeft <= 0) {
+ _timeLeft = _delay;
+ if (_effect)
+ _effect->update();
+ }
+
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/region_effect.h b/engines/zvision/scripting/effects/region_effect.h
new file mode 100644
index 0000000000..4fc16224ff
--- /dev/null
+++ b/engines/zvision/scripting/effects/region_effect.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_REGION_NODE_H
+#define ZVISION_REGION_NODE_H
+
+#include "graphics/surface.h"
+
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/graphics/graphics_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class RegionNode : public ScriptingEffect {
+public:
+ RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay);
+ ~RegionNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ int32 _timeLeft;
+ uint32 _delay;
+ GraphicsEffect *_effect;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/syncsound_effect.cpp b/engines/zvision/scripting/effects/syncsound_effect.cpp
new file mode 100644
index 0000000000..70ba97deb8
--- /dev/null
+++ b/engines/zvision/scripting/effects/syncsound_effect.cpp
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/syncsound_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/sound/zork_raw.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "audio/decoders/wave.h"
+
+namespace ZVision {
+
+SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::String &filename, int32 syncto)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_AUDIO) {
+ _syncto = syncto;
+ _sub = NULL;
+
+ Audio::RewindableAudioStream *audioStream = NULL;
+
+ if (filename.contains(".wav")) {
+ Common::File *file = new Common::File();
+ if (_engine->getSearchManager()->openFile(*file, filename)) {
+ audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
+ }
+ } else {
+ audioStream = makeRawZorkStream(filename, _engine);
+ }
+
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream);
+
+ Common::String subname = filename;
+ subname.setChar('s', subname.size() - 3);
+ subname.setChar('u', subname.size() - 2);
+ subname.setChar('b', subname.size() - 1);
+
+ if (_engine->getSearchManager()->hasFile(subname))
+ _sub = new Subtitle(_engine, subname);
+}
+
+SyncSoundNode::~SyncSoundNode() {
+ _engine->_mixer->stopHandle(_handle);
+ if (_sub)
+ delete _sub;
+}
+
+bool SyncSoundNode::process(uint32 deltaTimeInMillis) {
+ if (! _engine->_mixer->isSoundHandleActive(_handle))
+ return stop();
+ else {
+
+ if (_engine->getScriptManager()->getSideFX(_syncto) == NULL)
+ return stop();
+
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
+ _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
+ }
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/syncsound_effect.h b/engines/zvision/scripting/effects/syncsound_effect.h
new file mode 100644
index 0000000000..0eabff77a3
--- /dev/null
+++ b/engines/zvision/scripting/effects/syncsound_effect.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_SYNCSOUND_NODE_H
+#define ZVISION_SYNCSOUND_NODE_H
+
+#include "audio/mixer.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/subtitles.h"
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+class SyncSoundNode : public ScriptingEffect {
+public:
+ SyncSoundNode(ZVision *engine, uint32 key, Common::String &file, int32 syncto);
+ ~SyncSoundNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+private:
+ int32 _syncto;
+ Audio::SoundHandle _handle;
+ Subtitle *_sub;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/timer_effect.cpp b/engines/zvision/scripting/effects/timer_effect.cpp
new file mode 100644
index 0000000000..778f9dec6c
--- /dev/null
+++ b/engines/zvision/scripting/effects/timer_effect.cpp
@@ -0,0 +1,81 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/timer_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+
+#include "common/stream.h"
+
+namespace ZVision {
+
+TimerNode::TimerNode(ZVision *engine, uint32 key, uint timeInSeconds)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_TIMER) {
+ _timeLeft = 0;
+
+ if (_engine->getGameId() == GID_NEMESIS)
+ _timeLeft = timeInSeconds * 1000;
+ else if (_engine->getGameId() == GID_GRANDINQUISITOR)
+ _timeLeft = timeInSeconds * 100;
+
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+TimerNode::~TimerNode() {
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ int32 timeLeft = _timeLeft / (_engine->getGameId() == GID_NEMESIS ? 1000 : 100);
+ if (timeLeft > 0)
+ _engine->getScriptManager()->setStateValue(_key, timeLeft); // If timer was stopped by stop or kill
+}
+
+bool TimerNode::process(uint32 deltaTimeInMillis) {
+ _timeLeft -= deltaTimeInMillis;
+
+ if (_timeLeft <= 0)
+ return stop();
+
+ return false;
+}
+
+bool TimerNode::stop() {
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ return true;
+}
+
+void TimerNode::serialize(Common::WriteStream *stream) {
+ stream->writeUint32BE(MKTAG('T', 'I', 'M', 'R'));
+ stream->writeUint32LE(8); // size
+ stream->writeUint32LE(_key);
+ stream->writeUint32LE(_timeLeft);
+}
+
+void TimerNode::deserialize(Common::SeekableReadStream *stream) {
+ _timeLeft = stream->readUint32LE();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/timer_effect.h b/engines/zvision/scripting/effects/timer_effect.h
new file mode 100644
index 0000000000..5e45d54d7d
--- /dev/null
+++ b/engines/zvision/scripting/effects/timer_effect.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_TIMER_NODE_H
+#define ZVISION_TIMER_NODE_H
+
+#include "zvision/scripting/scripting_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class TimerNode : public ScriptingEffect {
+public:
+ TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
+ ~TimerNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+ void serialize(Common::WriteStream *stream);
+ void deserialize(Common::SeekableReadStream *stream);
+ inline bool needsSerialization() {
+ return true;
+ }
+
+ bool stop();
+
+private:
+ int32 _timeLeft;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/ttytext_effect.cpp b/engines/zvision/scripting/effects/ttytext_effect.cpp
new file mode 100644
index 0000000000..c60b3aa8c5
--- /dev/null
+++ b/engines/zvision/scripting/effects/ttytext_effect.cpp
@@ -0,0 +1,174 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/ttytext_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/text.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+
+namespace ZVision {
+
+ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay) :
+ ScriptingEffect(engine, key, SCRIPTING_EFFECT_TTYTXT),
+ _fnt(engine) {
+ _delay = delay;
+ _r = r;
+ _txtpos = 0;
+ _nexttime = 0;
+ _dx = 0;
+ _dy = 0;
+
+ Common::File *infile = _engine->getSearchManager()->openFile(file);
+ if (infile) {
+ while (!infile->eos()) {
+ Common::String asciiLine = readWideLine(*infile);
+ if (asciiLine.empty()) {
+ continue;
+ }
+ _txtbuf += asciiLine;
+ }
+
+ delete infile;
+ }
+ _img.create(_r.width(), _r.height(), _engine->_resourcePixelFormat);
+ _style._sharp = true;
+ _style.readAllStyle(_txtbuf);
+ _style.setFont(_fnt);
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+ttyTextNode::~ttyTextNode() {
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ _img.free();
+}
+
+bool ttyTextNode::process(uint32 deltaTimeInMillis) {
+ _nexttime -= deltaTimeInMillis;
+
+ if (_nexttime < 0) {
+ if (_txtpos < _txtbuf.size()) {
+ if (_txtbuf[_txtpos] == '<') {
+ int32 strt = _txtpos;
+ int32 endt = 0;
+ int16 ret = 0;
+ while (_txtbuf[_txtpos] != '>' && _txtpos < _txtbuf.size())
+ _txtpos++;
+ endt = _txtpos;
+ if (strt != -1)
+ if ((endt - strt - 1) > 0)
+ ret = _style.parseStyle(_txtbuf.c_str() + strt + 1, endt - strt - 1);
+
+ if (ret & (TXT_RET_FNTCHG | TXT_RET_FNTSTL | TXT_RET_NEWLN)) {
+ if (ret & TXT_RET_FNTCHG)
+ _style.setFont(_fnt);
+ if (ret & TXT_RET_FNTSTL)
+ _style.setFontStyle(_fnt);
+
+ if (ret & TXT_RET_NEWLN)
+ newline();
+ }
+
+ if (ret & TXT_RET_HASSTBOX) {
+ Common::String buf;
+ buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_style._statebox));
+
+ for (uint8 j = 0; j < buf.size(); j++)
+ outchar(buf[j]);
+ }
+
+ _txtpos++;
+ } else {
+ int8 charsz = getUtf8CharSize(_txtbuf[_txtpos]);
+
+ uint16 chr = readUtf8Char(_txtbuf.c_str() + _txtpos);
+
+ if (chr == ' ') {
+ uint32 i = _txtpos + charsz;
+ uint16 width = _fnt.getCharWidth(chr);
+
+ while (i < _txtbuf.size() && _txtbuf[i] != ' ' && _txtbuf[i] != '<') {
+
+ int8 chsz = getUtf8CharSize(_txtbuf[i]);
+ uint16 uchr = readUtf8Char(_txtbuf.c_str() + _txtpos);
+
+ width += _fnt.getCharWidth(uchr);
+
+ i += chsz;
+ }
+
+ if (_dx + width > _r.width())
+ newline();
+ else
+ outchar(chr);
+ } else
+ outchar(chr);
+
+ _txtpos += charsz;
+ }
+ _nexttime = _delay;
+ _engine->getRenderManager()->blitSurfaceToBkg(_img, _r.left, _r.top);
+ } else
+ return stop();
+ }
+
+ return false;
+}
+
+void ttyTextNode::scroll() {
+ int32 scrl = 0;
+ while (_dy - scrl > _r.height() - _fnt.getFontHeight())
+ scrl += _fnt.getFontHeight();
+ int8 *pixels = (int8 *)_img.getPixels();
+ for (uint16 h = scrl; h < _img.h; h++)
+ memcpy(pixels + _img.pitch * (h - scrl), pixels + _img.pitch * h, _img.pitch);
+
+ _img.fillRect(Common::Rect(0, _img.h - scrl, _img.w, _img.h), 0);
+ _dy -= scrl;
+}
+
+void ttyTextNode::newline() {
+ _dy += _fnt.getFontHeight();
+ _dx = 0;
+}
+
+void ttyTextNode::outchar(uint16 chr) {
+ uint32 clr = _engine->_resourcePixelFormat.RGBToColor(_style._red, _style._green, _style._blue);
+
+ if (_dx + _fnt.getCharWidth(chr) > _r.width())
+ newline();
+
+ if (_dy + _fnt.getFontHeight() >= _r.height())
+ scroll();
+
+ _fnt.drawChar(&_img, chr, _dx, _dy, clr);
+
+ _dx += _fnt.getCharWidth(chr);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/ttytext_effect.h b/engines/zvision/scripting/effects/ttytext_effect.h
new file mode 100644
index 0000000000..8d8a2518c7
--- /dev/null
+++ b/engines/zvision/scripting/effects/ttytext_effect.h
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_TTYTEXT_NODE_H
+#define ZVISION_TTYTEXT_NODE_H
+
+#include "common/rect.h"
+#include "graphics/surface.h"
+
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/text.h"
+#include "zvision/text/truetype_font.h"
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+class ttyTextNode : public ScriptingEffect {
+public:
+ ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay);
+ ~ttyTextNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+private:
+ Common::Rect _r;
+
+ cTxtStyle _style;
+ StyledTTFont _fnt;
+ Common::String _txtbuf;
+ uint32 _txtpos;
+
+ int32 _delay;
+ int32 _nexttime;
+ Graphics::Surface _img;
+ int16 _dx;
+ int16 _dy;
+private:
+
+ void newline();
+ void scroll();
+ void outchar(uint16 chr);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
index d0ebb18944..464e8bfe4d 100644
--- a/engines/zvision/scripting/script_manager.cpp
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -30,7 +30,7 @@
#include "zvision/file/save_manager.h"
#include "zvision/scripting/actions.h"
#include "zvision/scripting/menu.h"
-#include "zvision/scripting/sidefx/timer_node.h"
+#include "zvision/scripting/effects/timer_effect.h"
#include "common/algorithm.h"
#include "common/hashmap.h"
@@ -382,11 +382,11 @@ void ScriptManager::setFocusControlKey(uint32 key) {
_currentlyFocusedControl = key;
}
-void ScriptManager::addSideFX(SideFX *fx) {
+void ScriptManager::addSideFX(ScriptingEffect *fx) {
_activeSideFx.push_back(fx);
}
-SideFX *ScriptManager::getSideFX(uint32 key) {
+ScriptingEffect *ScriptManager::getSideFX(uint32 key) {
for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
if ((*iter)->getKey() == key) {
return (*iter);
@@ -430,7 +430,7 @@ void ScriptManager::killSideFx(uint32 key) {
}
}
-void ScriptManager::killSideFxType(SideFX::SideFXType type) {
+void ScriptManager::killSideFxType(ScriptingEffect::ScriptingEffectType type) {
for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end();) {
if ((*iter)->getType() & type) {
(*iter)->kill();
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
index 9f0f2f6e10..78c1b77dea 100644
--- a/engines/zvision/scripting/script_manager.h
+++ b/engines/zvision/scripting/script_manager.h
@@ -25,7 +25,7 @@
#include "zvision/scripting/puzzle.h"
#include "zvision/scripting/control.h"
-#include "zvision/scripting/sidefx.h"
+#include "zvision/scripting/scripting_effect.h"
#include "common/hashmap.h"
#include "common/queue.h"
@@ -116,7 +116,7 @@ typedef Common::List PuzzleList;
typedef Common::Queue PuzzleQueue;
typedef Common::List ControlList;
typedef Common::HashMap StateMap;
-typedef Common::List SideFXList;
+typedef Common::List SideFXList;
typedef Common::List EventList;
class ScriptManager {
@@ -196,12 +196,12 @@ public:
// Only change focus control without call focus/unfocus.
void setFocusControlKey(uint32 key);
- void addSideFX(SideFX *fx);
- SideFX *getSideFX(uint32 key);
+ void addSideFX(ScriptingEffect *fx);
+ ScriptingEffect *getSideFX(uint32 key);
void deleteSideFx(uint32 key);
void stopSideFx(uint32 key);
void killSideFx(uint32 key);
- void killSideFxType(SideFX::SideFXType type);
+ void killSideFxType(ScriptingEffect::ScriptingEffectType type);
void addEvent(Common::Event);
void flushEvent(Common::EventType type);
diff --git a/engines/zvision/scripting/scripting_effect.h b/engines/zvision/scripting/scripting_effect.h
new file mode 100644
index 0000000000..0af1d9c21c
--- /dev/null
+++ b/engines/zvision/scripting/scripting_effect.h
@@ -0,0 +1,124 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCRIPTING_EFFECT_H_INCLUDED
+#define SCRIPTING_EFFECT_H_INCLUDED
+
+namespace Common {
+class SeekableReadStream;
+struct Point;
+class WriteStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+/**
+ * The base class that represents effects created from Actions.
+ * This class is virtual.
+ *
+ * Detailed Description:
+ * A scene has Controls. By interacting with the controls, the user
+ * causes Actions to execute. Certain Actions create 'effects', for
+ * example, a sound or an animation. This is the base class for
+ * those effects.
+ */
+class ScriptingEffect {
+public:
+
+ enum ScriptingEffectType {
+ SCRIPTING_EFFECT_ANIM = 1,
+ SCRIPTING_EFFECT_AUDIO = 2,
+ SCRIPTING_EFFECT_DISTORT = 4,
+ SCRIPTING_EFFECT_PANTRACK = 8,
+ SCRIPTING_EFFECT_REGION = 16,
+ SCRIPTING_EFFECT_TIMER = 32,
+ SCRIPTING_EFFECT_TTYTXT = 64,
+ SCRIPTING_EFFECT_UNKNOWN = 128,
+ SCRIPTING_EFFECT_ALL = 255
+ };
+
+ ScriptingEffect() : _engine(0), _key(0), _type(SCRIPTING_EFFECT_UNKNOWN) {}
+ ScriptingEffect(ZVision *engine, uint32 key, ScriptingEffectType type) : _engine(engine), _key(key), _type(type) {}
+ virtual ~ScriptingEffect() {}
+
+ uint32 getKey() {
+ return _key;
+ }
+ ScriptingEffectType getType() {
+ return _type;
+ }
+
+ virtual bool process(uint32 deltaTimeInMillis) {
+ return false;
+ }
+ /**
+ * Serialize a SideFX for save game use. This should only be used if a SideFX needs
+ * to save values that would be different from initialization. AKA a TimerNode needs to
+ * store the amount of time left on the timer. Any Controls overriding this *MUST* write
+ * their key as the first data outputted. The default implementation is NOP.
+ *
+ * NOTE: If this method is overridden, you MUST also override deserialize()
+ * and needsSerialization()
+ *
+ * @param stream Stream to write any needed data to
+ */
+ virtual void serialize(Common::WriteStream *stream) {}
+ /**
+ * De-serialize data from a save game stream. This should only be implemented if the
+ * SideFX also implements serialize(). The calling method assumes the size of the
+ * data read from the stream exactly equals that written in serialize(). The default
+ * implementation is NOP.
+ *
+ * NOTE: If this method is overridden, you MUST also override serialize()
+ * and needsSerialization()
+ *
+ * @param stream Save game file stream
+ */
+ virtual void deserialize(Common::SeekableReadStream *stream) {}
+ /**
+ * If a SideFX overrides serialize() and deserialize(), this should return true
+ *
+ * @return Does the SideFX need save game serialization?
+ */
+ virtual inline bool needsSerialization() {
+ return false;
+ }
+
+ virtual bool stop() {
+ return true;
+ }
+ virtual void kill() {}
+
+protected:
+ ZVision *_engine;
+ uint32 _key;
+ ScriptingEffectType _type;
+
+// Static member functions
+public:
+
+};
+} // End of namespace ZVision
+
+#endif // SCRIPTING_EFFECT_H_INCLUDED
diff --git a/engines/zvision/scripting/sidefx.h b/engines/zvision/scripting/sidefx.h
deleted file mode 100644
index 5bb14f0cdd..0000000000
--- a/engines/zvision/scripting/sidefx.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef SIDEFX_H_INCLUDED
-#define SIDEFX_H_INCLUDED
-
-namespace Common {
-class SeekableReadStream;
-struct Point;
-class WriteStream;
-}
-
-namespace ZVision {
-
-class ZVision;
-
-class SideFX {
-public:
-
- enum SideFXType {
- SIDEFX_ANIM = 1,
- SIDEFX_AUDIO = 2,
- SIDEFX_DISTORT = 4,
- SIDEFX_PANTRACK = 8,
- SIDEFX_REGION = 16,
- SIDEFX_TIMER = 32,
- SIDEFX_TTYTXT = 64,
- SIDEFX_UNK = 128,
- SIDEFX_ALL = 255
- };
-
- SideFX() : _engine(0), _key(0), _type(SIDEFX_UNK) {}
- SideFX(ZVision *engine, uint32 key, SideFXType type) : _engine(engine), _key(key), _type(type) {}
- virtual ~SideFX() {}
-
- uint32 getKey() {
- return _key;
- }
- SideFXType getType() {
- return _type;
- }
-
- virtual bool process(uint32 deltaTimeInMillis) {
- return false;
- }
- /**
- * Serialize a SideFX for save game use. This should only be used if a SideFX needs
- * to save values that would be different from initialization. AKA a TimerNode needs to
- * store the amount of time left on the timer. Any Controls overriding this *MUST* write
- * their key as the first data outputted. The default implementation is NOP.
- *
- * NOTE: If this method is overridden, you MUST also override deserialize()
- * and needsSerialization()
- *
- * @param stream Stream to write any needed data to
- */
- virtual void serialize(Common::WriteStream *stream) {}
- /**
- * De-serialize data from a save game stream. This should only be implemented if the
- * SideFX also implements serialize(). The calling method assumes the size of the
- * data read from the stream exactly equals that written in serialize(). The default
- * implementation is NOP.
- *
- * NOTE: If this method is overridden, you MUST also override serialize()
- * and needsSerialization()
- *
- * @param stream Save game file stream
- */
- virtual void deserialize(Common::SeekableReadStream *stream) {}
- /**
- * If a SideFX overrides serialize() and deserialize(), this should return true
- *
- * @return Does the SideFX need save game serialization?
- */
- virtual inline bool needsSerialization() {
- return false;
- }
-
- virtual bool stop() {
- return true;
- }
- virtual void kill() {}
-
-protected:
- ZVision *_engine;
- uint32 _key;
- SideFXType _type;
-
-// Static member functions
-public:
-
-};
-} // End of namespace ZVision
-
-#endif // SIDEFX_H_INCLUDED
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp
deleted file mode 100644
index 07eda692c1..0000000000
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/scripting/sidefx/animation_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/scripting/script_manager.h"
-
-#include "graphics/surface.h"
-#include "video/video_decoder.h"
-
-namespace ZVision {
-
-AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse)
- : SideFX(engine, controlKey, SIDEFX_ANIM),
- _disposeAfterUse(disposeAfterUse),
- _mask(mask),
- _animation(NULL) {
-
- _animation = engine->loadAnimation(fileName);
-
- if (frate > 0) {
- _frmDelayOverride = (int32)(1000.0 / frate);
-
- // WORKAROUND: We do not allow the engine to delay more than 66 msec
- // per frame (15fps max)
- if (_frmDelayOverride > 66)
- _frmDelayOverride = 66;
- } else {
- _frmDelayOverride = 0;
- }
-}
-
-AnimationNode::~AnimationNode() {
- if (_animation)
- delete _animation;
-
- _engine->getScriptManager()->setStateValue(_key, 2);
-
- PlayNodes::iterator it = _playList.begin();
- if (it != _playList.end()) {
- _engine->getScriptManager()->setStateValue((*it).slot, 2);
-
- if ((*it)._scaled) {
- (*it)._scaled->free();
- delete(*it)._scaled;
- }
- }
-
- _playList.clear();
-}
-
-bool AnimationNode::process(uint32 deltaTimeInMillis) {
- ScriptManager *scriptManager = _engine->getScriptManager();
- RenderManager *renderManager = _engine->getRenderManager();
- RenderTable::RenderState renderState = renderManager->getRenderTable()->getRenderState();
- bool isPanorama = (renderState == RenderTable::PANORAMA);
- int16 velocity = _engine->getMouseVelocity() + _engine->getKeyboardVelocity();
-
- // Do not update animation nodes in panoramic mode while turning, if the user
- // has set this option
- if (scriptManager->getStateValue(StateKey_NoTurnAnim) == 1 && isPanorama && velocity)
- return false;
-
- PlayNodes::iterator it = _playList.begin();
- if (it != _playList.end()) {
- playnode *nod = &(*it);
-
- if (!_animation->isPlaying()) {
- // The node is just beginning playback
- _animation->start();
- _animation->seekToFrame(nod->start);
-
- nod->_delay = deltaTimeInMillis; // Force the frame to draw
- if (nod->slot)
- scriptManager->setStateValue(nod->slot, 1);
- } else if (_animation->endOfVideo()) {
- // The node has reached the end; check if we need to loop
- nod->loop--;
-
- if (nod->loop == 0) {
- if (nod->slot >= 0)
- scriptManager->setStateValue(nod->slot, 2);
- if (nod->_scaled) {
- nod->_scaled->free();
- delete nod->_scaled;
- }
- _playList.erase(it);
- return _disposeAfterUse;
- }
-
- _animation->seekToFrame(nod->start);
- }
-
- // Check if we need to draw a frame
- bool needsUpdate = false;
- if (_frmDelayOverride == 0) {
- // If not overridden, use the VideoDecoder's check
- needsUpdate = _animation->needsUpdate();
- } else {
- // Otherwise, implement our own timing
- nod->_delay -= deltaTimeInMillis;
-
- if (nod->_delay <= 0) {
- nod->_delay += _frmDelayOverride;
- needsUpdate = true;
- }
- }
-
- if (needsUpdate) {
- const Graphics::Surface *frame = _animation->decodeNextFrame();
-
- if (frame) {
- uint32 dstw;
- uint32 dsth;
- if (isPanorama) {
- dstw = nod->pos.height();
- dsth = nod->pos.width();
- } else {
- dstw = nod->pos.width();
- dsth = nod->pos.height();
- }
-
- // We only scale down the animation to fit its frame, not up, otherwise we
- // end up with distorted animations - e.g. the armor visor in location cz1e
- // in Nemesis (one of the armors inside Irondune), or the planet in location
- // aa10 in Nemesis (Juperon, outside the asylum). We do allow scaling up only
- // when a simple 2x filter is requested (e.g. the alchemists and cup sequence
- // in Nemesis)
- if (frame->w > dstw || frame->h > dsth || (frame->w == dstw / 2 && frame->h == dsth / 2)) {
- if (nod->_scaled)
- if (nod->_scaled->w != dstw || nod->_scaled->h != dsth) {
- nod->_scaled->free();
- delete nod->_scaled;
- nod->_scaled = NULL;
- }
-
- if (!nod->_scaled) {
- nod->_scaled = new Graphics::Surface;
- nod->_scaled->create(dstw, dsth, frame->format);
- }
-
- renderManager->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
- frame = nod->_scaled;
- }
-
- if (isPanorama) {
- Graphics::Surface *transposed = RenderManager::tranposeSurface(frame);
- renderManager->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
- transposed->free();
- delete transposed;
- } else {
- renderManager->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
- }
- }
- }
- }
-
- return false;
-}
-
-void AnimationNode::addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops) {
- playnode nod;
- nod.loop = loops;
- nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1);
- nod.start = startFrame;
- _animation->setEndFrame(CLIP(endFrame, 0, _animation->getFrameCount() - 1));
-
- nod.slot = slot;
- nod._delay = 0;
- nod._scaled = NULL;
- _playList.push_back(nod);
-}
-
-bool AnimationNode::stop() {
- PlayNodes::iterator it = _playList.begin();
- if (it != _playList.end()) {
- _engine->getScriptManager()->setStateValue((*it).slot, 2);
- if ((*it)._scaled) {
- (*it)._scaled->free();
- delete(*it)._scaled;
- }
- }
-
- _playList.clear();
-
- // We don't need to delete, it's may be reused
- return false;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/sidefx/animation_node.h
deleted file mode 100644
index 1dc0dc71b8..0000000000
--- a/engines/zvision/scripting/sidefx/animation_node.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_ANIMATION_NODE_H
-#define ZVISION_ANIMATION_NODE_H
-
-#include "zvision/scripting/sidefx.h"
-#include "common/rect.h"
-#include "common/list.h"
-
-namespace Graphics {
-struct Surface;
-}
-
-namespace Video {
- class VideoDecoder;
-}
-
-namespace ZVision {
-
-class ZVision;
-
-class AnimationNode : public SideFX {
-public:
- AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse = true);
- ~AnimationNode();
-
- struct playnode {
- Common::Rect pos;
- int32 slot;
- int32 start;
- int32 loop;
- int32 _delay;
- Graphics::Surface *_scaled;
- };
-
-private:
- typedef Common::List PlayNodes;
-
- PlayNodes _playList;
-
- int32 _mask;
- bool _disposeAfterUse;
-
- Video::VideoDecoder *_animation;
- int32 _frmDelayOverride;
-
-public:
- bool process(uint32 deltaTimeInMillis);
-
- void addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops = 1);
-
- bool stop();
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/scripting/sidefx/distort_node.cpp b/engines/zvision/scripting/sidefx/distort_node.cpp
deleted file mode 100644
index 7d25adc031..0000000000
--- a/engines/zvision/scripting/sidefx/distort_node.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/scripting/sidefx/distort_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/render_table.h"
-
-#include "common/stream.h"
-
-namespace ZVision {
-
-DistortNode::DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale)
- : SideFX(engine, key, SIDEFX_DISTORT) {
-
- _angle = _engine->getRenderManager()->getRenderTable()->getAngle();
- _linScale = _engine->getRenderManager()->getRenderTable()->getLinscale();
-
- _speed = speed;
- _incr = true;
- _startAngle = startAngle;
- _endAngle = endAngle;
- _startLineScale = startLineScale;
- _endLineScale = endLineScale;
-
- _curFrame = 1.0;
-
- _diffAngle = endAngle - startAngle;
- _diffLinScale = endLineScale - startLineScale;
-
- _frmSpeed = (float)speed / 15.0;
- _frames = ceil((5.0 - _frmSpeed * 2.0) / _frmSpeed);
- if (_frames <= 0)
- _frames = 1;
-
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 1);
-}
-
-DistortNode::~DistortNode() {
- setParams(_angle, _linScale);
-}
-
-bool DistortNode::process(uint32 deltaTimeInMillis) {
- float updTime = deltaTimeInMillis / (1000.0 / 60.0);
-
- if (_incr)
- _curFrame += updTime;
- else
- _curFrame -= updTime;
-
- if (_curFrame < 1.0) {
- _curFrame = 1.0;
- _incr = true;
- } else if (_curFrame > _frames) {
- _curFrame = _frames;
- _incr = false;
- }
-
- float diff = (1.0 / (5.0 - (_curFrame * _frmSpeed))) / (5.0 - _frmSpeed);
- setParams(_startAngle + diff * _diffAngle, _startLineScale + diff * _diffLinScale);
-
- return false;
-}
-
-void DistortNode::setParams(float angl, float linScale) {
- RenderTable *table = _engine->getRenderManager()->getRenderTable();
- if (table->getRenderState() == RenderTable::PANORAMA) {
- table->setPanoramaFoV(angl);
- table->setPanoramaScale(linScale);
- table->generateRenderTable();
- _engine->getRenderManager()->markDirty();
- } else if (table->getRenderState() == RenderTable::TILT) {
- table->setTiltFoV(angl);
- table->setTiltScale(linScale);
- table->generateRenderTable();
- _engine->getRenderManager()->markDirty();
- }
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/distort_node.h b/engines/zvision/scripting/sidefx/distort_node.h
deleted file mode 100644
index 787a69bdde..0000000000
--- a/engines/zvision/scripting/sidefx/distort_node.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_DISTORT_NODE_H
-#define ZVISION_DISTORT_NODE_H
-
-#include "zvision/scripting/sidefx.h"
-
-namespace ZVision {
-
-class ZVision;
-
-class DistortNode : public SideFX {
-public:
- DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale);
- ~DistortNode();
-
- bool process(uint32 deltaTimeInMillis);
-
-private:
- int16 _speed;
- float _startAngle;
- float _endAngle;
- float _startLineScale;
- float _endLineScale;
-
- float _frmSpeed;
- float _diffAngle;
- float _diffLinScale;
- bool _incr;
- int16 _frames;
-
- float _curFrame;
-
- float _angle;
- float _linScale;
-
-private:
- void setParams(float angl, float linScale);
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/scripting/sidefx/music_node.cpp b/engines/zvision/scripting/sidefx/music_node.cpp
deleted file mode 100644
index 0cada6d748..0000000000
--- a/engines/zvision/scripting/sidefx/music_node.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/scripting/sidefx/music_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/sound/midi.h"
-#include "zvision/sound/zork_raw.h"
-
-#include "common/stream.h"
-#include "common/file.h"
-#include "audio/decoders/wave.h"
-
-namespace ZVision {
-
-MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, int8 volume)
- : MusicNodeBASE(engine, key, SIDEFX_AUDIO) {
- _loop = loop;
- _volume = volume;
- _crossfade = false;
- _crossfadeTarget = 0;
- _crossfadeTime = 0;
- _attenuate = 0;
- _pantrack = false;
- _pantrackPosition = 0;
- _sub = NULL;
- _stereo = false;
- _loaded = false;
-
- Audio::RewindableAudioStream *audioStream = NULL;
-
- if (filename.contains(".wav")) {
- Common::File *file = new Common::File();
- if (_engine->getSearchManager()->openFile(*file, filename)) {
- audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
- }
- } else {
- audioStream = makeRawZorkStream(filename, _engine);
- }
-
- if (audioStream) {
- _stereo = audioStream->isStereo();
-
- if (_loop) {
- Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
- _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, _volume);
- } else {
- _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, _volume);
- }
-
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 1);
-
- // Change filename.raw into filename.sub
- Common::String subname = filename;
- subname.setChar('s', subname.size() - 3);
- subname.setChar('u', subname.size() - 2);
- subname.setChar('b', subname.size() - 1);
-
- if (_engine->getSearchManager()->hasFile(subname))
- _sub = new Subtitle(_engine, subname);
-
- _loaded = true;
- }
-}
-
-MusicNode::~MusicNode() {
- if (_loaded)
- _engine->_mixer->stopHandle(_handle);
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 2);
- if (_sub)
- delete _sub;
- debug(1, "MusicNode: %d destroyed\n", _key);
-}
-
-void MusicNode::setPanTrack(int16 pos) {
- if (!_stereo) {
- _pantrack = true;
- _pantrackPosition = pos;
- setVolume(_volume);
- }
-}
-
-void MusicNode::unsetPanTrack() {
- _pantrack = false;
- setVolume(_volume);
-}
-
-void MusicNode::setFade(int32 time, uint8 target) {
- _crossfadeTarget = target;
- _crossfadeTime = time;
- _crossfade = true;
-}
-
-bool MusicNode::process(uint32 deltaTimeInMillis) {
- if (!_loaded || ! _engine->_mixer->isSoundHandleActive(_handle))
- return stop();
- else {
- uint8 _newvol = _volume;
-
- if (_crossfade) {
- if (_crossfadeTime > 0) {
- if ((int32)deltaTimeInMillis > _crossfadeTime)
- deltaTimeInMillis = _crossfadeTime;
- _newvol += floor(((float)(_crossfadeTarget - _newvol) / (float)_crossfadeTime)) * (float)deltaTimeInMillis;
- _crossfadeTime -= deltaTimeInMillis;
- } else {
- _crossfade = false;
- _newvol = _crossfadeTarget;
- }
- }
-
- if (_pantrack || _volume != _newvol)
- setVolume(_newvol);
-
- if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
- _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
- }
- return false;
-}
-
-void MusicNode::setVolume(uint8 newVolume) {
- if (!_loaded)
- return;
- if (_pantrack) {
- int curX = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
- curX -= _pantrackPosition;
- int32 _width = _engine->getRenderManager()->getBkgSize().x;
- if (curX < (-_width) / 2)
- curX += _width;
- else if (curX >= _width / 2)
- curX -= _width;
-
- float norm = (float)curX / ((float)_width / 2.0);
- float lvl = fabs(norm);
- if (lvl > 0.5)
- lvl = (lvl - 0.5) * 1.7;
- else
- lvl = 1.0;
-
- float bal = sin(-norm * 3.1415926) * 127.0;
-
- if (_engine->_mixer->isSoundHandleActive(_handle)) {
- _engine->_mixer->setChannelBalance(_handle, bal);
- _engine->_mixer->setChannelVolume(_handle, newVolume * lvl);
- }
- } else {
- if (_engine->_mixer->isSoundHandleActive(_handle)) {
- _engine->_mixer->setChannelBalance(_handle, 0);
- _engine->_mixer->setChannelVolume(_handle, newVolume);
- }
- }
-
- _volume = newVolume;
-}
-
-PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos)
- : SideFX(engine, key, SIDEFX_PANTRACK) {
- _slot = slot;
-
- SideFX *fx = _engine->getScriptManager()->getSideFX(slot);
- if (fx && fx->getType() == SIDEFX_AUDIO) {
- MusicNodeBASE *mus = (MusicNodeBASE *)fx;
- mus->setPanTrack(pos);
- }
-}
-
-PanTrackNode::~PanTrackNode() {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_slot);
- if (fx && fx->getType() == SIDEFX_AUDIO) {
- MusicNodeBASE *mus = (MusicNodeBASE *)fx;
- mus->unsetPanTrack();
- }
-}
-
-MusicMidiNode::MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume)
- : MusicNodeBASE(engine, key, SIDEFX_AUDIO) {
- _volume = volume;
- _prog = program;
- _noteNumber = note;
- _pan = 0;
-
- _chan = _engine->getMidiManager()->getFreeChannel();
-
- if (_chan >= 0) {
- _engine->getMidiManager()->setVolume(_chan, _volume);
- _engine->getMidiManager()->setPan(_chan, _pan);
- _engine->getMidiManager()->setProgram(_chan, _prog);
- _engine->getMidiManager()->noteOn(_chan, _noteNumber, _volume);
- }
-
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 1);
-}
-
-MusicMidiNode::~MusicMidiNode() {
- if (_chan >= 0) {
- _engine->getMidiManager()->noteOff(_chan);
- }
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 2);
-}
-
-void MusicMidiNode::setPanTrack(int16 pos) {
-}
-
-void MusicMidiNode::unsetPanTrack() {
-}
-
-void MusicMidiNode::setFade(int32 time, uint8 target) {
-}
-
-bool MusicMidiNode::process(uint32 deltaTimeInMillis) {
- return false;
-}
-
-void MusicMidiNode::setVolume(uint8 newVolume) {
- if (_chan >= 0) {
- _engine->getMidiManager()->setVolume(_chan, newVolume);
- }
- _volume = newVolume;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/music_node.h b/engines/zvision/scripting/sidefx/music_node.h
deleted file mode 100644
index 3f1ca5cf7b..0000000000
--- a/engines/zvision/scripting/sidefx/music_node.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_MUSIC_NODE_H
-#define ZVISION_MUSIC_NODE_H
-
-#include "audio/mixer.h"
-#include "zvision/scripting/sidefx.h"
-#include "zvision/text/subtitles.h"
-
-namespace Common {
-class String;
-}
-
-namespace ZVision {
-
-class MusicNodeBASE : public SideFX {
-public:
- MusicNodeBASE(ZVision *engine, uint32 key, SideFXType type) : SideFX(engine, key, type) {}
- ~MusicNodeBASE() {}
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
- virtual bool process(uint32 deltaTimeInMillis) = 0;
-
- virtual void setVolume(uint8 volume) = 0;
-
- virtual void setPanTrack(int16 pos) = 0;
- virtual void unsetPanTrack() = 0;
-
- virtual void setFade(int32 time, uint8 target) = 0;
-};
-
-class MusicNode : public MusicNodeBASE {
-public:
- MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, int8 volume);
- ~MusicNode();
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
- bool process(uint32 deltaTimeInMillis);
-
- void setVolume(uint8 volume);
-
- void setPanTrack(int16 pos);
- void unsetPanTrack();
-
- void setFade(int32 time, uint8 target);
-
-private:
- bool _pantrack;
- int32 _pantrackPosition;
- int32 _attenuate;
- uint8 _volume;
- bool _loop;
- bool _crossfade;
- uint8 _crossfadeTarget;
- int32 _crossfadeTime;
- bool _stereo;
- Audio::SoundHandle _handle;
- Subtitle *_sub;
- bool _loaded;
-};
-
-// Only used by Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well as vr)
-class MusicMidiNode : public MusicNodeBASE {
-public:
- MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume);
- ~MusicMidiNode();
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
- bool process(uint32 deltaTimeInMillis);
-
- void setVolume(uint8 volume);
-
- void setPanTrack(int16 pos);
- void unsetPanTrack();
-
- void setFade(int32 time, uint8 target);
-
-private:
- int8 _chan;
- int8 _noteNumber;
- int8 _pan;
- int8 _volume;
- int8 _prog;
-};
-
-class PanTrackNode : public SideFX {
-public:
- PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos);
- ~PanTrackNode();
-
-private:
- uint32 _slot;
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/scripting/sidefx/region_node.cpp b/engines/zvision/scripting/sidefx/region_node.cpp
deleted file mode 100644
index de613d8af2..0000000000
--- a/engines/zvision/scripting/sidefx/region_node.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/scripting/sidefx/region_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-
-namespace ZVision {
-
-RegionNode::RegionNode(ZVision *engine, uint32 key, Effect *effect, uint32 delay)
- : SideFX(engine, key, SIDEFX_REGION) {
- _effect = effect;
- _delay = delay;
- _timeLeft = 0;
-}
-
-RegionNode::~RegionNode() {
- _engine->getRenderManager()->deleteEffect(_key);
-}
-
-bool RegionNode::process(uint32 deltaTimeInMillis) {
- _timeLeft -= deltaTimeInMillis;
-
- if (_timeLeft <= 0) {
- _timeLeft = _delay;
- if (_effect)
- _effect->update();
- }
-
- return false;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/region_node.h b/engines/zvision/scripting/sidefx/region_node.h
deleted file mode 100644
index ec716b6e3e..0000000000
--- a/engines/zvision/scripting/sidefx/region_node.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_REGION_NODE_H
-#define ZVISION_REGION_NODE_H
-
-#include "graphics/surface.h"
-
-#include "zvision/scripting/sidefx.h"
-#include "zvision/graphics/effect.h"
-
-namespace ZVision {
-
-class ZVision;
-
-class RegionNode : public SideFX {
-public:
- RegionNode(ZVision *engine, uint32 key, Effect *effect, uint32 delay);
- ~RegionNode();
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
- bool process(uint32 deltaTimeInMillis);
-
-private:
- int32 _timeLeft;
- uint32 _delay;
- Effect *_effect;
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/scripting/sidefx/syncsound_node.cpp b/engines/zvision/scripting/sidefx/syncsound_node.cpp
deleted file mode 100644
index eec320bf2e..0000000000
--- a/engines/zvision/scripting/sidefx/syncsound_node.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/scripting/sidefx/syncsound_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/sound/zork_raw.h"
-
-#include "common/stream.h"
-#include "common/file.h"
-#include "audio/decoders/wave.h"
-
-namespace ZVision {
-
-SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::String &filename, int32 syncto)
- : SideFX(engine, key, SIDEFX_AUDIO) {
- _syncto = syncto;
- _sub = NULL;
-
- Audio::RewindableAudioStream *audioStream = NULL;
-
- if (filename.contains(".wav")) {
- Common::File *file = new Common::File();
- if (_engine->getSearchManager()->openFile(*file, filename)) {
- audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
- }
- } else {
- audioStream = makeRawZorkStream(filename, _engine);
- }
-
- _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream);
-
- Common::String subname = filename;
- subname.setChar('s', subname.size() - 3);
- subname.setChar('u', subname.size() - 2);
- subname.setChar('b', subname.size() - 1);
-
- if (_engine->getSearchManager()->hasFile(subname))
- _sub = new Subtitle(_engine, subname);
-}
-
-SyncSoundNode::~SyncSoundNode() {
- _engine->_mixer->stopHandle(_handle);
- if (_sub)
- delete _sub;
-}
-
-bool SyncSoundNode::process(uint32 deltaTimeInMillis) {
- if (! _engine->_mixer->isSoundHandleActive(_handle))
- return stop();
- else {
-
- if (_engine->getScriptManager()->getSideFX(_syncto) == NULL)
- return stop();
-
- if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
- _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
- }
- return false;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/syncsound_node.h b/engines/zvision/scripting/sidefx/syncsound_node.h
deleted file mode 100644
index 5961fccab9..0000000000
--- a/engines/zvision/scripting/sidefx/syncsound_node.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_SYNCSOUND_NODE_H
-#define ZVISION_SYNCSOUND_NODE_H
-
-#include "audio/mixer.h"
-#include "zvision/scripting/sidefx.h"
-#include "zvision/text/subtitles.h"
-
-namespace Common {
-class String;
-}
-
-namespace ZVision {
-class SyncSoundNode : public SideFX {
-public:
- SyncSoundNode(ZVision *engine, uint32 key, Common::String &file, int32 syncto);
- ~SyncSoundNode();
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
- bool process(uint32 deltaTimeInMillis);
-private:
- int32 _syncto;
- Audio::SoundHandle _handle;
- Subtitle *_sub;
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/scripting/sidefx/timer_node.cpp b/engines/zvision/scripting/sidefx/timer_node.cpp
deleted file mode 100644
index 170f6e7472..0000000000
--- a/engines/zvision/scripting/sidefx/timer_node.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/scripting/sidefx/timer_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-
-#include "common/stream.h"
-
-namespace ZVision {
-
-TimerNode::TimerNode(ZVision *engine, uint32 key, uint timeInSeconds)
- : SideFX(engine, key, SIDEFX_TIMER) {
- _timeLeft = 0;
-
- if (_engine->getGameId() == GID_NEMESIS)
- _timeLeft = timeInSeconds * 1000;
- else if (_engine->getGameId() == GID_GRANDINQUISITOR)
- _timeLeft = timeInSeconds * 100;
-
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 1);
-}
-
-TimerNode::~TimerNode() {
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 2);
- int32 timeLeft = _timeLeft / (_engine->getGameId() == GID_NEMESIS ? 1000 : 100);
- if (timeLeft > 0)
- _engine->getScriptManager()->setStateValue(_key, timeLeft); // If timer was stopped by stop or kill
-}
-
-bool TimerNode::process(uint32 deltaTimeInMillis) {
- _timeLeft -= deltaTimeInMillis;
-
- if (_timeLeft <= 0)
- return stop();
-
- return false;
-}
-
-bool TimerNode::stop() {
- if (_key != StateKey_NotSet)
- _engine->getScriptManager()->setStateValue(_key, 2);
- return true;
-}
-
-void TimerNode::serialize(Common::WriteStream *stream) {
- stream->writeUint32BE(MKTAG('T', 'I', 'M', 'R'));
- stream->writeUint32LE(8); // size
- stream->writeUint32LE(_key);
- stream->writeUint32LE(_timeLeft);
-}
-
-void TimerNode::deserialize(Common::SeekableReadStream *stream) {
- _timeLeft = stream->readUint32LE();
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/timer_node.h b/engines/zvision/scripting/sidefx/timer_node.h
deleted file mode 100644
index 7a26aff251..0000000000
--- a/engines/zvision/scripting/sidefx/timer_node.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_TIMER_NODE_H
-#define ZVISION_TIMER_NODE_H
-
-#include "zvision/scripting/sidefx.h"
-
-namespace ZVision {
-
-class ZVision;
-
-class TimerNode : public SideFX {
-public:
- TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
- ~TimerNode();
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
- bool process(uint32 deltaTimeInMillis);
- void serialize(Common::WriteStream *stream);
- void deserialize(Common::SeekableReadStream *stream);
- inline bool needsSerialization() {
- return true;
- }
-
- bool stop();
-
-private:
- int32 _timeLeft;
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/scripting/sidefx/ttytext_node.cpp b/engines/zvision/scripting/sidefx/ttytext_node.cpp
deleted file mode 100644
index 66a27e96c5..0000000000
--- a/engines/zvision/scripting/sidefx/ttytext_node.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/scripting/sidefx/ttytext_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/text/text.h"
-
-#include "common/stream.h"
-#include "common/file.h"
-
-namespace ZVision {
-
-ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay) :
- SideFX(engine, key, SIDEFX_TTYTXT),
- _fnt(engine) {
- _delay = delay;
- _r = r;
- _txtpos = 0;
- _nexttime = 0;
- _dx = 0;
- _dy = 0;
-
- Common::File *infile = _engine->getSearchManager()->openFile(file);
- if (infile) {
- while (!infile->eos()) {
- Common::String asciiLine = readWideLine(*infile);
- if (asciiLine.empty()) {
- continue;
- }
- _txtbuf += asciiLine;
- }
-
- delete infile;
- }
- _img.create(_r.width(), _r.height(), _engine->_resourcePixelFormat);
- _style._sharp = true;
- _style.readAllStyle(_txtbuf);
- _style.setFont(_fnt);
- _engine->getScriptManager()->setStateValue(_key, 1);
-}
-
-ttyTextNode::~ttyTextNode() {
- _engine->getScriptManager()->setStateValue(_key, 2);
- _img.free();
-}
-
-bool ttyTextNode::process(uint32 deltaTimeInMillis) {
- _nexttime -= deltaTimeInMillis;
-
- if (_nexttime < 0) {
- if (_txtpos < _txtbuf.size()) {
- if (_txtbuf[_txtpos] == '<') {
- int32 strt = _txtpos;
- int32 endt = 0;
- int16 ret = 0;
- while (_txtbuf[_txtpos] != '>' && _txtpos < _txtbuf.size())
- _txtpos++;
- endt = _txtpos;
- if (strt != -1)
- if ((endt - strt - 1) > 0)
- ret = _style.parseStyle(_txtbuf.c_str() + strt + 1, endt - strt - 1);
-
- if (ret & (TXT_RET_FNTCHG | TXT_RET_FNTSTL | TXT_RET_NEWLN)) {
- if (ret & TXT_RET_FNTCHG)
- _style.setFont(_fnt);
- if (ret & TXT_RET_FNTSTL)
- _style.setFontStyle(_fnt);
-
- if (ret & TXT_RET_NEWLN)
- newline();
- }
-
- if (ret & TXT_RET_HASSTBOX) {
- Common::String buf;
- buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_style._statebox));
-
- for (uint8 j = 0; j < buf.size(); j++)
- outchar(buf[j]);
- }
-
- _txtpos++;
- } else {
- int8 charsz = getUtf8CharSize(_txtbuf[_txtpos]);
-
- uint16 chr = readUtf8Char(_txtbuf.c_str() + _txtpos);
-
- if (chr == ' ') {
- uint32 i = _txtpos + charsz;
- uint16 width = _fnt.getCharWidth(chr);
-
- while (i < _txtbuf.size() && _txtbuf[i] != ' ' && _txtbuf[i] != '<') {
-
- int8 chsz = getUtf8CharSize(_txtbuf[i]);
- uint16 uchr = readUtf8Char(_txtbuf.c_str() + _txtpos);
-
- width += _fnt.getCharWidth(uchr);
-
- i += chsz;
- }
-
- if (_dx + width > _r.width())
- newline();
- else
- outchar(chr);
- } else
- outchar(chr);
-
- _txtpos += charsz;
- }
- _nexttime = _delay;
- _engine->getRenderManager()->blitSurfaceToBkg(_img, _r.left, _r.top);
- } else
- return stop();
- }
-
- return false;
-}
-
-void ttyTextNode::scroll() {
- int32 scrl = 0;
- while (_dy - scrl > _r.height() - _fnt.getFontHeight())
- scrl += _fnt.getFontHeight();
- int8 *pixels = (int8 *)_img.getPixels();
- for (uint16 h = scrl; h < _img.h; h++)
- memcpy(pixels + _img.pitch * (h - scrl), pixels + _img.pitch * h, _img.pitch);
-
- _img.fillRect(Common::Rect(0, _img.h - scrl, _img.w, _img.h), 0);
- _dy -= scrl;
-}
-
-void ttyTextNode::newline() {
- _dy += _fnt.getFontHeight();
- _dx = 0;
-}
-
-void ttyTextNode::outchar(uint16 chr) {
- uint32 clr = _engine->_resourcePixelFormat.RGBToColor(_style._red, _style._green, _style._blue);
-
- if (_dx + _fnt.getCharWidth(chr) > _r.width())
- newline();
-
- if (_dy + _fnt.getFontHeight() >= _r.height())
- scroll();
-
- _fnt.drawChar(&_img, chr, _dx, _dy, clr);
-
- _dx += _fnt.getCharWidth(chr);
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/ttytext_node.h b/engines/zvision/scripting/sidefx/ttytext_node.h
deleted file mode 100644
index 26d9be8e77..0000000000
--- a/engines/zvision/scripting/sidefx/ttytext_node.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ZVISION_TTYTEXT_NODE_H
-#define ZVISION_TTYTEXT_NODE_H
-
-#include "common/rect.h"
-#include "graphics/surface.h"
-
-#include "zvision/scripting/sidefx.h"
-#include "zvision/text/text.h"
-#include "zvision/text/truetype_font.h"
-
-namespace Common {
-class String;
-}
-
-namespace ZVision {
-class ttyTextNode : public SideFX {
-public:
- ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay);
- ~ttyTextNode();
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
- bool process(uint32 deltaTimeInMillis);
-private:
- Common::Rect _r;
-
- cTxtStyle _style;
- StyledTTFont _fnt;
- Common::String _txtbuf;
- uint32 _txtpos;
-
- int32 _delay;
- int32 _nexttime;
- Graphics::Surface _img;
- int16 _dx;
- int16 _dy;
-private:
-
- void newline();
- void scroll();
- void outchar(uint16 chr);
-};
-
-} // End of namespace ZVision
-
-#endif
--
cgit v1.2.3
From 1f5736a9020796e6986a15ea4d3b627b81233241 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 01:19:54 -0600
Subject: ZVISION: Update function documentation to represent the changes to
the internal pixel format
Aka: We keep everything as 555, and only convert to 565 before we send everything to the backend
---
engines/zvision/graphics/render_manager.h | 6 +-
engines/zvision/zvision.cpp | 720 +++++++++++++++---------------
2 files changed, 362 insertions(+), 364 deletions(-)
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index 9002d66b47..c22f9a78c9 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -277,8 +277,7 @@ public:
void prepareBackground();
/**
- * Reads an image file pixel data into a Surface buffer. In the process
- * it converts the pixel data from RGB 555 to RGB 565. Also, if the image
+ * Reads an image file pixel data into a Surface buffer. Also, if the image
* is transposed, it will un-transpose the pixel data. The function will
* call destination::create() if the dimensions of destination do not match
* up with the dimensions of the image.
@@ -289,8 +288,7 @@ public:
void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination);
/**
- * Reads an image file pixel data into a Surface buffer. In the process
- * it converts the pixel data from RGB 555 to RGB 565. Also, if the image
+ * Reads an image file pixel data into a Surface buffer. Also, if the image
* is transposed, it will un-transpose the pixel data. The function will
* call destination::create() if the dimensions of destination do not match
* up with the dimensions of the image.
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 10e0aaedc4..a70f9d8e39 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -1,361 +1,361 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/zvision.h"
-#include "zvision/core/console.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/cursors/cursor_manager.h"
-#include "zvision/file/save_manager.h"
-#include "zvision/text/string_manager.h"
-#include "zvision/detection.h"
-#include "zvision/scripting/menu.h"
-#include "zvision/file/search_manager.h"
-#include "zvision/text/text.h"
-#include "zvision/text/truetype_font.h"
-#include "zvision/sound/midi.h"
-#include "zvision/file/zfs_archive.h"
-
-#include "common/config-manager.h"
-#include "common/str.h"
-#include "common/debug.h"
-#include "common/debug-channels.h"
-#include "common/textconsole.h"
-#include "common/error.h"
-#include "common/system.h"
-#include "common/file.h"
-
-#include "gui/message.h"
-#include "engines/util.h"
-#include "audio/mixer.h"
-
-namespace ZVision {
-
-#define ZVISION_SETTINGS_KEYS_COUNT 11
-
-struct zvisionIniSettings {
- const char *name;
- int16 slot;
- int16 defaultValue; // -1: use the bool value
- bool defaultBoolValue;
- bool allowEditing;
-} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
- // Hardcoded settings
- {"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, subtitles are shown for codes 0 - 4, unused
- {"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
- {"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, checked by universe.scr
- {"highquality", StateKey_HighQuality, -1, true, false}, // high panorama quality, unused
- {"qsoundenabled", StateKey_Qsound, -1, true, false}, // 1 = enable QSound - TODO: not supported yet
- {"debugcheats", StateKey_DebugCheats, -1, true, false}, // always start with the GOxxxx cheat enabled
- // Editable settings
- {"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
- {"panarotatespeed", StateKey_RotateSpeed, 540, false, true}, // checked by universe.scr
- {"noanimwhileturning", StateKey_NoTurnAnim, -1, false, true}, // toggle playing animations during pana rotation
- {"venusenabled", StateKey_VenusEnable, -1, true, true},
- {"subtitles", StateKey_Subtitles, -1, true, true}
-};
-
-ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
- : Engine(syst),
- _gameDescription(gameDesc),
- _resourcePixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /* RGB 555 */
- _screenPixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /* RGB 565 */
- _desiredFrameTime(33), /* ~30 fps */
- _clock(_system),
- _scriptManager(nullptr),
- _renderManager(nullptr),
- _saveManager(nullptr),
- _stringManager(nullptr),
- _cursorManager(nullptr),
- _midiManager(nullptr),
- _rnd(nullptr),
- _console(nullptr),
- _menu(nullptr),
- _searchManager(nullptr),
- _textRenderer(nullptr),
- _doubleFPS(false),
- _audioId(0),
- _frameRenderDelay(2),
- _keyboardVelocity(0),
- _mouseVelocity(0),
- _videoIsPlaying(false),
- _renderedFrameCount(0),
- _fps(0) {
-
- debug(1, "ZVision::ZVision");
-
- uint16 workingWindowWidth = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_WIDTH : ZGI_WORKING_WINDOW_WIDTH;
- uint16 workingWindowHeight = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_HEIGHT : ZGI_WORKING_WINDOW_HEIGHT;
- _workingWindow = Common::Rect(
- (WINDOW_WIDTH - workingWindowWidth) / 2,
- (WINDOW_HEIGHT - workingWindowHeight) / 2,
- ((WINDOW_WIDTH - workingWindowWidth) / 2) + workingWindowWidth,
- ((WINDOW_HEIGHT - workingWindowHeight) / 2) + workingWindowHeight
- );
-
- memset(_cheatBuffer, 0, sizeof(_cheatBuffer));
-}
-
-ZVision::~ZVision() {
- debug(1, "ZVision::~ZVision");
-
- // Dispose of resources
- delete _console;
- delete _cursorManager;
- delete _stringManager;
- delete _saveManager;
- delete _scriptManager;
- delete _renderManager; // should be deleted after the script manager
- delete _rnd;
- delete _midiManager;
-
- getTimerManager()->removeTimerProc(&fpsTimerCallback);
-
- // Remove all of our debug levels
- DebugMan.clearAllDebugChannels();
-}
-
-void ZVision::registerDefaultSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
- if (settingsKeys[i].allowEditing) {
- if (settingsKeys[i].defaultValue >= 0)
- ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultValue);
- else
- ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultBoolValue);
- }
- }
-
- ConfMan.registerDefault("originalsaveload", false);
- ConfMan.registerDefault("doublefps", false);
-}
-
-void ZVision::loadSettings() {
- int16 value = 0;
- bool boolValue = false;
-
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
- if (settingsKeys[i].defaultValue >= 0) {
- value = (settingsKeys[i].allowEditing) ? ConfMan.getInt(settingsKeys[i].name) : settingsKeys[i].defaultValue;
- } else {
- boolValue = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
- value = (boolValue) ? 1 : 0;
- }
-
- _scriptManager->setStateValue(settingsKeys[i].slot, value);
- }
-
- if (getGameId() == GID_NEMESIS)
- _scriptManager->setStateValue(StateKey_ExecScopeStyle, 1);
- else
- _scriptManager->setStateValue(StateKey_ExecScopeStyle, 0);
-}
-
-void ZVision::saveSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
- if (settingsKeys[i].allowEditing) {
- if (settingsKeys[i].defaultValue >= 0)
- ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
- else
- ConfMan.setBool(settingsKeys[i].name, (_scriptManager->getStateValue(settingsKeys[i].slot) == 1));
- }
- }
-
- ConfMan.flushToDisk();
-}
-
-void ZVision::initialize() {
- const Common::FSNode gameDataDir(ConfMan.get("path"));
-
- _searchManager = new SearchManager(ConfMan.get("path"), 6);
-
- _searchManager->addDir("FONTS");
- _searchManager->addDir("addon");
-
- if (_gameDescription->gameId == GID_GRANDINQUISITOR) {
- _searchManager->loadZix("INQUIS.ZIX");
- _searchManager->addPatch("C000H01Q.RAW", "C000H01Q.SRC");
- _searchManager->addPatch("CM00H01Q.RAW", "CM00H01Q.SRC");
- _searchManager->addPatch("DM00H01Q.RAW", "DM00H01Q.SRC");
- _searchManager->addPatch("E000H01Q.RAW", "E000H01Q.SRC");
- _searchManager->addPatch("EM00H50Q.RAW", "EM00H50Q.SRC");
- _searchManager->addPatch("GJNPH65P.RAW", "GJNPH65P.SRC");
- _searchManager->addPatch("GJNPH72P.RAW", "GJNPH72P.SRC");
- _searchManager->addPatch("H000H01Q.RAW", "H000H01Q.SRC");
- _searchManager->addPatch("M000H01Q.RAW", "M000H01Q.SRC");
- _searchManager->addPatch("P000H01Q.RAW", "P000H01Q.SRC");
- _searchManager->addPatch("Q000H01Q.RAW", "Q000H01Q.SRC");
- _searchManager->addPatch("SW00H01Q.RAW", "SW00H01Q.SRC");
- _searchManager->addPatch("T000H01Q.RAW", "T000H01Q.SRC");
- _searchManager->addPatch("U000H01Q.RAW", "U000H01Q.SRC");
- } else if (_gameDescription->gameId == GID_NEMESIS)
- _searchManager->loadZix("NEMESIS.ZIX");
-
- initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
-
- // Register random source
- _rnd = new Common::RandomSource("zvision");
-
- // Create managers
- _scriptManager = new ScriptManager(this);
- _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat, _doubleFPS);
- _saveManager = new SaveManager(this);
- _stringManager = new StringManager(this);
- _cursorManager = new CursorManager(this, _resourcePixelFormat);
- _textRenderer = new TextRenderer(this);
- _midiManager = new MidiManager();
-
- if (_gameDescription->gameId == GID_GRANDINQUISITOR)
- _menu = new MenuZGI(this);
- else
- _menu = new MenuNemesis(this);
-
- // Initialize the managers
- _cursorManager->initialize();
- _scriptManager->initialize();
- _stringManager->initialize(_gameDescription->gameId);
-
- registerDefaultSettings();
-
- loadSettings();
-
- // Create debugger console. It requires GFX to be initialized
- _console = new Console(this);
- _doubleFPS = ConfMan.getBool("doublefps");
-
- // Initialize FPS timer callback
- getTimerManager()->installTimerProc(&fpsTimerCallback, 1000000, this, "zvisionFPS");
-}
-
-Common::Error ZVision::run() {
- initialize();
-
- // Check if a saved game is to be loaded from the launcher
- if (ConfMan.hasKey("save_slot"))
- _saveManager->loadGame(ConfMan.getInt("save_slot"));
-
- // Before starting, make absolutely sure that the user has copied the needed fonts
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/zvision.h"
+#include "zvision/core/console.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/text/string_manager.h"
+#include "zvision/detection.h"
+#include "zvision/scripting/menu.h"
+#include "zvision/file/search_manager.h"
+#include "zvision/text/text.h"
+#include "zvision/text/truetype_font.h"
+#include "zvision/sound/midi.h"
+#include "zvision/file/zfs_archive.h"
+
+#include "common/config-manager.h"
+#include "common/str.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/textconsole.h"
+#include "common/error.h"
+#include "common/system.h"
+#include "common/file.h"
+
+#include "gui/message.h"
+#include "engines/util.h"
+#include "audio/mixer.h"
+
+namespace ZVision {
+
+#define ZVISION_SETTINGS_KEYS_COUNT 11
+
+struct zvisionIniSettings {
+ const char *name;
+ int16 slot;
+ int16 defaultValue; // -1: use the bool value
+ bool defaultBoolValue;
+ bool allowEditing;
+} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
+ // Hardcoded settings
+ {"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, subtitles are shown for codes 0 - 4, unused
+ {"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
+ {"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, checked by universe.scr
+ {"highquality", StateKey_HighQuality, -1, true, false}, // high panorama quality, unused
+ {"qsoundenabled", StateKey_Qsound, -1, true, false}, // 1 = enable QSound - TODO: not supported yet
+ {"debugcheats", StateKey_DebugCheats, -1, true, false}, // always start with the GOxxxx cheat enabled
+ // Editable settings
+ {"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
+ {"panarotatespeed", StateKey_RotateSpeed, 540, false, true}, // checked by universe.scr
+ {"noanimwhileturning", StateKey_NoTurnAnim, -1, false, true}, // toggle playing animations during pana rotation
+ {"venusenabled", StateKey_VenusEnable, -1, true, true},
+ {"subtitles", StateKey_Subtitles, -1, true, true}
+};
+
+ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
+ : Engine(syst),
+ _gameDescription(gameDesc),
+ _resourcePixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /* RGB 555 */
+ _screenPixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /* RGB 565 */
+ _desiredFrameTime(33), /* ~30 fps */
+ _clock(_system),
+ _scriptManager(nullptr),
+ _renderManager(nullptr),
+ _saveManager(nullptr),
+ _stringManager(nullptr),
+ _cursorManager(nullptr),
+ _midiManager(nullptr),
+ _rnd(nullptr),
+ _console(nullptr),
+ _menu(nullptr),
+ _searchManager(nullptr),
+ _textRenderer(nullptr),
+ _doubleFPS(false),
+ _audioId(0),
+ _frameRenderDelay(2),
+ _keyboardVelocity(0),
+ _mouseVelocity(0),
+ _videoIsPlaying(false),
+ _renderedFrameCount(0),
+ _fps(0) {
+
+ debug(1, "ZVision::ZVision");
+
+ uint16 workingWindowWidth = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_WIDTH : ZGI_WORKING_WINDOW_WIDTH;
+ uint16 workingWindowHeight = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_HEIGHT : ZGI_WORKING_WINDOW_HEIGHT;
+ _workingWindow = Common::Rect(
+ (WINDOW_WIDTH - workingWindowWidth) / 2,
+ (WINDOW_HEIGHT - workingWindowHeight) / 2,
+ ((WINDOW_WIDTH - workingWindowWidth) / 2) + workingWindowWidth,
+ ((WINDOW_HEIGHT - workingWindowHeight) / 2) + workingWindowHeight
+ );
+
+ memset(_cheatBuffer, 0, sizeof(_cheatBuffer));
+}
+
+ZVision::~ZVision() {
+ debug(1, "ZVision::~ZVision");
+
+ // Dispose of resources
+ delete _console;
+ delete _cursorManager;
+ delete _stringManager;
+ delete _saveManager;
+ delete _scriptManager;
+ delete _renderManager; // should be deleted after the script manager
+ delete _rnd;
+ delete _midiManager;
+
+ getTimerManager()->removeTimerProc(&fpsTimerCallback);
+
+ // Remove all of our debug levels
+ DebugMan.clearAllDebugChannels();
+}
+
+void ZVision::registerDefaultSettings() {
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultValue);
+ else
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultBoolValue);
+ }
+ }
+
+ ConfMan.registerDefault("originalsaveload", false);
+ ConfMan.registerDefault("doublefps", false);
+}
+
+void ZVision::loadSettings() {
+ int16 value = 0;
+ bool boolValue = false;
+
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].defaultValue >= 0) {
+ value = (settingsKeys[i].allowEditing) ? ConfMan.getInt(settingsKeys[i].name) : settingsKeys[i].defaultValue;
+ } else {
+ boolValue = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
+ value = (boolValue) ? 1 : 0;
+ }
+
+ _scriptManager->setStateValue(settingsKeys[i].slot, value);
+ }
+
+ if (getGameId() == GID_NEMESIS)
+ _scriptManager->setStateValue(StateKey_ExecScopeStyle, 1);
+ else
+ _scriptManager->setStateValue(StateKey_ExecScopeStyle, 0);
+}
+
+void ZVision::saveSettings() {
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
+ else
+ ConfMan.setBool(settingsKeys[i].name, (_scriptManager->getStateValue(settingsKeys[i].slot) == 1));
+ }
+ }
+
+ ConfMan.flushToDisk();
+}
+
+void ZVision::initialize() {
+ const Common::FSNode gameDataDir(ConfMan.get("path"));
+
+ _searchManager = new SearchManager(ConfMan.get("path"), 6);
+
+ _searchManager->addDir("FONTS");
+ _searchManager->addDir("addon");
+
+ if (_gameDescription->gameId == GID_GRANDINQUISITOR) {
+ _searchManager->loadZix("INQUIS.ZIX");
+ _searchManager->addPatch("C000H01Q.RAW", "C000H01Q.SRC");
+ _searchManager->addPatch("CM00H01Q.RAW", "CM00H01Q.SRC");
+ _searchManager->addPatch("DM00H01Q.RAW", "DM00H01Q.SRC");
+ _searchManager->addPatch("E000H01Q.RAW", "E000H01Q.SRC");
+ _searchManager->addPatch("EM00H50Q.RAW", "EM00H50Q.SRC");
+ _searchManager->addPatch("GJNPH65P.RAW", "GJNPH65P.SRC");
+ _searchManager->addPatch("GJNPH72P.RAW", "GJNPH72P.SRC");
+ _searchManager->addPatch("H000H01Q.RAW", "H000H01Q.SRC");
+ _searchManager->addPatch("M000H01Q.RAW", "M000H01Q.SRC");
+ _searchManager->addPatch("P000H01Q.RAW", "P000H01Q.SRC");
+ _searchManager->addPatch("Q000H01Q.RAW", "Q000H01Q.SRC");
+ _searchManager->addPatch("SW00H01Q.RAW", "SW00H01Q.SRC");
+ _searchManager->addPatch("T000H01Q.RAW", "T000H01Q.SRC");
+ _searchManager->addPatch("U000H01Q.RAW", "U000H01Q.SRC");
+ } else if (_gameDescription->gameId == GID_NEMESIS)
+ _searchManager->loadZix("NEMESIS.ZIX");
+
+ initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
+
+ // Register random source
+ _rnd = new Common::RandomSource("zvision");
+
+ // Create managers
+ _scriptManager = new ScriptManager(this);
+ _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat, _doubleFPS);
+ _saveManager = new SaveManager(this);
+ _stringManager = new StringManager(this);
+ _cursorManager = new CursorManager(this, _resourcePixelFormat);
+ _textRenderer = new TextRenderer(this);
+ _midiManager = new MidiManager();
+
+ if (_gameDescription->gameId == GID_GRANDINQUISITOR)
+ _menu = new MenuZGI(this);
+ else
+ _menu = new MenuNemesis(this);
+
+ // Initialize the managers
+ _cursorManager->initialize();
+ _scriptManager->initialize();
+ _stringManager->initialize(_gameDescription->gameId);
+
+ registerDefaultSettings();
+
+ loadSettings();
+
+ // Create debugger console. It requires GFX to be initialized
+ _console = new Console(this);
+ _doubleFPS = ConfMan.getBool("doublefps");
+
+ // Initialize FPS timer callback
+ getTimerManager()->installTimerProc(&fpsTimerCallback, 1000000, this, "zvisionFPS");
+}
+
+Common::Error ZVision::run() {
+ initialize();
+
+ // Check if a saved game is to be loaded from the launcher
+ if (ConfMan.hasKey("save_slot"))
+ _saveManager->loadGame(ConfMan.getInt("save_slot"));
+
+ // Before starting, make absolutely sure that the user has copied the needed fonts
if (!Common::File::exists("arial.ttf") && !Common::File::exists("FreeSans.ttf") && !_searchManager->hasFile("arial.ttf") && !_searchManager->hasFile("FreeSans.ttf") ) {
- GUI::MessageDialog dialog(
- "Before playing this game, you'll need to copy the required "
- "fonts into ScummVM's extras directory, or into the game directory. "
- "On Windows, you'll need the following font files from the Windows "
- "font directory: Times New Roman, Century Schoolbook, Garamond, "
- "Courier New and Arial. Alternatively, you can download the GNU "
- "FreeFont package. You'll need all the fonts from that package, "
- "i.e., FreeMono, FreeSans and FreeSerif."
- );
- dialog.runModal();
- quitGame();
- return Common::kUnknownError;
- }
-
- // Main loop
- while (!shouldQuit()) {
- _clock.update();
- uint32 currentTime = _clock.getLastMeasuredTime();
- uint32 deltaTime = _clock.getDeltaTime();
-
- _cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem));
-
- processEvents();
- _renderManager->updateRotation();
-
- _scriptManager->update(deltaTime);
- _menu->process(deltaTime);
-
- // Render the backBuffer to the screen
- _renderManager->prepareBackground();
- _renderManager->renderMenuToScreen();
- _renderManager->processSubs(deltaTime);
- _renderManager->renderSceneToScreen();
-
- // Update the screen
- if (canRender()) {
- _system->updateScreen();
- _renderedFrameCount++;
- } else {
- _frameRenderDelay--;
- }
-
- // Calculate the frame delay based off a desired frame time
- int delay = _desiredFrameTime - int32(_system->getMillis() - currentTime);
- // Ensure non-negative
- delay = delay < 0 ? 0 : delay;
-
- if (_doubleFPS) {
- delay >>= 1;
- }
-
- if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) {
- _saveManager->autoSave();
- }
-
- _system->delayMillis(delay);
- }
-
- return Common::kNoError;
-}
-
-void ZVision::pauseEngineIntern(bool pause) {
- _mixer->pauseAll(pause);
-
- if (pause) {
- _clock.stop();
- } else {
- _clock.start();
- }
-}
-
-Common::String ZVision::generateSaveFileName(uint slot) {
- return Common::String::format("%s.%03u", _targetName.c_str(), slot);
-}
-
-void ZVision::setRenderDelay(uint delay) {
- _frameRenderDelay = delay;
-}
-
-bool ZVision::canRender() {
- return _frameRenderDelay <= 0;
-}
-
-GUI::Debugger *ZVision::getDebugger() {
- return _console;
-}
-
-void ZVision::syncSoundSettings() {
- Engine::syncSoundSettings();
-
- _scriptManager->setStateValue(StateKey_Subtitles, ConfMan.getBool("subtitles") ? 1 : 0);
-}
-
-void ZVision::fpsTimerCallback(void *refCon) {
- ((ZVision *)refCon)->fpsTimer();
-}
-
-void ZVision::fpsTimer() {
- _fps = _renderedFrameCount;
- _renderedFrameCount = 0;
-}
-
-} // End of namespace ZVision
+ GUI::MessageDialog dialog(
+ "Before playing this game, you'll need to copy the required "
+ "fonts into ScummVM's extras directory, or into the game directory. "
+ "On Windows, you'll need the following font files from the Windows "
+ "font directory: Times New Roman, Century Schoolbook, Garamond, "
+ "Courier New and Arial. Alternatively, you can download the GNU "
+ "FreeFont package. You'll need all the fonts from that package, "
+ "i.e., FreeMono, FreeSans and FreeSerif."
+ );
+ dialog.runModal();
+ quitGame();
+ return Common::kUnknownError;
+ }
+
+ // Main loop
+ while (!shouldQuit()) {
+ _clock.update();
+ uint32 currentTime = _clock.getLastMeasuredTime();
+ uint32 deltaTime = _clock.getDeltaTime();
+
+ _cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem));
+
+ processEvents();
+ _renderManager->updateRotation();
+
+ _scriptManager->update(deltaTime);
+ _menu->process(deltaTime);
+
+ // Render the backBuffer to the screen
+ _renderManager->prepareBackground();
+ _renderManager->renderMenuToScreen();
+ _renderManager->processSubs(deltaTime);
+ _renderManager->renderSceneToScreen();
+
+ // Update the screen
+ if (canRender()) {
+ _system->updateScreen();
+ _renderedFrameCount++;
+ } else {
+ _frameRenderDelay--;
+ }
+
+ // Calculate the frame delay based off a desired frame time
+ int delay = _desiredFrameTime - int32(_system->getMillis() - currentTime);
+ // Ensure non-negative
+ delay = delay < 0 ? 0 : delay;
+
+ if (_doubleFPS) {
+ delay >>= 1;
+ }
+
+ if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) {
+ _saveManager->autoSave();
+ }
+
+ _system->delayMillis(delay);
+ }
+
+ return Common::kNoError;
+}
+
+void ZVision::pauseEngineIntern(bool pause) {
+ _mixer->pauseAll(pause);
+
+ if (pause) {
+ _clock.stop();
+ } else {
+ _clock.start();
+ }
+}
+
+Common::String ZVision::generateSaveFileName(uint slot) {
+ return Common::String::format("%s.%03u", _targetName.c_str(), slot);
+}
+
+void ZVision::setRenderDelay(uint delay) {
+ _frameRenderDelay = delay;
+}
+
+bool ZVision::canRender() {
+ return _frameRenderDelay <= 0;
+}
+
+GUI::Debugger *ZVision::getDebugger() {
+ return _console;
+}
+
+void ZVision::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _scriptManager->setStateValue(StateKey_Subtitles, ConfMan.getBool("subtitles") ? 1 : 0);
+}
+
+void ZVision::fpsTimerCallback(void *refCon) {
+ ((ZVision *)refCon)->fpsTimer();
+}
+
+void ZVision::fpsTimer() {
+ _fps = _renderedFrameCount;
+ _renderedFrameCount = 0;
+}
+
+} // End of namespace ZVision
--
cgit v1.2.3
From df605069552d680e203b7e16f3bcd0fb31825c2c Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 01:51:22 -0600
Subject: ZVISION: Restore LF line ending that was accidentally changed in
1f5736a9020796e6986a15ea4d3b627b81233241
---
engines/zvision/zvision.cpp | 722 ++++++++++++++++++++++----------------------
1 file changed, 361 insertions(+), 361 deletions(-)
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index a70f9d8e39..54991aced3 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -1,361 +1,361 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-
-#include "zvision/zvision.h"
-#include "zvision/core/console.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/cursors/cursor_manager.h"
-#include "zvision/file/save_manager.h"
-#include "zvision/text/string_manager.h"
-#include "zvision/detection.h"
-#include "zvision/scripting/menu.h"
-#include "zvision/file/search_manager.h"
-#include "zvision/text/text.h"
-#include "zvision/text/truetype_font.h"
-#include "zvision/sound/midi.h"
-#include "zvision/file/zfs_archive.h"
-
-#include "common/config-manager.h"
-#include "common/str.h"
-#include "common/debug.h"
-#include "common/debug-channels.h"
-#include "common/textconsole.h"
-#include "common/error.h"
-#include "common/system.h"
-#include "common/file.h"
-
-#include "gui/message.h"
-#include "engines/util.h"
-#include "audio/mixer.h"
-
-namespace ZVision {
-
-#define ZVISION_SETTINGS_KEYS_COUNT 11
-
-struct zvisionIniSettings {
- const char *name;
- int16 slot;
- int16 defaultValue; // -1: use the bool value
- bool defaultBoolValue;
- bool allowEditing;
-} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
- // Hardcoded settings
- {"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, subtitles are shown for codes 0 - 4, unused
- {"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
- {"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, checked by universe.scr
- {"highquality", StateKey_HighQuality, -1, true, false}, // high panorama quality, unused
- {"qsoundenabled", StateKey_Qsound, -1, true, false}, // 1 = enable QSound - TODO: not supported yet
- {"debugcheats", StateKey_DebugCheats, -1, true, false}, // always start with the GOxxxx cheat enabled
- // Editable settings
- {"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
- {"panarotatespeed", StateKey_RotateSpeed, 540, false, true}, // checked by universe.scr
- {"noanimwhileturning", StateKey_NoTurnAnim, -1, false, true}, // toggle playing animations during pana rotation
- {"venusenabled", StateKey_VenusEnable, -1, true, true},
- {"subtitles", StateKey_Subtitles, -1, true, true}
-};
-
-ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
- : Engine(syst),
- _gameDescription(gameDesc),
- _resourcePixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /* RGB 555 */
- _screenPixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /* RGB 565 */
- _desiredFrameTime(33), /* ~30 fps */
- _clock(_system),
- _scriptManager(nullptr),
- _renderManager(nullptr),
- _saveManager(nullptr),
- _stringManager(nullptr),
- _cursorManager(nullptr),
- _midiManager(nullptr),
- _rnd(nullptr),
- _console(nullptr),
- _menu(nullptr),
- _searchManager(nullptr),
- _textRenderer(nullptr),
- _doubleFPS(false),
- _audioId(0),
- _frameRenderDelay(2),
- _keyboardVelocity(0),
- _mouseVelocity(0),
- _videoIsPlaying(false),
- _renderedFrameCount(0),
- _fps(0) {
-
- debug(1, "ZVision::ZVision");
-
- uint16 workingWindowWidth = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_WIDTH : ZGI_WORKING_WINDOW_WIDTH;
- uint16 workingWindowHeight = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_HEIGHT : ZGI_WORKING_WINDOW_HEIGHT;
- _workingWindow = Common::Rect(
- (WINDOW_WIDTH - workingWindowWidth) / 2,
- (WINDOW_HEIGHT - workingWindowHeight) / 2,
- ((WINDOW_WIDTH - workingWindowWidth) / 2) + workingWindowWidth,
- ((WINDOW_HEIGHT - workingWindowHeight) / 2) + workingWindowHeight
- );
-
- memset(_cheatBuffer, 0, sizeof(_cheatBuffer));
-}
-
-ZVision::~ZVision() {
- debug(1, "ZVision::~ZVision");
-
- // Dispose of resources
- delete _console;
- delete _cursorManager;
- delete _stringManager;
- delete _saveManager;
- delete _scriptManager;
- delete _renderManager; // should be deleted after the script manager
- delete _rnd;
- delete _midiManager;
-
- getTimerManager()->removeTimerProc(&fpsTimerCallback);
-
- // Remove all of our debug levels
- DebugMan.clearAllDebugChannels();
-}
-
-void ZVision::registerDefaultSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
- if (settingsKeys[i].allowEditing) {
- if (settingsKeys[i].defaultValue >= 0)
- ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultValue);
- else
- ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultBoolValue);
- }
- }
-
- ConfMan.registerDefault("originalsaveload", false);
- ConfMan.registerDefault("doublefps", false);
-}
-
-void ZVision::loadSettings() {
- int16 value = 0;
- bool boolValue = false;
-
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
- if (settingsKeys[i].defaultValue >= 0) {
- value = (settingsKeys[i].allowEditing) ? ConfMan.getInt(settingsKeys[i].name) : settingsKeys[i].defaultValue;
- } else {
- boolValue = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
- value = (boolValue) ? 1 : 0;
- }
-
- _scriptManager->setStateValue(settingsKeys[i].slot, value);
- }
-
- if (getGameId() == GID_NEMESIS)
- _scriptManager->setStateValue(StateKey_ExecScopeStyle, 1);
- else
- _scriptManager->setStateValue(StateKey_ExecScopeStyle, 0);
-}
-
-void ZVision::saveSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
- if (settingsKeys[i].allowEditing) {
- if (settingsKeys[i].defaultValue >= 0)
- ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
- else
- ConfMan.setBool(settingsKeys[i].name, (_scriptManager->getStateValue(settingsKeys[i].slot) == 1));
- }
- }
-
- ConfMan.flushToDisk();
-}
-
-void ZVision::initialize() {
- const Common::FSNode gameDataDir(ConfMan.get("path"));
-
- _searchManager = new SearchManager(ConfMan.get("path"), 6);
-
- _searchManager->addDir("FONTS");
- _searchManager->addDir("addon");
-
- if (_gameDescription->gameId == GID_GRANDINQUISITOR) {
- _searchManager->loadZix("INQUIS.ZIX");
- _searchManager->addPatch("C000H01Q.RAW", "C000H01Q.SRC");
- _searchManager->addPatch("CM00H01Q.RAW", "CM00H01Q.SRC");
- _searchManager->addPatch("DM00H01Q.RAW", "DM00H01Q.SRC");
- _searchManager->addPatch("E000H01Q.RAW", "E000H01Q.SRC");
- _searchManager->addPatch("EM00H50Q.RAW", "EM00H50Q.SRC");
- _searchManager->addPatch("GJNPH65P.RAW", "GJNPH65P.SRC");
- _searchManager->addPatch("GJNPH72P.RAW", "GJNPH72P.SRC");
- _searchManager->addPatch("H000H01Q.RAW", "H000H01Q.SRC");
- _searchManager->addPatch("M000H01Q.RAW", "M000H01Q.SRC");
- _searchManager->addPatch("P000H01Q.RAW", "P000H01Q.SRC");
- _searchManager->addPatch("Q000H01Q.RAW", "Q000H01Q.SRC");
- _searchManager->addPatch("SW00H01Q.RAW", "SW00H01Q.SRC");
- _searchManager->addPatch("T000H01Q.RAW", "T000H01Q.SRC");
- _searchManager->addPatch("U000H01Q.RAW", "U000H01Q.SRC");
- } else if (_gameDescription->gameId == GID_NEMESIS)
- _searchManager->loadZix("NEMESIS.ZIX");
-
- initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
-
- // Register random source
- _rnd = new Common::RandomSource("zvision");
-
- // Create managers
- _scriptManager = new ScriptManager(this);
- _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat, _doubleFPS);
- _saveManager = new SaveManager(this);
- _stringManager = new StringManager(this);
- _cursorManager = new CursorManager(this, _resourcePixelFormat);
- _textRenderer = new TextRenderer(this);
- _midiManager = new MidiManager();
-
- if (_gameDescription->gameId == GID_GRANDINQUISITOR)
- _menu = new MenuZGI(this);
- else
- _menu = new MenuNemesis(this);
-
- // Initialize the managers
- _cursorManager->initialize();
- _scriptManager->initialize();
- _stringManager->initialize(_gameDescription->gameId);
-
- registerDefaultSettings();
-
- loadSettings();
-
- // Create debugger console. It requires GFX to be initialized
- _console = new Console(this);
- _doubleFPS = ConfMan.getBool("doublefps");
-
- // Initialize FPS timer callback
- getTimerManager()->installTimerProc(&fpsTimerCallback, 1000000, this, "zvisionFPS");
-}
-
-Common::Error ZVision::run() {
- initialize();
-
- // Check if a saved game is to be loaded from the launcher
- if (ConfMan.hasKey("save_slot"))
- _saveManager->loadGame(ConfMan.getInt("save_slot"));
-
- // Before starting, make absolutely sure that the user has copied the needed fonts
- if (!Common::File::exists("arial.ttf") && !Common::File::exists("FreeSans.ttf") && !_searchManager->hasFile("arial.ttf") && !_searchManager->hasFile("FreeSans.ttf") ) {
- GUI::MessageDialog dialog(
- "Before playing this game, you'll need to copy the required "
- "fonts into ScummVM's extras directory, or into the game directory. "
- "On Windows, you'll need the following font files from the Windows "
- "font directory: Times New Roman, Century Schoolbook, Garamond, "
- "Courier New and Arial. Alternatively, you can download the GNU "
- "FreeFont package. You'll need all the fonts from that package, "
- "i.e., FreeMono, FreeSans and FreeSerif."
- );
- dialog.runModal();
- quitGame();
- return Common::kUnknownError;
- }
-
- // Main loop
- while (!shouldQuit()) {
- _clock.update();
- uint32 currentTime = _clock.getLastMeasuredTime();
- uint32 deltaTime = _clock.getDeltaTime();
-
- _cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem));
-
- processEvents();
- _renderManager->updateRotation();
-
- _scriptManager->update(deltaTime);
- _menu->process(deltaTime);
-
- // Render the backBuffer to the screen
- _renderManager->prepareBackground();
- _renderManager->renderMenuToScreen();
- _renderManager->processSubs(deltaTime);
- _renderManager->renderSceneToScreen();
-
- // Update the screen
- if (canRender()) {
- _system->updateScreen();
- _renderedFrameCount++;
- } else {
- _frameRenderDelay--;
- }
-
- // Calculate the frame delay based off a desired frame time
- int delay = _desiredFrameTime - int32(_system->getMillis() - currentTime);
- // Ensure non-negative
- delay = delay < 0 ? 0 : delay;
-
- if (_doubleFPS) {
- delay >>= 1;
- }
-
- if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) {
- _saveManager->autoSave();
- }
-
- _system->delayMillis(delay);
- }
-
- return Common::kNoError;
-}
-
-void ZVision::pauseEngineIntern(bool pause) {
- _mixer->pauseAll(pause);
-
- if (pause) {
- _clock.stop();
- } else {
- _clock.start();
- }
-}
-
-Common::String ZVision::generateSaveFileName(uint slot) {
- return Common::String::format("%s.%03u", _targetName.c_str(), slot);
-}
-
-void ZVision::setRenderDelay(uint delay) {
- _frameRenderDelay = delay;
-}
-
-bool ZVision::canRender() {
- return _frameRenderDelay <= 0;
-}
-
-GUI::Debugger *ZVision::getDebugger() {
- return _console;
-}
-
-void ZVision::syncSoundSettings() {
- Engine::syncSoundSettings();
-
- _scriptManager->setStateValue(StateKey_Subtitles, ConfMan.getBool("subtitles") ? 1 : 0);
-}
-
-void ZVision::fpsTimerCallback(void *refCon) {
- ((ZVision *)refCon)->fpsTimer();
-}
-
-void ZVision::fpsTimer() {
- _fps = _renderedFrameCount;
- _renderedFrameCount = 0;
-}
-
-} // End of namespace ZVision
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/zvision.h"
+#include "zvision/core/console.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/text/string_manager.h"
+#include "zvision/detection.h"
+#include "zvision/scripting/menu.h"
+#include "zvision/file/search_manager.h"
+#include "zvision/text/text.h"
+#include "zvision/text/truetype_font.h"
+#include "zvision/sound/midi.h"
+#include "zvision/file/zfs_archive.h"
+
+#include "common/config-manager.h"
+#include "common/str.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/textconsole.h"
+#include "common/error.h"
+#include "common/system.h"
+#include "common/file.h"
+
+#include "gui/message.h"
+#include "engines/util.h"
+#include "audio/mixer.h"
+
+namespace ZVision {
+
+#define ZVISION_SETTINGS_KEYS_COUNT 11
+
+struct zvisionIniSettings {
+ const char *name;
+ int16 slot;
+ int16 defaultValue; // -1: use the bool value
+ bool defaultBoolValue;
+ bool allowEditing;
+} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
+ // Hardcoded settings
+ {"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, subtitles are shown for codes 0 - 4, unused
+ {"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
+ {"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, checked by universe.scr
+ {"highquality", StateKey_HighQuality, -1, true, false}, // high panorama quality, unused
+ {"qsoundenabled", StateKey_Qsound, -1, true, false}, // 1 = enable QSound - TODO: not supported yet
+ {"debugcheats", StateKey_DebugCheats, -1, true, false}, // always start with the GOxxxx cheat enabled
+ // Editable settings
+ {"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
+ {"panarotatespeed", StateKey_RotateSpeed, 540, false, true}, // checked by universe.scr
+ {"noanimwhileturning", StateKey_NoTurnAnim, -1, false, true}, // toggle playing animations during pana rotation
+ {"venusenabled", StateKey_VenusEnable, -1, true, true},
+ {"subtitles", StateKey_Subtitles, -1, true, true}
+};
+
+ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
+ : Engine(syst),
+ _gameDescription(gameDesc),
+ _resourcePixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /* RGB 555 */
+ _screenPixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /* RGB 565 */
+ _desiredFrameTime(33), /* ~30 fps */
+ _clock(_system),
+ _scriptManager(nullptr),
+ _renderManager(nullptr),
+ _saveManager(nullptr),
+ _stringManager(nullptr),
+ _cursorManager(nullptr),
+ _midiManager(nullptr),
+ _rnd(nullptr),
+ _console(nullptr),
+ _menu(nullptr),
+ _searchManager(nullptr),
+ _textRenderer(nullptr),
+ _doubleFPS(false),
+ _audioId(0),
+ _frameRenderDelay(2),
+ _keyboardVelocity(0),
+ _mouseVelocity(0),
+ _videoIsPlaying(false),
+ _renderedFrameCount(0),
+ _fps(0) {
+
+ debug(1, "ZVision::ZVision");
+
+ uint16 workingWindowWidth = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_WIDTH : ZGI_WORKING_WINDOW_WIDTH;
+ uint16 workingWindowHeight = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_HEIGHT : ZGI_WORKING_WINDOW_HEIGHT;
+ _workingWindow = Common::Rect(
+ (WINDOW_WIDTH - workingWindowWidth) / 2,
+ (WINDOW_HEIGHT - workingWindowHeight) / 2,
+ ((WINDOW_WIDTH - workingWindowWidth) / 2) + workingWindowWidth,
+ ((WINDOW_HEIGHT - workingWindowHeight) / 2) + workingWindowHeight
+ );
+
+ memset(_cheatBuffer, 0, sizeof(_cheatBuffer));
+}
+
+ZVision::~ZVision() {
+ debug(1, "ZVision::~ZVision");
+
+ // Dispose of resources
+ delete _console;
+ delete _cursorManager;
+ delete _stringManager;
+ delete _saveManager;
+ delete _scriptManager;
+ delete _renderManager; // should be deleted after the script manager
+ delete _rnd;
+ delete _midiManager;
+
+ getTimerManager()->removeTimerProc(&fpsTimerCallback);
+
+ // Remove all of our debug levels
+ DebugMan.clearAllDebugChannels();
+}
+
+void ZVision::registerDefaultSettings() {
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultValue);
+ else
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultBoolValue);
+ }
+ }
+
+ ConfMan.registerDefault("originalsaveload", false);
+ ConfMan.registerDefault("doublefps", false);
+}
+
+void ZVision::loadSettings() {
+ int16 value = 0;
+ bool boolValue = false;
+
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].defaultValue >= 0) {
+ value = (settingsKeys[i].allowEditing) ? ConfMan.getInt(settingsKeys[i].name) : settingsKeys[i].defaultValue;
+ } else {
+ boolValue = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
+ value = (boolValue) ? 1 : 0;
+ }
+
+ _scriptManager->setStateValue(settingsKeys[i].slot, value);
+ }
+
+ if (getGameId() == GID_NEMESIS)
+ _scriptManager->setStateValue(StateKey_ExecScopeStyle, 1);
+ else
+ _scriptManager->setStateValue(StateKey_ExecScopeStyle, 0);
+}
+
+void ZVision::saveSettings() {
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
+ else
+ ConfMan.setBool(settingsKeys[i].name, (_scriptManager->getStateValue(settingsKeys[i].slot) == 1));
+ }
+ }
+
+ ConfMan.flushToDisk();
+}
+
+void ZVision::initialize() {
+ const Common::FSNode gameDataDir(ConfMan.get("path"));
+
+ _searchManager = new SearchManager(ConfMan.get("path"), 6);
+
+ _searchManager->addDir("FONTS");
+ _searchManager->addDir("addon");
+
+ if (_gameDescription->gameId == GID_GRANDINQUISITOR) {
+ _searchManager->loadZix("INQUIS.ZIX");
+ _searchManager->addPatch("C000H01Q.RAW", "C000H01Q.SRC");
+ _searchManager->addPatch("CM00H01Q.RAW", "CM00H01Q.SRC");
+ _searchManager->addPatch("DM00H01Q.RAW", "DM00H01Q.SRC");
+ _searchManager->addPatch("E000H01Q.RAW", "E000H01Q.SRC");
+ _searchManager->addPatch("EM00H50Q.RAW", "EM00H50Q.SRC");
+ _searchManager->addPatch("GJNPH65P.RAW", "GJNPH65P.SRC");
+ _searchManager->addPatch("GJNPH72P.RAW", "GJNPH72P.SRC");
+ _searchManager->addPatch("H000H01Q.RAW", "H000H01Q.SRC");
+ _searchManager->addPatch("M000H01Q.RAW", "M000H01Q.SRC");
+ _searchManager->addPatch("P000H01Q.RAW", "P000H01Q.SRC");
+ _searchManager->addPatch("Q000H01Q.RAW", "Q000H01Q.SRC");
+ _searchManager->addPatch("SW00H01Q.RAW", "SW00H01Q.SRC");
+ _searchManager->addPatch("T000H01Q.RAW", "T000H01Q.SRC");
+ _searchManager->addPatch("U000H01Q.RAW", "U000H01Q.SRC");
+ } else if (_gameDescription->gameId == GID_NEMESIS)
+ _searchManager->loadZix("NEMESIS.ZIX");
+
+ initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
+
+ // Register random source
+ _rnd = new Common::RandomSource("zvision");
+
+ // Create managers
+ _scriptManager = new ScriptManager(this);
+ _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat, _doubleFPS);
+ _saveManager = new SaveManager(this);
+ _stringManager = new StringManager(this);
+ _cursorManager = new CursorManager(this, _resourcePixelFormat);
+ _textRenderer = new TextRenderer(this);
+ _midiManager = new MidiManager();
+
+ if (_gameDescription->gameId == GID_GRANDINQUISITOR)
+ _menu = new MenuZGI(this);
+ else
+ _menu = new MenuNemesis(this);
+
+ // Initialize the managers
+ _cursorManager->initialize();
+ _scriptManager->initialize();
+ _stringManager->initialize(_gameDescription->gameId);
+
+ registerDefaultSettings();
+
+ loadSettings();
+
+ // Create debugger console. It requires GFX to be initialized
+ _console = new Console(this);
+ _doubleFPS = ConfMan.getBool("doublefps");
+
+ // Initialize FPS timer callback
+ getTimerManager()->installTimerProc(&fpsTimerCallback, 1000000, this, "zvisionFPS");
+}
+
+Common::Error ZVision::run() {
+ initialize();
+
+ // Check if a saved game is to be loaded from the launcher
+ if (ConfMan.hasKey("save_slot"))
+ _saveManager->loadGame(ConfMan.getInt("save_slot"));
+
+ // Before starting, make absolutely sure that the user has copied the needed fonts
+ if (!Common::File::exists("arial.ttf") && !Common::File::exists("FreeSans.ttf") && !_searchManager->hasFile("arial.ttf") && !_searchManager->hasFile("FreeSans.ttf") ) {
+ GUI::MessageDialog dialog(
+ "Before playing this game, you'll need to copy the required "
+ "fonts into ScummVM's extras directory, or into the game directory. "
+ "On Windows, you'll need the following font files from the Windows "
+ "font directory: Times New Roman, Century Schoolbook, Garamond, "
+ "Courier New and Arial. Alternatively, you can download the GNU "
+ "FreeFont package. You'll need all the fonts from that package, "
+ "i.e., FreeMono, FreeSans and FreeSerif."
+ );
+ dialog.runModal();
+ quitGame();
+ return Common::kUnknownError;
+ }
+
+ // Main loop
+ while (!shouldQuit()) {
+ _clock.update();
+ uint32 currentTime = _clock.getLastMeasuredTime();
+ uint32 deltaTime = _clock.getDeltaTime();
+
+ _cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem));
+
+ processEvents();
+ _renderManager->updateRotation();
+
+ _scriptManager->update(deltaTime);
+ _menu->process(deltaTime);
+
+ // Render the backBuffer to the screen
+ _renderManager->prepareBackground();
+ _renderManager->renderMenuToScreen();
+ _renderManager->processSubs(deltaTime);
+ _renderManager->renderSceneToScreen();
+
+ // Update the screen
+ if (canRender()) {
+ _system->updateScreen();
+ _renderedFrameCount++;
+ } else {
+ _frameRenderDelay--;
+ }
+
+ // Calculate the frame delay based off a desired frame time
+ int delay = _desiredFrameTime - int32(_system->getMillis() - currentTime);
+ // Ensure non-negative
+ delay = delay < 0 ? 0 : delay;
+
+ if (_doubleFPS) {
+ delay >>= 1;
+ }
+
+ if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) {
+ _saveManager->autoSave();
+ }
+
+ _system->delayMillis(delay);
+ }
+
+ return Common::kNoError;
+}
+
+void ZVision::pauseEngineIntern(bool pause) {
+ _mixer->pauseAll(pause);
+
+ if (pause) {
+ _clock.stop();
+ } else {
+ _clock.start();
+ }
+}
+
+Common::String ZVision::generateSaveFileName(uint slot) {
+ return Common::String::format("%s.%03u", _targetName.c_str(), slot);
+}
+
+void ZVision::setRenderDelay(uint delay) {
+ _frameRenderDelay = delay;
+}
+
+bool ZVision::canRender() {
+ return _frameRenderDelay <= 0;
+}
+
+GUI::Debugger *ZVision::getDebugger() {
+ return _console;
+}
+
+void ZVision::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _scriptManager->setStateValue(StateKey_Subtitles, ConfMan.getBool("subtitles") ? 1 : 0);
+}
+
+void ZVision::fpsTimerCallback(void *refCon) {
+ ((ZVision *)refCon)->fpsTimer();
+}
+
+void ZVision::fpsTimer() {
+ _fps = _renderedFrameCount;
+ _renderedFrameCount = 0;
+}
+
+} // End of namespace ZVision
--
cgit v1.2.3
From cc916625d9025ffaa898854c4de19da5dc2e2925 Mon Sep 17 00:00:00 2001
From: Torbjörn Andersson
Date: Tue, 30 Dec 2014 10:47:51 +0100
Subject: SCUMM: Add a "chained games manager"
This replaces the somewhat ugly use of the config manager to store
the chained games.
---
base/main.cpp | 38 ++++++++------------------------------
engines/engine.cpp | 31 +++++++++++++++++++++++++++++++
engines/engine.h | 28 ++++++++++++++++++++++++++++
engines/scumm/scumm.cpp | 3 ++-
4 files changed, 69 insertions(+), 31 deletions(-)
diff --git a/base/main.cpp b/base/main.cpp
index b9bd97dbef..0f5ebc7845 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -529,43 +529,21 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// at. At the time of writing, this is used for the Maniac Mansion
// easter egg in Day of the Tentacle.
- Common::String chainedGames, nextGame, saveSlot;
+ Common::String chainedGame;
+ int saveSlot = -1;
- if (ConfMan.hasKey("chained_games", Common::ConfigManager::kTransientDomain)) {
- chainedGames = ConfMan.get("chained_games", Common::ConfigManager::kTransientDomain);
- }
+ ChainedGamesMan.pop(chainedGame, saveSlot);
// Discard any command line options. It's unlikely that the user
// wanted to apply them to *all* games ever launched.
ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
- if (!chainedGames.empty()) {
- if (chainedGames.contains(',')) {
- for (uint i = 0; i < chainedGames.size(); i++) {
- if (chainedGames[i] == ',') {
- chainedGames.erase(0, i + 1);
- break;
- }
- nextGame += chainedGames[i];
- }
- ConfMan.set("chained_games", chainedGames, Common::ConfigManager::kTransientDomain);
- } else {
- nextGame = chainedGames;
- chainedGames.clear();
- ConfMan.removeKey("chained_games", Common::ConfigManager::kTransientDomain);
- }
- if (nextGame.contains(':')) {
- for (int i = nextGame.size() - 1; i >= 0; i--) {
- if (nextGame[i] == ':') {
- nextGame.erase(i);
- break;
- }
- saveSlot = nextGame[i] + saveSlot;
- }
- ConfMan.setInt("save_slot", atoi(saveSlot.c_str()), Common::ConfigManager::kTransientDomain);
+ if (!chainedGame.empty()) {
+ if (saveSlot != -1) {
+ ConfMan.setInt("save_slot", saveSlot, Common::ConfigManager::kTransientDomain);
}
- // Start the next game
- ConfMan.setActiveDomain(nextGame);
+ // Start the chained game
+ ConfMan.setActiveDomain(chainedGame);
} else {
// Clear the active config domain
ConfMan.setActiveDomain("");
diff --git a/engines/engine.cpp b/engines/engine.cpp
index c63437f800..24008dd073 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -45,6 +45,7 @@
#include "common/taskbar.h"
#include "common/textconsole.h"
#include "common/translation.h"
+#include "common/singleton.h"
#include "backends/keymapper/keymapper.h"
@@ -101,6 +102,36 @@ static void defaultErrorHandler(const char *msg) {
}
}
+// Chained games manager
+
+ChainedGamesManager::ChainedGamesManager() {
+ clear();
+}
+
+void ChainedGamesManager::clear() {
+ _chainedGames.clear();
+}
+
+void ChainedGamesManager::push(const Common::String target, const int slot) {
+ Game game;
+ game.target = target;
+ game.slot = slot;
+ _chainedGames.push(game);
+}
+
+bool ChainedGamesManager::pop(Common::String &target, int &slot) {
+ if (_chainedGames.empty()) {
+ return false;
+ }
+ Game game = _chainedGames.pop();
+ target = game.target;
+ slot = game.slot;
+ return true;
+}
+
+namespace Common {
+DECLARE_SINGLETON(ChainedGamesManager);
+}
Engine::Engine(OSystem *syst)
: _system(syst),
diff --git a/engines/engine.h b/engines/engine.h
index e325cc1ba2..d3415d584c 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -27,6 +27,8 @@
#include "common/str.h"
#include "common/language.h"
#include "common/platform.h"
+#include "common/queue.h"
+#include "common/singleton.h"
class OSystem;
@@ -334,6 +336,32 @@ protected:
};
+// Chained games
+
+/**
+ * Singleton class which manages chained games. A chained game is one that
+ * starts automatically, optionally loading a saved game, instead of returning
+ * to the launcher.
+ */
+class ChainedGamesManager : public Common::Singleton {
+private:
+ struct Game {
+ Common::String target;
+ int slot;
+ };
+
+ Common::Queue _chainedGames;
+
+public:
+ ChainedGamesManager();
+ void clear();
+ void push(const Common::String target, const int slot = -1);
+ bool pop(Common::String &target, int &slot);
+};
+
+/** Convenience shortcut for accessing the chained games manager. */
+#define ChainedGamesMan ChainedGamesManager::instance()
+
// FIXME: HACK for MidiEmu & error()
extern Engine *g_engine;
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 34ae957951..9518ed4e5c 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2625,7 +2625,8 @@ bool ScummEngine::startManiac() {
// Set up the chanined games to Maniac Mansion, and then back
// to the current game again with that save slot.
- ConfMan.set("chained_games", maniacTarget + "," + ConfMan.getActiveDomainName() + ":100", Common::ConfigManager::kTransientDomain);
+ ChainedGamesMan.push(maniacTarget);
+ ChainedGamesMan.push(ConfMan.getActiveDomainName(), 100);
// Force a return to the launcher. This will start the first
// chained game.
--
cgit v1.2.3
From 7dc316cced4c7a45a376d76a6ca0c84bd563132f Mon Sep 17 00:00:00 2001
From: Torbjörn Andersson
Date: Tue, 30 Dec 2014 10:54:49 +0100
Subject: SCUMM: Add secret "easter_egg" config key
This makes it possible to override the detection of Maniac Mansion
when starting the Day of the Tentacle easter egg. There is no GUI
for setting this, no error handling, and setting it to Day of the
Tentacle itself is probably a bad idea...
---
engines/scumm/scumm.cpp | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 9518ed4e5c..7d927b0cda 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2601,20 +2601,24 @@ bool ScummEngine::startManiac() {
Common::String currentPath = ConfMan.get("path");
Common::String maniacTarget;
- // Look for a game with a game path pointing to a 'Maniac' directory
- // as a subdirectory to the current game.
- Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
- for (; iter != ConfMan.endGameDomains(); ++iter) {
- Common::ConfigManager::Domain &dom = iter->_value;
- Common::String path = dom.getVal("path");
-
- if (path.hasPrefix(currentPath)) {
- path.erase(0, currentPath.size() + 1);
- if (path.equalsIgnoreCase("maniac")) {
- maniacTarget = dom.getVal("gameid");
- break;
+ if (!ConfMan.hasKey("easter_egg")) {
+ // Look for a game with a game path pointing to a 'Maniac' directory
+ // as a subdirectory to the current game.
+ Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
+ for (; iter != ConfMan.endGameDomains(); ++iter) {
+ Common::ConfigManager::Domain &dom = iter->_value;
+ Common::String path = dom.getVal("path");
+
+ if (path.hasPrefix(currentPath)) {
+ path.erase(0, currentPath.size() + 1);
+ if (path.equalsIgnoreCase("maniac")) {
+ maniacTarget = dom.getVal("gameid");
+ break;
+ }
}
}
+ } else {
+ maniacTarget = ConfMan.get("easter_egg");
}
if (!maniacTarget.empty()) {
--
cgit v1.2.3
From 88ba96aa3cb76c7d251a60f32d41f415a40b3dc4 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 30 Dec 2014 12:55:19 +0200
Subject: ZVISION: Fix an off-by-one error in the RLF decoder
A regression from 7f61a09478. The current frame is the currently
displayed frame, not the frame that should be displayed next. Thanks to
clone2727 and Marisa-Chan for the explanation and fixes
---
engines/zvision/video/rlf_decoder.cpp | 16 ++++++++--------
engines/zvision/video/rlf_decoder.h | 4 ++--
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index 6e2000f93c..db598a25b6 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -56,7 +56,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
_height(0),
_frameTime(0),
_frames(0),
- _curFrame(-1),
+ _displayedFrame(-1),
_frameBufferByteSize(0) {
if (!readHeader()) {
@@ -161,11 +161,11 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
uint frame = getFrameAtTime(time);
assert(frame < (int)_frameCount);
- if ((uint)_curFrame == frame)
+ if ((uint)_displayedFrame == frame)
return true;
- int closestFrame = _curFrame;
- int distance = (int)frame - _curFrame;
+ int closestFrame = _displayedFrame;
+ int distance = (int)frame - closestFrame;
if (distance < 0) {
for (uint i = 0; i < _completeFrames.size(); ++i) {
@@ -189,18 +189,18 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
applyFrameToCurrent(i);
}
- _curFrame = frame;
+ _displayedFrame = frame - 1;
return true;
}
const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() {
- if (_curFrame == (int)_frameCount)
+ if (_displayedFrame >= (int)_frameCount)
return NULL;
- applyFrameToCurrent(_curFrame);
+ _displayedFrame++;
+ applyFrameToCurrent(_displayedFrame);
- _curFrame++;
return &_currentFrameBuffer;
}
diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h
index 740f3fdd43..8b8cbaecd5 100644
--- a/engines/zvision/video/rlf_decoder.h
+++ b/engines/zvision/video/rlf_decoder.h
@@ -46,7 +46,7 @@ private:
uint16 getWidth() const { return _width; }
uint16 getHeight() const { return _height; }
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); /* RGB 555 */ }
- int getCurFrame() const { return _curFrame; }
+ int getCurFrame() const { return _displayedFrame; }
int getFrameCount() const { return _frameCount; }
const Graphics::Surface *decodeNextFrame();
bool isSeekable() const { return true; }
@@ -121,7 +121,7 @@ private:
Frame *_frames;
Common::Array _completeFrames;
- int _curFrame;
+ int _displayedFrame;
Graphics::Surface _currentFrameBuffer;
uint32 _frameBufferByteSize;
--
cgit v1.2.3
From 64979d5e453bd279c88e559d295d47b175a6559b Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Tue, 30 Dec 2014 15:38:03 +0200
Subject: ZVISION: Fix regression in the handling of multiple animations
A regression from 0c4e0673c3. Thanks to Marisa-Chan for noticing
---
engines/zvision/scripting/effects/animation_effect.cpp | 10 +++++++---
engines/zvision/scripting/effects/animation_effect.h | 2 ++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/engines/zvision/scripting/effects/animation_effect.cpp b/engines/zvision/scripting/effects/animation_effect.cpp
index c3cbc25406..511a0db353 100644
--- a/engines/zvision/scripting/effects/animation_effect.cpp
+++ b/engines/zvision/scripting/effects/animation_effect.cpp
@@ -88,10 +88,13 @@ bool AnimationEffect::process(uint32 deltaTimeInMillis) {
if (it != _playList.end()) {
playnode *nod = &(*it);
- if (!_animation->isPlaying()) {
+ if (nod->_curFrame == -1) {
// The node is just beginning playback
+ nod->_curFrame = nod->start;
+
_animation->start();
_animation->seekToFrame(nod->start);
+ _animation->setEndFrame(nod->stop);
nod->_delay = deltaTimeInMillis; // Force the frame to draw
if (nod->slot)
@@ -111,6 +114,7 @@ bool AnimationEffect::process(uint32 deltaTimeInMillis) {
return _disposeAfterUse;
}
+ nod->_curFrame = nod->start;
_animation->seekToFrame(nod->start);
}
@@ -186,9 +190,9 @@ void AnimationEffect::addPlayNode(int32 slot, int x, int y, int x2, int y2, int
nod.loop = loops;
nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1);
nod.start = startFrame;
- _animation->setEndFrame(CLIP(endFrame, 0, _animation->getFrameCount() - 1));
-
+ nod.stop = CLIP(endFrame, 0, _animation->getFrameCount() - 1);
nod.slot = slot;
+ nod._curFrame = -1;
nod._delay = 0;
nod._scaled = NULL;
_playList.push_back(nod);
diff --git a/engines/zvision/scripting/effects/animation_effect.h b/engines/zvision/scripting/effects/animation_effect.h
index a564b83ff3..fd6e24ab8b 100644
--- a/engines/zvision/scripting/effects/animation_effect.h
+++ b/engines/zvision/scripting/effects/animation_effect.h
@@ -48,7 +48,9 @@ public:
Common::Rect pos;
int32 slot;
int32 start;
+ int32 stop;
int32 loop;
+ int32 _curFrame;
int32 _delay;
Graphics::Surface *_scaled;
};
--
cgit v1.2.3
From d9ae84808f6314ec8c3b7b0a73e3e746bc8fc201 Mon Sep 17 00:00:00 2001
From: Fedor Strizhnev
Date: Tue, 30 Dec 2014 17:18:28 +0300
Subject: SYMBIAN: Add symbian support for access and princes engines
---
backends/platform/symbian/AdaptAllMMPs.pl | 2 +
.../symbian/BuildPackageUpload_LocalSettings.pl | 40 ++++++-----
backends/platform/symbian/help/ScummVM.rtf | 78 ++++++++++++----------
.../platform/symbian/mmp/scummvm_access.mmp.in | 52 +++++++++++++++
.../platform/symbian/mmp/scummvm_prince.mmp.in | 52 +++++++++++++++
5 files changed, 169 insertions(+), 55 deletions(-)
create mode 100644 backends/platform/symbian/mmp/scummvm_access.mmp.in
create mode 100644 backends/platform/symbian/mmp/scummvm_prince.mmp.in
diff --git a/backends/platform/symbian/AdaptAllMMPs.pl b/backends/platform/symbian/AdaptAllMMPs.pl
index 6eed7f0690..ead28ba4b1 100644
--- a/backends/platform/symbian/AdaptAllMMPs.pl
+++ b/backends/platform/symbian/AdaptAllMMPs.pl
@@ -48,12 +48,14 @@ chdir("../../../");
"mmp/scummvm_voyeur.mmp",
"mmp/scummvm_wintermute.mmp",
# New engines
+ "mmp/scummvm_access.mmp",
"mmp/scummvm_avalanche.mmp",
"mmp/scummvm_bbvs.mmp",
"mmp/scummvm_cge2.mmp",
"mmp/scummvm_fullpipe.mmp",
"mmp/scummvm_lastexpress.mmp",
"mmp/scummvm_mads.mmp",
+ "mmp/scummvm_prince.mmp",
"mmp/scummvm_sword25.mmp",
"mmp/scummvm_testbed.mmp",
"mmp/scummvm_zvision.mmp",
diff --git a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
index f9b376d674..8c19631524 100644
--- a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
+++ b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
@@ -3,32 +3,36 @@
@WorkingEngines = qw(
agos agi cine cge composer cruise draci dreamweb
- drascula hugo gob groovie kyra lastexpress
- lure made mohawk parallaction pegasus queen
- saga sci scumm sky sword1 sword2 teenagent tinsel
- toltecs tony toon touche tsage tucker wintermute
- bbvs fullpipe hopkins mortevielle mads cge2
- neverhood testbed avalanche zvision voyeur
+ drascula hugo gob groovie hopkins kyra lastexpress
+ lure made mohawk mortevielle neverhood parallaction
+ pegasus queen saga sci scumm sky sword1 sword2
+ teenagent tinsel toltecs tony toon touche tsage
+ tucker voyeur wintermute
+ access avalanche bbvs cge2 fullpipe mads prince
+ testbed zvision
);
-#### New engines
-#### sword25
+
+#### sword25 yet not added
+
+#### In progress engines are :
+#### access avalanche bbvs cge2 fullpipe mads prince
+#### testbed zvision
@WorkingEngines_1st = qw(
- cge2 cine composer cruise drascula groovie
- lastexpress made parallaction queen
- saga scumm touche tucker wintermute
- avalanche zvision voyeur
+ cine composer cruise drascula groovie
+ lastexpress made parallaction queen saga
+ scumm touche tucker wintermute voyeur
+ access avalanche cge2 zvision
);
@WorkingEngines_2nd = qw(
- agi agos bbvs cge draci gob hopkins
- hugo kyra lure mohawk pegasus sci
- sky sword1 sword2 teenagent mads
+ agi agos cge draci dreamweb gob hopkins
+ hugo kyra lure mohawk mortevielle neverhood
+ pegasus sci sky sword1 sword2 teenagent
tinsel tsage toltecs tony toon
- dreamweb fullpipe mortevielle
- neverhood testbed
+ bbvs fullpipe mads prince testbed
);
-#### sword25
+#### sword25 yet not added
@TestingEngines = qw(
diff --git a/backends/platform/symbian/help/ScummVM.rtf b/backends/platform/symbian/help/ScummVM.rtf
index 8e9d37363c..15b2105ecd 100644
--- a/backends/platform/symbian/help/ScummVM.rtf
+++ b/backends/platform/symbian/help/ScummVM.rtf
@@ -51,24 +51,27 @@ Synonyms;}{\*\cs33 \additive \super \sbasedon10 endnote reference;}{\s34\ql \fi-
{\listoverride\listid-125\listoverridecount0\ls12}{\listoverride\listid-120\listoverridecount0\ls13}{\listoverride\listid-129\listoverridecount0\ls14}{\listoverride\listid-119\listoverridecount0\ls15}{\listoverride\listid-125\listoverridecount0\ls16}
{\listoverride\listid-120\listoverridecount0\ls17}{\listoverride\listid-129\listoverridecount0\ls18}{\listoverride\listid-119\listoverridecount0\ls19}{\listoverride\listid-125\listoverridecount0\ls20}{\listoverride\listid-120\listoverridecount0\ls21}
{\listoverride\listid-129\listoverridecount0\ls22}{\listoverride\listid-119\listoverridecount0\ls23}{\listoverride\listid-125\listoverridecount0\ls24}{\listoverride\listid-120\listoverridecount0\ls25}{\listoverride\listid-129\listoverridecount0\ls26}
-{\listoverride\listid-119\listoverridecount0\ls27}{\listoverride\listid-125\listoverridecount0\ls28}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1
-\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls29}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel
-\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls30}}{\info{\author Fedor}
-{\operator Fedor}{\creatim\yr2013\mo11\dy30\hr23\min4}{\revtim\yr2014\mo9\dy9\hr19\min22}{\version99}{\edmins93}{\nofpages8}{\nofwords1514}{\nofchars8634}{\*\company DEV}{\nofcharsws0}{\vern8249}}\margl1701\margr850\margt1134\margb1134
-\deftab708\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind4\viewscale100\nolnhtadjtbl \fet0{\*\template
-E:\\Documents and Settings\\Administrator\\Application Data\\Microsoft\\\'d8\'e0\'e1\'eb\'ee\'ed\'fb\\cshelp2000.dot}\sectd \linex0\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
-{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang
-{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain
-\s17\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\lang1033\langfe1033\langnp1033 Author: Fedor Strizhniou.}{\f28
-\par }{\lang1033\langfe1033\langnp1033 Date: November 2013}{\f28
-\par }{\lang1033\langfe1033\langnp1033 Version: 1.7.0
+{\listoverride\listid-119\listoverridecount0\ls27}{\listoverride\listid-125\listoverridecount0\ls28}{\listoverride\listid-120\listoverridecount0\ls29}{\listoverride\listid-129\listoverridecount0\ls30}{\listoverride\listid-119\listoverridecount0\ls31}
+{\listoverride\listid-125\listoverridecount0\ls32}{\listoverride\listid-120\listoverridecount0\ls33}{\listoverride\listid-129\listoverridecount0\ls34}{\listoverride\listid-119\listoverridecount0\ls35}{\listoverride\listid-125\listoverridecount0\ls36}
+{\listoverride\listid-120\listoverridecount0\ls37}{\listoverride\listid-129\listoverridecount0\ls38}{\listoverride\listid-119\listoverridecount0\ls39}{\listoverride\listid-125\listoverridecount0\ls40}{\listoverride\listid-2\listoverridecount1{\lfolevel
+\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283
+}}\ls41}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr
+\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls42}}{\info{\author Fedor}{\operator Fedor}{\creatim\yr2013\mo11\dy30\hr23\min4}{\revtim\yr2014\mo12\dy29\hr22\min52}{\version102}{\edmins95}{\nofpages8}{\nofwords1514}{\nofchars8634}
+{\*\company DEV}{\nofcharsws0}{\vern8249}}\margl1701\margr850\margt1134\margb1134 \deftab708\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0
+\dgvshow3\jcompress\viewkind4\viewscale100\nolnhtadjtbl \fet0{\*\template E:\\Documents and Settings\\Administrator\\Application Data\\Microsoft\\\'d8\'e0\'e1\'eb\'ee\'ed\'fb\\cshelp2000.dot}\sectd \linex0\sectdefaultcl {\*\pnseclvl1
+\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5
+\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
+{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s17\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {
+\lang1033\langfe1033\langnp1033 Author: Fedor Strizhniou.}{\f28
+\par }{\lang1033\langfe1033\langnp1033 Date: November 2014}{\f28
+\par }{\lang1033\langfe1033\langnp1033 Version: 1.8.0
\par }\pard\plain \s1\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \b\f1\fs32\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 {ScummVM Help
\par }\pard\plain \s16\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \b\f1\fs32\cf9\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 {\lang1033\langfe1033\langnp1033 0x100039ce}{\lang1059\langfe1033\langnp1059
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0 \b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28
About ScummVM Help
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {About ScummVM Help
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {About ScummVM Help
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }{
This help file based on ScummVM forum thread with some elaborations(in Anotherguest section) and text correction. If you wish add some text or translate you may download and modify source document from https://sourceforge.net/projects/scummvms60git/ and t
@@ -79,8 +82,8 @@ hen send me to fedor_qd@mail.ru
\par }{\f29
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 1st guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, UIQ, UIQ3, S80, s80, S90, s90
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, UIQ, UIQ3, S80, s80, S90, s90
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }{UIQ3 devices: To the top right (holding the phone portrait) you four icons, from the top they are
\par
@@ -126,17 +129,17 @@ through directorylist (one hand use perhaps!?) or save games etc. Keyboard mode
of events that ScummVM receives from SDL.
\par What are these Shrinked, Zoomed and Upscaled modes anyway?
\par
-\par Shrink displays the game on your screen but in a shrinked way, either in Portrait or Landscape mode, so not all the pixels c
-an be seen. Zoom mode uses the maximum resolution of your phone displaying a smaller part of the game zoomed at 1:1 pixels. For scrolling in S60 Zoom mode: 0+Cursor keys to scroll around, 0+Ok button to center view. Upscale tries to fill the larger screen
-s on S80/S90 devices in a better way for low resolution games. Currently it uses a pixel interpolation upscaling routine.
+\par Shrink displays the game on your screen but in a shrinked way, either in Port
+rait or Landscape mode, so not all the pixels can be seen. Zoom mode uses the maximum resolution of your phone displaying a smaller part of the game zoomed at 1:1 pixels. For scrolling in S60 Zoom mode: 0+Cursor keys to scroll around, 0+Ok button to cente
+r view. Upscale tries to fill the larger screens on S80/S90 devices in a better way for low resolution games. Currently it uses a pixel interpolation upscaling routine.
\par
\par You can also use a bluetooth mouse with S60v3 devices to control your game. You need the bluetooth hid library from Hinkka http://koti.mbnet.fi/hinkka/Download.html to get it to work properly.
\par }{\f29
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 2nd guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par
\par }{More user-friendly guide for Nokia phones (based on N96 but should apply to most phones)
@@ -161,9 +164,8 @@ s on S80/S90 devices in a better way for low resolution games. Currently it uses
\par }{1 - Change Input.
\par This is the option you'll probably use the most. There are three settings; A,C and J.
\par
-\par A -
- This is the "Text Input" mode. It allows you to type directly into ScummVM as if you were using a keyboard. Type the same way you would when sending a text message off of your phone. Please note that the pointer is disabled when in this mode. Don't forge
-t to exit Configuration Mode before typing!
+\par A - This is the "Text Input" mode. It allows you to type directly into ScummVM as if you were using a keyboard. Type the same way you would when sending a text message o
+ff of your phone. Please note that the pointer is disabled when in this mode. Don't forget to exit Configuration Mode before typing!
\par
\par C - This is the "Cursor" mode. This emulates the arrow keys of the keyboard. Some games require using this instead of the mouse (e.g. the destruction derby section towards the end of Full Throttle).
\par
@@ -178,8 +180,9 @@ t to exit Configuration Mode before typing!
\par Only applies to Landscape mode, simply swaps the screen output between having the phone tilted on its left side or on its right side.
\par
\par 4 - Toggle Zoom On and Off
-\par Zooms in on a portion of the screen. Handy for when you are looking through a screen for items or having trouble reading subtitles. Use the navigation buttons for panning around
- the play area. Don't forget you'll have to exit out of Configuration Mode before you can move the pointer again. Exiting Configuration Mode does not reset the zoom level.
+\par Zooms in on a portion of the screen. Handy for when you are looking through a screen fo
+r items or having trouble reading subtitles. Use the navigation buttons for panning around the play area. Don't forget you'll have to exit out of Configuration Mode before you can move the pointer again. Exiting Configuration Mode does not reset the zoom
+level.
\par }{\f29
\par }{5 & 6 - Unused
\par
@@ -200,12 +203,12 @@ t to exit Configuration Mode before typing!
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 3rd guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par
-\par }{ScummVM keys on Nokia e71 (most likely on any other qwerty-device, too), tested on version 0.14.0svn (Feb. 18 2009
- 05:56:07). Number keys are inserted by first pressing fn-key (leftmost key at bottom row on E71) and then pressing correct key (e.g. 5 is fn+g). You don't have to press both keys simultaneously.
+\par }{ScummVM keys on Nokia e71 (most likely on any other qwerty-device, too), tested on version 0.14.0svn (Feb. 18 20
+09 05:56:07). Number keys are inserted by first pressing fn-key (leftmost key at bottom row on E71) and then pressing correct key (e.g. 5 is fn+g). You don't have to press both keys simultaneously.
\par
\par Basic keys:
\par
@@ -255,9 +258,8 @@ t to exit Configuration Mode before typing!
\par p -- punch (hand)
\par
\par AGI games (King's Quest, Police Quest etc.):
-\par The
- games work beautifully on the E71, but there's some stupid bugs (in input). I recall finding some debug keys and "last sentence" / "inventory" -keys in earlier version, but I can't find them any more. Also you can't turn on sirens in Police Quest, which
-kinda makes it unplayable.
+\par The games work beautifully on the E71, but there's some stupid bugs (in input). I recall finding some debug keys and "last sentence" / "inventory" -keys in earlier version, but I can't find them any more. Also you can't turn on sirens in Police Quest, whi
+ch kinda makes it unplayable.
\par
\par There's good side and bad side to each input mode:
\par Keyboard (I use this primarily)
@@ -278,9 +280,10 @@ kinda makes it unplayable.
\par }{\f28
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {ScummVM1 engines list
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls30\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls30\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
-\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {agi
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls42\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls42\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
+\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {access
+\par agi
\par agos
\par \tab AGOS2
\par cge2
@@ -312,8 +315,8 @@ kinda makes it unplayable.
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {ScummVM2 engines list
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls30\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls30\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls42\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls42\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {avalanche
\par cge
\par composer
@@ -330,6 +333,7 @@ kinda makes it unplayable.
\par \tab RIVEN
\par mortevielle
\par pegasus
+\par prince
\par sci
\par \tab SCI32
\par sky
diff --git a/backends/platform/symbian/mmp/scummvm_access.mmp.in b/backends/platform/symbian/mmp/scummvm_access.mmp.in
new file mode 100644
index 0000000000..4f8b258ec0
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_access.mmp.in
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
+ * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
+ * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
+ * Copyright (C) 2005-2013 The ScummVM project
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+//
+// EPOC MMP makefile project for ScummVM
+//
+
+// *** Definitions
+
+TARGET scummvm_access.lib
+TARGETTYPE lib
+#include "config.mmh"
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\access
+
+//START_AUTO_OBJECTS_ACCESS_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_ACCESS_//
+
diff --git a/backends/platform/symbian/mmp/scummvm_prince.mmp.in b/backends/platform/symbian/mmp/scummvm_prince.mmp.in
new file mode 100644
index 0000000000..7dfec04f46
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_prince.mmp.in
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
+ * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
+ * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
+ * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2014 Strizniou Fedor
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+//
+// EPOC MMP makefile project for ScummVM
+//
+
+// *** Definitions
+
+TARGET scummvm_prince.lib
+TARGETTYPE lib
+#include "config.mmh"
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\prince
+
+//START_AUTO_OBJECTS_PRINCE_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_PRINCE_//
--
cgit v1.2.3
From da18e796d0d2f928ef8b1d0988f4457329d2f31e Mon Sep 17 00:00:00 2001
From: Fedor Strizhnev
Date: Tue, 30 Dec 2014 17:18:28 +0300
Subject: SYMBIAN: Add symbian support for access and prince engines
---
backends/platform/symbian/AdaptAllMMPs.pl | 2 +
.../symbian/BuildPackageUpload_LocalSettings.pl | 40 ++++++-----
backends/platform/symbian/help/ScummVM.rtf | 78 ++++++++++++----------
.../platform/symbian/mmp/scummvm_access.mmp.in | 52 +++++++++++++++
.../platform/symbian/mmp/scummvm_prince.mmp.in | 52 +++++++++++++++
5 files changed, 169 insertions(+), 55 deletions(-)
create mode 100644 backends/platform/symbian/mmp/scummvm_access.mmp.in
create mode 100644 backends/platform/symbian/mmp/scummvm_prince.mmp.in
diff --git a/backends/platform/symbian/AdaptAllMMPs.pl b/backends/platform/symbian/AdaptAllMMPs.pl
index 6eed7f0690..ead28ba4b1 100644
--- a/backends/platform/symbian/AdaptAllMMPs.pl
+++ b/backends/platform/symbian/AdaptAllMMPs.pl
@@ -48,12 +48,14 @@ chdir("../../../");
"mmp/scummvm_voyeur.mmp",
"mmp/scummvm_wintermute.mmp",
# New engines
+ "mmp/scummvm_access.mmp",
"mmp/scummvm_avalanche.mmp",
"mmp/scummvm_bbvs.mmp",
"mmp/scummvm_cge2.mmp",
"mmp/scummvm_fullpipe.mmp",
"mmp/scummvm_lastexpress.mmp",
"mmp/scummvm_mads.mmp",
+ "mmp/scummvm_prince.mmp",
"mmp/scummvm_sword25.mmp",
"mmp/scummvm_testbed.mmp",
"mmp/scummvm_zvision.mmp",
diff --git a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
index f9b376d674..8c19631524 100644
--- a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
+++ b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
@@ -3,32 +3,36 @@
@WorkingEngines = qw(
agos agi cine cge composer cruise draci dreamweb
- drascula hugo gob groovie kyra lastexpress
- lure made mohawk parallaction pegasus queen
- saga sci scumm sky sword1 sword2 teenagent tinsel
- toltecs tony toon touche tsage tucker wintermute
- bbvs fullpipe hopkins mortevielle mads cge2
- neverhood testbed avalanche zvision voyeur
+ drascula hugo gob groovie hopkins kyra lastexpress
+ lure made mohawk mortevielle neverhood parallaction
+ pegasus queen saga sci scumm sky sword1 sword2
+ teenagent tinsel toltecs tony toon touche tsage
+ tucker voyeur wintermute
+ access avalanche bbvs cge2 fullpipe mads prince
+ testbed zvision
);
-#### New engines
-#### sword25
+
+#### sword25 yet not added
+
+#### In progress engines are :
+#### access avalanche bbvs cge2 fullpipe mads prince
+#### testbed zvision
@WorkingEngines_1st = qw(
- cge2 cine composer cruise drascula groovie
- lastexpress made parallaction queen
- saga scumm touche tucker wintermute
- avalanche zvision voyeur
+ cine composer cruise drascula groovie
+ lastexpress made parallaction queen saga
+ scumm touche tucker wintermute voyeur
+ access avalanche cge2 zvision
);
@WorkingEngines_2nd = qw(
- agi agos bbvs cge draci gob hopkins
- hugo kyra lure mohawk pegasus sci
- sky sword1 sword2 teenagent mads
+ agi agos cge draci dreamweb gob hopkins
+ hugo kyra lure mohawk mortevielle neverhood
+ pegasus sci sky sword1 sword2 teenagent
tinsel tsage toltecs tony toon
- dreamweb fullpipe mortevielle
- neverhood testbed
+ bbvs fullpipe mads prince testbed
);
-#### sword25
+#### sword25 yet not added
@TestingEngines = qw(
diff --git a/backends/platform/symbian/help/ScummVM.rtf b/backends/platform/symbian/help/ScummVM.rtf
index 8e9d37363c..15b2105ecd 100644
--- a/backends/platform/symbian/help/ScummVM.rtf
+++ b/backends/platform/symbian/help/ScummVM.rtf
@@ -51,24 +51,27 @@ Synonyms;}{\*\cs33 \additive \super \sbasedon10 endnote reference;}{\s34\ql \fi-
{\listoverride\listid-125\listoverridecount0\ls12}{\listoverride\listid-120\listoverridecount0\ls13}{\listoverride\listid-129\listoverridecount0\ls14}{\listoverride\listid-119\listoverridecount0\ls15}{\listoverride\listid-125\listoverridecount0\ls16}
{\listoverride\listid-120\listoverridecount0\ls17}{\listoverride\listid-129\listoverridecount0\ls18}{\listoverride\listid-119\listoverridecount0\ls19}{\listoverride\listid-125\listoverridecount0\ls20}{\listoverride\listid-120\listoverridecount0\ls21}
{\listoverride\listid-129\listoverridecount0\ls22}{\listoverride\listid-119\listoverridecount0\ls23}{\listoverride\listid-125\listoverridecount0\ls24}{\listoverride\listid-120\listoverridecount0\ls25}{\listoverride\listid-129\listoverridecount0\ls26}
-{\listoverride\listid-119\listoverridecount0\ls27}{\listoverride\listid-125\listoverridecount0\ls28}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1
-\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls29}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel
-\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls30}}{\info{\author Fedor}
-{\operator Fedor}{\creatim\yr2013\mo11\dy30\hr23\min4}{\revtim\yr2014\mo9\dy9\hr19\min22}{\version99}{\edmins93}{\nofpages8}{\nofwords1514}{\nofchars8634}{\*\company DEV}{\nofcharsws0}{\vern8249}}\margl1701\margr850\margt1134\margb1134
-\deftab708\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind4\viewscale100\nolnhtadjtbl \fet0{\*\template
-E:\\Documents and Settings\\Administrator\\Application Data\\Microsoft\\\'d8\'e0\'e1\'eb\'ee\'ed\'fb\\cshelp2000.dot}\sectd \linex0\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
-{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang
-{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain
-\s17\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\lang1033\langfe1033\langnp1033 Author: Fedor Strizhniou.}{\f28
-\par }{\lang1033\langfe1033\langnp1033 Date: November 2013}{\f28
-\par }{\lang1033\langfe1033\langnp1033 Version: 1.7.0
+{\listoverride\listid-119\listoverridecount0\ls27}{\listoverride\listid-125\listoverridecount0\ls28}{\listoverride\listid-120\listoverridecount0\ls29}{\listoverride\listid-129\listoverridecount0\ls30}{\listoverride\listid-119\listoverridecount0\ls31}
+{\listoverride\listid-125\listoverridecount0\ls32}{\listoverride\listid-120\listoverridecount0\ls33}{\listoverride\listid-129\listoverridecount0\ls34}{\listoverride\listid-119\listoverridecount0\ls35}{\listoverride\listid-125\listoverridecount0\ls36}
+{\listoverride\listid-120\listoverridecount0\ls37}{\listoverride\listid-129\listoverridecount0\ls38}{\listoverride\listid-119\listoverridecount0\ls39}{\listoverride\listid-125\listoverridecount0\ls40}{\listoverride\listid-2\listoverridecount1{\lfolevel
+\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283
+}}\ls41}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr
+\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls42}}{\info{\author Fedor}{\operator Fedor}{\creatim\yr2013\mo11\dy30\hr23\min4}{\revtim\yr2014\mo12\dy29\hr22\min52}{\version102}{\edmins95}{\nofpages8}{\nofwords1514}{\nofchars8634}
+{\*\company DEV}{\nofcharsws0}{\vern8249}}\margl1701\margr850\margt1134\margb1134 \deftab708\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0
+\dgvshow3\jcompress\viewkind4\viewscale100\nolnhtadjtbl \fet0{\*\template E:\\Documents and Settings\\Administrator\\Application Data\\Microsoft\\\'d8\'e0\'e1\'eb\'ee\'ed\'fb\\cshelp2000.dot}\sectd \linex0\sectdefaultcl {\*\pnseclvl1
+\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5
+\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
+{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s17\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {
+\lang1033\langfe1033\langnp1033 Author: Fedor Strizhniou.}{\f28
+\par }{\lang1033\langfe1033\langnp1033 Date: November 2014}{\f28
+\par }{\lang1033\langfe1033\langnp1033 Version: 1.8.0
\par }\pard\plain \s1\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \b\f1\fs32\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 {ScummVM Help
\par }\pard\plain \s16\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \b\f1\fs32\cf9\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 {\lang1033\langfe1033\langnp1033 0x100039ce}{\lang1059\langfe1033\langnp1059
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0 \b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28
About ScummVM Help
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {About ScummVM Help
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {About ScummVM Help
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }{
This help file based on ScummVM forum thread with some elaborations(in Anotherguest section) and text correction. If you wish add some text or translate you may download and modify source document from https://sourceforge.net/projects/scummvms60git/ and t
@@ -79,8 +82,8 @@ hen send me to fedor_qd@mail.ru
\par }{\f29
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 1st guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, UIQ, UIQ3, S80, s80, S90, s90
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, UIQ, UIQ3, S80, s80, S90, s90
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }{UIQ3 devices: To the top right (holding the phone portrait) you four icons, from the top they are
\par
@@ -126,17 +129,17 @@ through directorylist (one hand use perhaps!?) or save games etc. Keyboard mode
of events that ScummVM receives from SDL.
\par What are these Shrinked, Zoomed and Upscaled modes anyway?
\par
-\par Shrink displays the game on your screen but in a shrinked way, either in Portrait or Landscape mode, so not all the pixels c
-an be seen. Zoom mode uses the maximum resolution of your phone displaying a smaller part of the game zoomed at 1:1 pixels. For scrolling in S60 Zoom mode: 0+Cursor keys to scroll around, 0+Ok button to center view. Upscale tries to fill the larger screen
-s on S80/S90 devices in a better way for low resolution games. Currently it uses a pixel interpolation upscaling routine.
+\par Shrink displays the game on your screen but in a shrinked way, either in Port
+rait or Landscape mode, so not all the pixels can be seen. Zoom mode uses the maximum resolution of your phone displaying a smaller part of the game zoomed at 1:1 pixels. For scrolling in S60 Zoom mode: 0+Cursor keys to scroll around, 0+Ok button to cente
+r view. Upscale tries to fill the larger screens on S80/S90 devices in a better way for low resolution games. Currently it uses a pixel interpolation upscaling routine.
\par
\par You can also use a bluetooth mouse with S60v3 devices to control your game. You need the bluetooth hid library from Hinkka http://koti.mbnet.fi/hinkka/Download.html to get it to work properly.
\par }{\f29
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 2nd guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par
\par }{More user-friendly guide for Nokia phones (based on N96 but should apply to most phones)
@@ -161,9 +164,8 @@ s on S80/S90 devices in a better way for low resolution games. Currently it uses
\par }{1 - Change Input.
\par This is the option you'll probably use the most. There are three settings; A,C and J.
\par
-\par A -
- This is the "Text Input" mode. It allows you to type directly into ScummVM as if you were using a keyboard. Type the same way you would when sending a text message off of your phone. Please note that the pointer is disabled when in this mode. Don't forge
-t to exit Configuration Mode before typing!
+\par A - This is the "Text Input" mode. It allows you to type directly into ScummVM as if you were using a keyboard. Type the same way you would when sending a text message o
+ff of your phone. Please note that the pointer is disabled when in this mode. Don't forget to exit Configuration Mode before typing!
\par
\par C - This is the "Cursor" mode. This emulates the arrow keys of the keyboard. Some games require using this instead of the mouse (e.g. the destruction derby section towards the end of Full Throttle).
\par
@@ -178,8 +180,9 @@ t to exit Configuration Mode before typing!
\par Only applies to Landscape mode, simply swaps the screen output between having the phone tilted on its left side or on its right side.
\par
\par 4 - Toggle Zoom On and Off
-\par Zooms in on a portion of the screen. Handy for when you are looking through a screen for items or having trouble reading subtitles. Use the navigation buttons for panning around
- the play area. Don't forget you'll have to exit out of Configuration Mode before you can move the pointer again. Exiting Configuration Mode does not reset the zoom level.
+\par Zooms in on a portion of the screen. Handy for when you are looking through a screen fo
+r items or having trouble reading subtitles. Use the navigation buttons for panning around the play area. Don't forget you'll have to exit out of Configuration Mode before you can move the pointer again. Exiting Configuration Mode does not reset the zoom
+level.
\par }{\f29
\par }{5 & 6 - Unused
\par
@@ -200,12 +203,12 @@ t to exit Configuration Mode before typing!
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 3rd guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par
-\par }{ScummVM keys on Nokia e71 (most likely on any other qwerty-device, too), tested on version 0.14.0svn (Feb. 18 2009
- 05:56:07). Number keys are inserted by first pressing fn-key (leftmost key at bottom row on E71) and then pressing correct key (e.g. 5 is fn+g). You don't have to press both keys simultaneously.
+\par }{ScummVM keys on Nokia e71 (most likely on any other qwerty-device, too), tested on version 0.14.0svn (Feb. 18 20
+09 05:56:07). Number keys are inserted by first pressing fn-key (leftmost key at bottom row on E71) and then pressing correct key (e.g. 5 is fn+g). You don't have to press both keys simultaneously.
\par
\par Basic keys:
\par
@@ -255,9 +258,8 @@ t to exit Configuration Mode before typing!
\par p -- punch (hand)
\par
\par AGI games (King's Quest, Police Quest etc.):
-\par The
- games work beautifully on the E71, but there's some stupid bugs (in input). I recall finding some debug keys and "last sentence" / "inventory" -keys in earlier version, but I can't find them any more. Also you can't turn on sirens in Police Quest, which
-kinda makes it unplayable.
+\par The games work beautifully on the E71, but there's some stupid bugs (in input). I recall finding some debug keys and "last sentence" / "inventory" -keys in earlier version, but I can't find them any more. Also you can't turn on sirens in Police Quest, whi
+ch kinda makes it unplayable.
\par
\par There's good side and bad side to each input mode:
\par Keyboard (I use this primarily)
@@ -278,9 +280,10 @@ kinda makes it unplayable.
\par }{\f28
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {ScummVM1 engines list
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls30\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls30\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
-\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {agi
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls42\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls42\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
+\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {access
+\par agi
\par agos
\par \tab AGOS2
\par cge2
@@ -312,8 +315,8 @@ kinda makes it unplayable.
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {ScummVM2 engines list
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls30\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls30\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls42\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls42\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {avalanche
\par cge
\par composer
@@ -330,6 +333,7 @@ kinda makes it unplayable.
\par \tab RIVEN
\par mortevielle
\par pegasus
+\par prince
\par sci
\par \tab SCI32
\par sky
diff --git a/backends/platform/symbian/mmp/scummvm_access.mmp.in b/backends/platform/symbian/mmp/scummvm_access.mmp.in
new file mode 100644
index 0000000000..4f8b258ec0
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_access.mmp.in
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
+ * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
+ * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
+ * Copyright (C) 2005-2013 The ScummVM project
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+//
+// EPOC MMP makefile project for ScummVM
+//
+
+// *** Definitions
+
+TARGET scummvm_access.lib
+TARGETTYPE lib
+#include "config.mmh"
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\access
+
+//START_AUTO_OBJECTS_ACCESS_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_ACCESS_//
+
diff --git a/backends/platform/symbian/mmp/scummvm_prince.mmp.in b/backends/platform/symbian/mmp/scummvm_prince.mmp.in
new file mode 100644
index 0000000000..7dfec04f46
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_prince.mmp.in
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
+ * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
+ * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
+ * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2014 Strizniou Fedor
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+//
+// EPOC MMP makefile project for ScummVM
+//
+
+// *** Definitions
+
+TARGET scummvm_prince.lib
+TARGETTYPE lib
+#include "config.mmh"
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\prince
+
+//START_AUTO_OBJECTS_PRINCE_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_PRINCE_//
--
cgit v1.2.3
From e27f5f69882345e45d6b2f1c8b449ea622d7d464 Mon Sep 17 00:00:00 2001
From: Fedor Strizhnev
Date: Tue, 30 Dec 2014 19:05:27 +0300
Subject: Symbian: completely disabled MT32
---
backends/platform/symbian/AdaptAllMMPs.pl | 3 +++
1 file changed, 3 insertions(+)
diff --git a/backends/platform/symbian/AdaptAllMMPs.pl b/backends/platform/symbian/AdaptAllMMPs.pl
index ead28ba4b1..6b9f918a51 100644
--- a/backends/platform/symbian/AdaptAllMMPs.pl
+++ b/backends/platform/symbian/AdaptAllMMPs.pl
@@ -105,6 +105,7 @@ my @sections_scumm = ("", "ENABLE_SCUMM_7_8", "ENABLE_HE"); # special sections f
# files excluded from build, case insensitive, will be matched in filename string only
my @excludes_snd = (
"mt32.*",
+ "Analog.cpp",
"fluidsynth.cpp",
"i386.cpp",
"part.*",
@@ -193,6 +194,7 @@ ParseModule("_tucker", "tucker", \@section_empty);
ParseModule("_voyeur" ,"voyeur", \@section_empty);
ParseModule("_wintermute","wintermute", \@section_empty);
##### new engines
+ParseModule("_access" ,"access", \@section_empty);
ParseModule("_avalanche" ,"avalanche", \@section_empty);
ParseModule("_bbvs" ,"bbvs", \@section_empty);
ParseModule("_cge2" ,"cge2", \@section_empty);
@@ -200,6 +202,7 @@ ParseModule("_fullpipe" ,"fullpipe", \@section_empty);
ParseModule("_lastexpress","lastexpress", \@section_empty);
ParseModule("_m4", "m4", \@section_empty);
ParseModule("_mads" ,"mads", \@section_empty);
+ParseModule("_prince" ,"prince", \@section_empty);
ParseModule("_sword25" ,"sword25", \@section_empty);
ParseModule("_testbed" ,"testbed", \@section_empty);
ParseModule("_zvision" ,"zvision", \@section_empty);
--
cgit v1.2.3
From 2fb116f10eaa1bf682a220c33016fc61492af4fe Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 13:32:44 -0600
Subject: SWORD25: Move all lua serialization helper functions to their own
file
---
engines/sword25/util/lua_serialization_util.cpp | 269 +++++++++++++++++
engines/sword25/util/lua_serialization_util.h | 55 ++++
engines/sword25/util/lua_serializer.cpp | 56 ++--
engines/sword25/util/lua_unserializer.cpp | 368 ++----------------------
4 files changed, 376 insertions(+), 372 deletions(-)
diff --git a/engines/sword25/util/lua_serialization_util.cpp b/engines/sword25/util/lua_serialization_util.cpp
index 80c5f86b20..fc3f73eca6 100644
--- a/engines/sword25/util/lua_serialization_util.cpp
+++ b/engines/sword25/util/lua_serialization_util.cpp
@@ -27,10 +27,20 @@
#include "lua/lobject.h"
#include "lua/lstate.h"
#include "lua/lgc.h"
+#include "lua/lopcodes.h"
namespace Lua {
+void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize) {
+ global_State *globalState = G(luaState);
+
+ block = (*globalState->frealloc)(globalState->ud, block, osize, nsize);
+ globalState->totalbytes = (globalState->totalbytes - osize) + nsize;
+
+ return block;
+}
+
void pushObject(lua_State *luaState, TValue *obj) {
setobj2s(luaState, luaState->top, obj);
@@ -74,4 +84,263 @@ StkId getObject(lua_State *luaState, int stackpos) {
}
}
+void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
+ global_State *globalState = G(luaState);
+
+ obj->gch.next = globalState->rootgc;
+ globalState->rootgc = obj;
+ obj->gch.marked = luaC_white(globalState);
+ obj->gch.tt = type;
+}
+
+Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable) {
+ Closure *c = (Closure *)lua_malloc(luaState, sizeLclosure(numElements));
+ lua_linkObjToGC(luaState, obj2gco(c), LUA_TFUNCTION);
+
+ c->l.isC = 0;
+ c->l.env = elementTable;
+ c->l.nupvalues = cast_byte(numElements);
+
+ while (numElements--) {
+ c->l.upvals[numElements] = NULL;
+ }
+
+ return c;
+}
+
+void pushClosure(lua_State *luaState, Closure *closure) {
+ TValue obj;
+ setclvalue(luaState, &obj, closure);
+ pushObject(luaState, &obj);
+}
+
+Proto *createProto(lua_State *luaState) {
+ Proto *newProto = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_linkObjToGC(luaState, obj2gco(newProto), LUA_TPROTO);
+
+ newProto->k = NULL;
+ newProto->sizek = 0;
+ newProto->p = NULL;
+ newProto->sizep = 0;
+ newProto->code = NULL;
+ newProto->sizecode = 0;
+ newProto->sizelineinfo = 0;
+ newProto->sizeupvalues = 0;
+ newProto->nups = 0;
+ newProto->upvalues = NULL;
+ newProto->numparams = 0;
+ newProto->is_vararg = 0;
+ newProto->maxstacksize = 0;
+ newProto->lineinfo = NULL;
+ newProto->sizelocvars = 0;
+ newProto->locvars = NULL;
+ newProto->linedefined = 0;
+ newProto->lastlinedefined = 0;
+ newProto->source = NULL;
+
+ return newProto;
+}
+
+TString *createString(lua_State *luaState, const char *str, size_t len) {
+ TString *res;
+ lua_pushlstring(luaState, str, len);
+
+ res = rawtsvalue(luaState->top - 1);
+ lua_pop(luaState, 1);
+
+ return res;
+}
+
+Proto *makeFakeProto(lua_State *L, lu_byte nups) {
+ Proto *p = createProto(L);
+
+ p->sizelineinfo = 1;
+ p->lineinfo = lua_newVector(L, 1, int);
+ p->lineinfo[0] = 1;
+ p->sizecode = 1;
+ p->code = lua_newVector(L, 1, Instruction);
+ p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ p->source = createString(L, "", 0);
+ p->maxstacksize = 2;
+ p->nups = nups;
+ p->sizek = 0;
+ p->sizep = 0;
+
+ return p;
+}
+
+UpVal *createUpValue(lua_State *luaState, int stackpos) {
+ UpVal *upValue = (UpVal *)lua_malloc(luaState, sizeof(UpVal));
+ lua_linkObjToGC(luaState, (GCObject *)upValue, LUA_TUPVAL);
+ upValue->tt = LUA_TUPVAL;
+ upValue->v = &upValue->u.value;
+ upValue->u.l.prev = NULL;
+ upValue->u.l.next = NULL;
+
+ const TValue *o2 = (TValue *)getObject(luaState, stackpos);
+ upValue->v->value = o2->value;
+ upValue->v->tt = o2->tt;
+ checkliveness(G(L), upValue->v);
+
+ return upValue;
+}
+
+void unboxUpValue(lua_State *luaState) {
+ // >>>>> ...... func
+ LClosure *lcl;
+ UpVal *uv;
+
+ lcl = (LClosure *)clvalue(getObject(luaState, -1));
+ uv = lcl->upvals[0];
+
+ lua_pop(luaState, 1);
+ // >>>>> ......
+
+ pushUpValue(luaState, uv);
+ // >>>>> ...... upValue
+}
+
+size_t appendStackToStack_reverse(lua_State *from, lua_State *to) {
+ for (StkId id = from->top - 1; id >= from->stack; --id) {
+ setobj2s(to, to->top, id);
+ to->top++;
+ }
+
+ return from->top - from->stack;
+}
+
+void correctStack(lua_State *L, TValue *oldstack) {
+ CallInfo *ci;
+ GCObject *up;
+ L->top = (L->top - oldstack) + L->stack;
+ for (up = L->openupval; up != NULL; up = up->gch.next)
+ gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
+ for (ci = L->base_ci; ci <= L->ci; ci++) {
+ ci->top = (ci->top - oldstack) + L->stack;
+ ci->base = (ci->base - oldstack) + L->stack;
+ ci->func = (ci->func - oldstack) + L->stack;
+ }
+ L->base = (L->base - oldstack) + L->stack;
+}
+
+void lua_reallocstack(lua_State *L, int newsize) {
+ TValue *oldstack = L->stack;
+ int realsize = newsize + 1 + EXTRA_STACK;
+
+ lua_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
+ L->stacksize = realsize;
+ L->stack_last = L->stack + newsize;
+ correctStack(L, oldstack);
+}
+
+void lua_growstack(lua_State *L, int n) {
+ // Double size is enough?
+ if (n <= L->stacksize) {
+ lua_reallocstack(L, 2 * L->stacksize);
+ } else {
+ lua_reallocstack(L, L->stacksize + n);
+ }
+}
+
+void lua_reallocCallInfo(lua_State *lauState, int newsize) {
+ CallInfo *oldci = lauState->base_ci;
+ lua_reallocvector(lauState, lauState->base_ci, lauState->size_ci, newsize, CallInfo);
+
+ lauState->size_ci = newsize;
+ lauState->ci = (lauState->ci - oldci) + lauState->base_ci;
+ lauState->end_ci = lauState->base_ci + lauState->size_ci - 1;
+}
+
+void GCUnlink(lua_State *luaState, GCObject *gco) {
+ GCObject *prevslot;
+ if (G(luaState)->rootgc == gco) {
+ G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
+ return;
+ }
+
+ prevslot = G(luaState)->rootgc;
+ while (prevslot->gch.next != gco) {
+ prevslot = prevslot->gch.next;
+ }
+
+ prevslot->gch.next = prevslot->gch.next->gch.next;
+}
+
+TString *lua_newlstr(lua_State *luaState, const char *str, size_t len) {
+ lua_pushlstring(luaState, str, len);
+ TString *luaStr = &(luaState->top - 1)->value.gc->ts;
+
+ lua_pop(luaState, 1);
+
+ return luaStr;
+}
+
+void lua_link(lua_State *luaState, GCObject *o, lu_byte tt) {
+ global_State *g = G(luaState);
+ o->gch.next = g->rootgc;
+ g->rootgc = o;
+ o->gch.marked = luaC_white(g);
+ o->gch.tt = tt;
+}
+
+Proto *lua_newproto(lua_State *luaState) {
+ Proto *f = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_link(luaState, obj2gco(f), LUA_TPROTO);
+ f->k = NULL;
+ f->sizek = 0;
+ f->p = NULL;
+ f->sizep = 0;
+ f->code = NULL;
+ f->sizecode = 0;
+ f->sizelineinfo = 0;
+ f->sizeupvalues = 0;
+ f->nups = 0;
+ f->upvalues = NULL;
+ f->numparams = 0;
+ f->is_vararg = 0;
+ f->maxstacksize = 0;
+ f->lineinfo = NULL;
+ f->sizelocvars = 0;
+ f->locvars = NULL;
+ f->linedefined = 0;
+ f->lastlinedefined = 0;
+ f->source = NULL;
+ return f;
+}
+
+UpVal *makeUpValue(lua_State *luaState, int stackPos) {
+ UpVal *uv = lua_new(luaState, UpVal);
+ lua_link(luaState, (GCObject *)uv, LUA_TUPVAL);
+ uv->tt = LUA_TUPVAL;
+ uv->v = &uv->u.value;
+ uv->u.l.prev = NULL;
+ uv->u.l.next = NULL;
+
+ setobj(luaState, uv->v, getObject(luaState, stackPos));
+
+ return uv;
+}
+
+void boxUpValue_start(lua_State *luaState) {
+ LClosure *closure;
+ closure = (LClosure *)lua_newLclosure(luaState, 1, hvalue(&luaState->l_gt));
+ pushClosure(luaState, (Closure *)closure);
+ // >>>>> ...... func
+ closure->p = makeFakeProto(luaState, 1);
+
+ // Temporarily initialize the upvalue to nil
+ lua_pushnil(luaState);
+ closure->upvals[0] = makeUpValue(luaState, -1);
+ lua_pop(luaState, 1);
+}
+
+void boxUpValue_finish(lua_State *luaState) {
+ // >>>>> ...... func obj
+ LClosure *lcl = (LClosure *)clvalue(getObject(luaState, -2));
+
+ lcl->upvals[0]->u.value = *getObject(luaState, -1);
+ lua_pop(luaState, 1);
+ // >>>>> ...... func
+}
+
} // End of namespace Lua
diff --git a/engines/sword25/util/lua_serialization_util.h b/engines/sword25/util/lua_serialization_util.h
index 6c55d0dd53..345996f606 100644
--- a/engines/sword25/util/lua_serialization_util.h
+++ b/engines/sword25/util/lua_serialization_util.h
@@ -32,12 +32,67 @@ typedef TValue *StkId;
namespace Lua {
+#define lua_malloc(luaState, nsize) lua_realloc(luaState, nullptr, 0, nsize)
+#define lua_reallocv(luaState, block, on, n, e) lua_realloc(luaState, block, (on) * (e), (n) * (e))
+#define lua_reallocvector(luaState, vec, oldn, n, T) ((vec) = (T *)(lua_reallocv(luaState, vec, oldn, n, sizeof(T))))
+#define lua_newVector(luaState, num, T) ((T *)lua_reallocv(luaState, nullptr, 0, num, sizeof(T)))
+#define lua_new(luaState,T) (T *)lua_malloc(luaState, sizeof(T))
+
+void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize);
+
void pushObject(lua_State *luaState, TValue *obj);
void pushProto(lua_State *luaState, Proto *proto);
void pushUpValue(lua_State *luaState, UpVal *upval);
void pushString(lua_State *luaState, TString *str);
+
StkId getObject(lua_State *luaState, int stackpos);
+void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type);
+
+#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
+
+Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable);
+void pushClosure(lua_State *luaState, Closure *closure);
+
+Proto *createProto(lua_State *luaState);
+Proto *makeFakeProto(lua_State *L, lu_byte nups);
+
+TString *createString(lua_State *luaState, const char *str, size_t len);
+
+UpVal *createUpValue(lua_State *luaState, int stackpos);
+void unboxUpValue(lua_State *luaState);
+
+/* Appends one stack to another stack, but the stack is reversed in the process */
+size_t appendStackToStack_reverse(lua_State *from, lua_State *to);
+void correctStack(lua_State *L, TValue *oldstack);
+void lua_reallocstack(lua_State *L, int newsize);
+void lua_growstack(lua_State *L, int n);
+
+void lua_reallocCallInfo(lua_State *lauState, int newsize);
+
+/* Does basically the opposite of luaC_link().
+ * Right now this function is rather inefficient; it requires traversing the
+ * entire root GC set in order to find one object. If the GC list were doubly
+ * linked this would be much easier, but there's no reason for Lua to have
+ * that. */
+void GCUnlink(lua_State *luaState, GCObject *gco);
+
+TString *lua_newlstr(lua_State *luaState, const char *str, size_t len);
+void lua_link(lua_State *luaState, GCObject *o, lu_byte tt);
+Proto *lua_newproto(lua_State *luaState) ;
+
+UpVal *makeUpValue(lua_State *luaState, int stackPos);
+/**
+ * The GC is not fond of finding upvalues in tables. We get around this
+ * during persistence using a weakly keyed table, so that the GC doesn't
+ * bother to mark them. This won't work in unpersisting, however, since
+ * if we make the values weak they'll be collected (since nothing else
+ * references them). Our solution, during unpersisting, is to represent
+ * upvalues as dummy functions, each with one upvalue.
+ */
+void boxUpValue_start(lua_State *luaState);
+void boxUpValue_finish(lua_State *luaState);
+
} // End of namespace Lua
#endif
diff --git a/engines/sword25/util/lua_serializer.cpp b/engines/sword25/util/lua_serializer.cpp
index c6c5f99342..55b6257324 100644
--- a/engines/sword25/util/lua_serializer.cpp
+++ b/engines/sword25/util/lua_serializer.cpp
@@ -42,7 +42,7 @@ struct SerializationInfo {
uint counter;
};
-static void serializeObject(SerializationInfo *info);
+static void serialize(SerializationInfo *info);
static void serializeBoolean(SerializationInfo *info);
static void serializeNumber(SerializationInfo *info);
@@ -103,14 +103,14 @@ void serializeLua(lua_State *luaState, Common::WriteStream *writeStream) {
// >>>>> permTbl indexTbl rootObj
// Serialize the root recursively
- serializeObject(&info);
+ serialize(&info);
// Return the stack back to the original state
lua_remove(luaState, 2);
// >>>>> permTbl rootObj
}
-static void serializeObject(SerializationInfo *info) {
+static void serialize(SerializationInfo *info) {
// The stack can potentially have many things on it
// The object we want to serialize is the item on the top of the stack
// >>>>> permTbl indexTbl rootObj ...... obj
@@ -188,7 +188,7 @@ static void serializeObject(SerializationInfo *info) {
info->writeStream->writeSint32LE(PERMANENT_TYPE);
// Serialize the key
- serializeObject(info);
+ serialize(info);
// Pop the key off the stack
lua_pop(info->luaState, 1);
@@ -368,7 +368,7 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
info->writeStream->writeSint32LE(1);
// Serialize the function
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 2);
// >>>>> permTbl indexTbl ...... obj
@@ -395,7 +395,7 @@ static void serializeTable(SerializationInfo *info) {
}
// >>>>> permTbl indexTbl ...... tbl metaTbl/nil */
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl
@@ -412,13 +412,13 @@ static void serializeTable(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... tbl k v k */
// Serialize the key
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl k v */
// Serialize the value
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl k */
@@ -430,7 +430,7 @@ static void serializeTable(SerializationInfo *info) {
lua_pushnil(info->luaState);
// >>>>> permTbl indexTbl ...... tbl
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl
@@ -457,7 +457,7 @@ static void serializeFunction(SerializationInfo *info) {
pushProto(info->luaState, cl->l.p);
// >>>>> permTbl indexTbl ...... func proto */
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
@@ -468,7 +468,7 @@ static void serializeFunction(SerializationInfo *info) {
pushUpValue(info->luaState, cl->l.upvals[i]);
// >>>>> permTbl indexTbl ...... func upval
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
@@ -492,23 +492,13 @@ static void serializeFunction(SerializationInfo *info) {
}
// >>>>> permTbl indexTbl ...... func fenv/nil
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
}
}
-/* Appends one stack to another stack, but the stack is reversed in the process */
-static size_t appendStackToStack_rev(lua_State *from, lua_State *to) {
- for (StkId id = from->top - 1; id >= from->stack; --id) {
- setobj2s(to, to->top, id);
- to->top++;
- }
-
- return from->top - from->stack;
-}
-
static void serializeThread(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... thread
lua_State *threadState = lua_tothread(info->luaState, -1);
@@ -525,12 +515,12 @@ static void serializeThread(SerializationInfo *info) {
// Persist the stack
// We *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
- uint32 stackSize = static_cast(appendStackToStack_rev(threadState, info->luaState));
+ uint32 stackSize = static_cast(appendStackToStack_reverse(threadState, info->luaState));
info->writeStream->writeUint32LE(stackSize);
// >>>>> permTbl indexTbl ...... thread (reversed contents of thread stack) */
for (; stackSize > 0; --stackSize) {
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
}
@@ -592,7 +582,7 @@ static void serializeThread(SerializationInfo *info) {
pushUpValue(info->luaState, upVal);
// >>>>> permTbl indexTbl ...... thread upVal
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... thread
@@ -607,7 +597,7 @@ static void serializeThread(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... thread nil
// Use nil as a terminator
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... thread
@@ -627,7 +617,7 @@ static void serializeProto(SerializationInfo *info) {
pushObject(info->luaState, &proto->k[i]);
// >>>>> permTbl indexTbl ...... proto const
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -643,7 +633,7 @@ static void serializeProto(SerializationInfo *info) {
pushProto(info->luaState, proto->p[i]);
// >>>>> permTbl indexTbl ...... proto subProto */
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -666,7 +656,7 @@ static void serializeProto(SerializationInfo *info) {
pushString(info->luaState, proto->upvalues[i]);
// >>>>> permTbl indexTbl ...... proto str
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -680,7 +670,7 @@ static void serializeProto(SerializationInfo *info) {
pushString(info->luaState, proto->locvars[i].varname);
// >>>>> permTbl indexTbl ...... proto str
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -694,7 +684,7 @@ static void serializeProto(SerializationInfo *info) {
pushString(info->luaState, proto->source);
// >>>>> permTbl indexTbl ...... proto sourceStr
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -757,7 +747,7 @@ static void serializeUpValue(SerializationInfo *info) {
pushObject(info->luaState, upValue->v);
// >>>>> permTbl indexTbl ...... obj
- serializeObject(info);
+ serialize(info);
// >>>>> permTbl indexTbl ...... obj
}
@@ -787,7 +777,7 @@ static void serializeUserData(SerializationInfo *info) {
}
// >>>>> permTbl rootObj ...... udata metaTbl/nil
- serializeObject(info);
+ serialize(info);
lua_pop(info->luaState, 1);
/* perms reftbl ... udata */
diff --git a/engines/sword25/util/lua_unserializer.cpp b/engines/sword25/util/lua_unserializer.cpp
index 69cb764dd2..803c79c8c2 100644
--- a/engines/sword25/util/lua_unserializer.cpp
+++ b/engines/sword25/util/lua_unserializer.cpp
@@ -40,7 +40,7 @@ struct UnSerializationInfo {
Common::ReadStream *readStream;
};
-static void unserializeObject(UnSerializationInfo *info);
+static void unserialize(UnSerializationInfo *info);
static void unserializeBoolean(UnSerializationInfo *info);
static void unserializeNumber(UnSerializationInfo *info);
@@ -74,7 +74,7 @@ void unserializeLua(lua_State *luaState, Common::ReadStream *readStream) {
lua_gc(luaState, LUA_GCSTOP, 0);
// Unserialize the root object
- unserializeObject(&info);
+ unserialize(&info);
// >>>>> permTbl indexTbl rootObj
// Re-start garbage collection
@@ -85,7 +85,7 @@ void unserializeLua(lua_State *luaState, Common::ReadStream *readStream) {
// >>>>> permTbl rootObj
}
-/* The object is left on the stack. This is primarily used by unpersist, but
+/* The object is left on the stack. This is primarily used by unserialize, but
* may be used by GCed objects that may incur cycles in order to preregister
* the object. */
static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
@@ -105,7 +105,7 @@ static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... obj
}
-static void unserializeObject(UnSerializationInfo *info) {
+static void unserialize(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -241,7 +241,7 @@ static void unserializeSpecialTable(UnSerializationInfo *info, int index) {
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 1);
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... spfunc
lua_call(info->luaState, 0, 1);
@@ -262,7 +262,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... tbl
// Unserialize metatable
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
if (lua_istable(info->luaState, -1)) {
@@ -279,7 +279,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
while (1) {
// >>>>> permTbl indexTbl ...... tbl
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... tbl key/nil
// The table serialization is nil terminated
@@ -292,7 +292,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
}
// >>>>> permTbl indexTbl ...... tbl key
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... tbl value
lua_rawset(info->luaState, -3);
@@ -317,142 +317,6 @@ void unserializeTable(UnSerializationInfo *info, int index) {
}
}
-
-
-void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize) {
- global_State *globalState = G(luaState);
-
- block = (*globalState->frealloc)(globalState->ud, block, osize, nsize);
- globalState->totalbytes = (globalState->totalbytes - osize) + nsize;
-
- return block;
-}
-
-#define lua_malloc(luaState, nsize) lua_realloc(luaState, nullptr, 0, nsize)
-#define lua_reallocv(luaState, block, on, n, e) lua_realloc(luaState, block, (on) * (e), (n) * (e))
-#define lua_reallocvector(luaState, vec, oldn, n, T) ((vec) = (T *)(lua_reallocv(luaState, vec, oldn, n, sizeof(T))))
-#define lua_newVector(luaState, num, T) ((T *)lua_reallocv(luaState, nullptr, 0, num, sizeof(T)))
-#define lua_new(luaState,T) (T *)lua_malloc(luaState, sizeof(T))
-
-void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
- global_State *globalState = G(luaState);
-
- obj->gch.next = globalState->rootgc;
- globalState->rootgc = obj;
- obj->gch.marked = luaC_white(globalState);
- obj->gch.tt = type;
-}
-
-#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
-
-Closure *newLClosure(lua_State *luaState, byte numUpValues, Table *env) {
- Closure *newClosure = (Closure *)lua_malloc(luaState, sizeLclosure(numUpValues));
-
- lua_linkObjToGC(luaState, obj2gco(newClosure), LUA_TFUNCTION);
-
- newClosure->l.isC = 0;
- newClosure->l.env = env;
- newClosure->l.nupvalues = numUpValues;
-
- while (numUpValues--) {
- newClosure->l.upvals[numUpValues] = NULL;
- }
-
- return newClosure;
-}
-
-static void pushClosure(lua_State *luaState, Closure *closure) {
- TValue obj;
- setclvalue(luaState, &obj, closure);
- pushObject(luaState, &obj);
-}
-
-Proto *createProto(lua_State *luaState) {
- Proto *newProto = (Proto *)lua_malloc(luaState, sizeof(Proto));
- lua_linkObjToGC(luaState, obj2gco(newProto), LUA_TPROTO);
-
- newProto->k = NULL;
- newProto->sizek = 0;
- newProto->p = NULL;
- newProto->sizep = 0;
- newProto->code = NULL;
- newProto->sizecode = 0;
- newProto->sizelineinfo = 0;
- newProto->sizeupvalues = 0;
- newProto->nups = 0;
- newProto->upvalues = NULL;
- newProto->numparams = 0;
- newProto->is_vararg = 0;
- newProto->maxstacksize = 0;
- newProto->lineinfo = NULL;
- newProto->sizelocvars = 0;
- newProto->locvars = NULL;
- newProto->linedefined = 0;
- newProto->lastlinedefined = 0;
- newProto->source = NULL;
-
- return newProto;
-}
-
-TString *createString(lua_State *luaState, const char *str, size_t len) {
- TString *res;
- lua_pushlstring(luaState, str, len);
-
- res = rawtsvalue(luaState->top - 1);
- lua_pop(luaState, 1);
-
- return res;
-}
-
-static Proto *makeFakeProto(lua_State *L, lu_byte nups) {
- Proto *p = createProto(L);
-
- p->sizelineinfo = 1;
- p->lineinfo = lua_newVector(L, 1, int);
- p->lineinfo[0] = 1;
- p->sizecode = 1;
- p->code = lua_newVector(L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->source = createString(L, "", 0);
- p->maxstacksize = 2;
- p->nups = nups;
- p->sizek = 0;
- p->sizep = 0;
-
- return p;
-}
-
-static UpVal *createUpValue(lua_State *luaState, int stackpos) {
- UpVal *upValue = (UpVal *)lua_malloc(luaState, sizeof(UpVal));
- lua_linkObjToGC(luaState, (GCObject *)upValue, LUA_TUPVAL);
- upValue->tt = LUA_TUPVAL;
- upValue->v = &upValue->u.value;
- upValue->u.l.prev = NULL;
- upValue->u.l.next = NULL;
-
- const TValue *o2 = (TValue *)getObject(luaState, stackpos);
- upValue->v->value = o2->value;
- upValue->v->tt = o2->tt;
- checkliveness(G(L), upValue->v);
-
- return upValue;
-}
-
-static void unboxUpValue(lua_State *luaState) {
- // >>>>> ...... func
- LClosure *lcl;
- UpVal *uv;
-
- lcl = (LClosure *)clvalue(getObject(luaState, -1));
- uv = lcl->upvals[0];
-
- lua_pop(luaState, 1);
- // >>>>> ......
-
- pushUpValue(luaState, uv);
- // >>>>> ...... upValue
-}
-
void unserializeFunction(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
@@ -461,7 +325,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
byte numUpValues = info->readStream->readByte();
- LClosure *lclosure = (LClosure *)newLClosure(info->luaState, numUpValues, hvalue(&info->luaState->l_gt));
+ LClosure *lclosure = (LClosure *)lua_newLclosure(info->luaState, numUpValues, hvalue(&info->luaState->l_gt));
pushClosure(info->luaState, (Closure *)lclosure);
// >>>>> permTbl indexTbl ...... func
@@ -484,7 +348,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
registerObjectInIndexTable(info, index);
// Now that it's safe, we can get the real proto
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... func proto
lclosure->p = gco2p(getObject(info->luaState, -1)->value.gc);
@@ -494,7 +358,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
for (byte i = 0; i < numUpValues; ++i) {
// >>>>> permTbl indexTbl ...... func
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... func func2
unboxUpValue(info->luaState);
@@ -506,7 +370,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
}
// Finally, the fenv
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... func ?fenv/nil?
if (!lua_isnil(info->luaState, -1)) {
@@ -522,81 +386,6 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... func
}
-static void correctStack(lua_State *L, TValue *oldstack) {
- CallInfo *ci;
- GCObject *up;
- L->top = (L->top - oldstack) + L->stack;
- for (up = L->openupval; up != NULL; up = up->gch.next)
- gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
- for (ci = L->base_ci; ci <= L->ci; ci++) {
- ci->top = (ci->top - oldstack) + L->stack;
- ci->base = (ci->base - oldstack) + L->stack;
- ci->func = (ci->func - oldstack) + L->stack;
- }
- L->base = (L->base - oldstack) + L->stack;
-}
-
-void lua_reallocstack(lua_State *L, int newsize) {
- TValue *oldstack = L->stack;
- int realsize = newsize + 1 + EXTRA_STACK;
-
- lua_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
- L->stacksize = realsize;
- L->stack_last = L->stack + newsize;
- correctStack(L, oldstack);
-}
-
-void lua_growstack(lua_State *L, int n) {
- // Double size is enough?
- if (n <= L->stacksize) {
- lua_reallocstack(L, 2 * L->stacksize);
- } else {
- lua_reallocstack(L, L->stacksize + n);
- }
-}
-
-void lua_reallocCallInfo(lua_State *lauState, int newsize) {
- CallInfo *oldci = lauState->base_ci;
- lua_reallocvector(lauState, lauState->base_ci, lauState->size_ci, newsize, CallInfo);
-
- lauState->size_ci = newsize;
- lauState->ci = (lauState->ci - oldci) + lauState->base_ci;
- lauState->end_ci = lauState->base_ci + lauState->size_ci - 1;
-}
-
-void unboxUpVal(lua_State *luaState) {
- // >>>>> ... func
- LClosure *lcl;
- UpVal *uv;
-
- lcl = (LClosure *)(&getObject(luaState, -1)->value.gc->cl);
- uv = lcl->upvals[0];
- lua_pop(luaState, 1);
- // >>>>> ...
- pushUpValue(luaState, uv);
- // >>>>> ... upVal
-}
-
-/* Does basically the opposite of luaC_link().
- * Right now this function is rather inefficient; it requires traversing the
- * entire root GC set in order to find one object. If the GC list were doubly
- * linked this would be much easier, but there's no reason for Lua to have
- * that. */
-static void GCUnlink(lua_State *luaState, GCObject *gco) {
- GCObject *prevslot;
- if (G(luaState)->rootgc == gco) {
- G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
- return;
- }
-
- prevslot = G(luaState)->rootgc;
- while (prevslot->gch.next != gco) {
- prevslot = prevslot->gch.next;
- }
-
- prevslot->gch.next = prevslot->gch.next->gch.next;
-}
-
void unserializeThread(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
@@ -619,7 +408,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
// very bottom of the stack
L2->top--;
for (uint32 i = 0; i < stackSize; ++i) {
- unserializeObject(info);
+ unserialize(info);
// L1: permTbl indexTbl ...... thread obj*
}
@@ -679,7 +468,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
global_State *g = G(L2);
while (true) {
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... thread upVal/nil
// The list is terminated by a nil
@@ -691,7 +480,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
}
// >>>>> permTbl indexTbl ...... thread boxedUpVal
- unboxUpVal(info->luaState);
+ unboxUpValue(info->luaState);
// >>>>> permTbl indexTbl ...... thread boxedUpVal
uv = &(getObject(info->luaState, -1)->value.gc->uv);
@@ -722,48 +511,6 @@ void unserializeThread(UnSerializationInfo *info, int index) {
}
}
-TString *lua_newlstr(lua_State *luaState, const char *str, size_t len) {
- lua_pushlstring(luaState, str, len);
- TString *luaStr = &(luaState->top - 1)->value.gc->ts;
-
- lua_pop(luaState, 1);
-
- return luaStr;
-}
-
-void lua_link(lua_State *luaState, GCObject *o, lu_byte tt) {
- global_State *g = G(luaState);
- o->gch.next = g->rootgc;
- g->rootgc = o;
- o->gch.marked = luaC_white(g);
- o->gch.tt = tt;
-}
-
-Proto *lua_newproto(lua_State *luaState) {
- Proto *f = (Proto *)lua_malloc(luaState, sizeof(Proto));
- lua_link(luaState, obj2gco(f), LUA_TPROTO);
- f->k = NULL;
- f->sizek = 0;
- f->p = NULL;
- f->sizep = 0;
- f->code = NULL;
- f->sizecode = 0;
- f->sizelineinfo = 0;
- f->sizeupvalues = 0;
- f->nups = 0;
- f->upvalues = NULL;
- f->numparams = 0;
- f->is_vararg = 0;
- f->maxstacksize = 0;
- f->lineinfo = NULL;
- f->sizelocvars = 0;
- f->locvars = NULL;
- f->linedefined = 0;
- f->lastlinedefined = 0;
- f->source = NULL;
- return f;
-}
-
void unserializeProto(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
@@ -793,7 +540,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
for (int i = 0; i < sizek; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... proto k
setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
@@ -810,7 +557,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
for (int i = 0; i < sizep; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... proto subproto
p->p[i] = (Proto *)getObject(info->luaState, -1)->value.gc;
@@ -834,7 +581,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
for (int i = 0; i < p->sizeupvalues; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... proto str
p->upvalues[i] = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
@@ -850,7 +597,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
for (int i = 0; i < p->sizelocvars; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... proto str
p->locvars[i].varname = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
@@ -864,7 +611,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... proto
// Read in source string
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... proto sourceStr
p->source = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
@@ -890,75 +637,18 @@ void unserializeProto(UnSerializationInfo *info, int index) {
p->maxstacksize = info->readStream->readByte();
}
-Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable) {
- Closure *c = (Closure *)lua_malloc(luaState, sizeLclosure(numElements));
- lua_link(luaState, obj2gco(c), LUA_TFUNCTION);
- c->l.isC = 0;
- c->l.env = elementTable;
- c->l.nupvalues = cast_byte(numElements);
-
- while (numElements--) {
- c->l.upvals[numElements] = NULL;
- }
-
- return c;
-}
-
-static UpVal *makeUpVal(lua_State *luaState, int stackPos) {
- UpVal *uv = lua_new(luaState, UpVal);
- lua_link(luaState, (GCObject *)uv, LUA_TUPVAL);
- uv->tt = LUA_TUPVAL;
- uv->v = &uv->u.value;
- uv->u.l.prev = NULL;
- uv->u.l.next = NULL;
-
- setobj(luaState, uv->v, getObject(luaState, stackPos));
-
- return uv;
-}
-
-/**
- * The GC is not fond of finding upvalues in tables. We get around this
- * during persistence using a weakly keyed table, so that the GC doesn't
- * bother to mark them. This won't work in unpersisting, however, since
- * if we make the values weak they'll be collected (since nothing else
- * references them). Our solution, during unpersisting, is to represent
- * upvalues as dummy functions, each with one upvalue.
- */
-static void boxupval_start(lua_State *luaState) {
- LClosure *closure;
- closure = (LClosure *)lua_newLclosure(luaState, 1, hvalue(&luaState->l_gt));
- pushClosure(luaState, (Closure *)closure);
- // >>>>> ...... func
- closure->p = makeFakeProto(luaState, 1);
-
- // Temporarily initialize the upvalue to nil
- lua_pushnil(luaState);
- closure->upvals[0] = makeUpVal(luaState, -1);
- lua_pop(luaState, 1);
-}
-
-static void boxupval_finish(lua_State *luaState) {
- // >>>>> ...... func obj
- LClosure *lcl = (LClosure *)clvalue(getObject(luaState, -2));
-
- lcl->upvals[0]->u.value = *getObject(luaState, -1);
- lua_pop(luaState, 1);
- // >>>>> ...... func
-}
-
void unserializeUpValue(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
- lua_checkstack(upi->L, 2);
+ lua_checkstack(info->luaState, 2);
- boxupval_start(upi->L);
+ boxUpValue_start(info->luaState);
// >>>>> permTbl indexTbl ...... func
registerObjectInIndexTable(info, index);
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... func obj
- boxupval_finish(upi->L);
+ boxUpValue_finish(info->luaState);
// >>>>> permTbl indexTbl ...... func
}
@@ -970,7 +660,7 @@ void unserializeUserData(UnSerializationInfo *info, int index) {
int isspecial = info->readStream->readSint32LE();
if (isspecial) {
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... specialFunc
lua_call(info->luaState, 0, 1);
@@ -981,12 +671,12 @@ void unserializeUserData(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... udata
registerObjectInIndexTable(info, index);
- info->readStream->read(lua_touserdata(upi->L, -1), length);
+ info->readStream->read(lua_touserdata(info->luaState, -1), length);
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... udata metaTable/nil
- lua_setmetatable(upi->L, -2);
+ lua_setmetatable(info->luaState, -2);
// >>>>> permTbl indexTbl ...... udata
}
// >>>>> permTbl indexTbl ...... udata
@@ -998,7 +688,7 @@ void unserializePermanent(UnSerializationInfo *info, int index) {
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 2);
- unserializeObject(info);
+ unserialize(info);
// >>>>> permTbl indexTbl ...... permKey
lua_gettable(info->luaState, 1);
--
cgit v1.2.3
From 0b8482b55fb38147927d2c27478aae59c0f98dab Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 13:42:02 -0600
Subject: SWORD25: Update module.mk with lua serialization changes
---
engines/sword25/module.mk | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/engines/sword25/module.mk b/engines/sword25/module.mk
index 234baec165..0135f53783 100644
--- a/engines/sword25/module.mk
+++ b/engines/sword25/module.mk
@@ -82,9 +82,10 @@ MODULE_OBJS := \
util/lua/lvm.o \
util/lua/lzio.o \
util/lua/scummvm_file.o \
- util/pluto/pdep.o \
- util/pluto/pluto.o \
- util/pluto/plzio.o
+ util/double_serializer.o \
+ util/lua_serialization_util.o \
+ util/lua_serializer.o \
+ util/lua_unserializer.o
# This module can be built as a plugin
ifeq ($(ENABLE_SWORD25), DYNAMIC_PLUGIN)
--
cgit v1.2.3
From a188b31d15711bd86725ca4feb0dc36fb2ab71ac Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 13:42:45 -0600
Subject: SWORD25: Use new lua serialization functions to persist state
---
engines/sword25/kernel/outputpersistenceblock.cpp | 7 +++
engines/sword25/kernel/outputpersistenceblock.h | 1 +
engines/sword25/script/luascript.cpp | 61 +++++------------------
3 files changed, 20 insertions(+), 49 deletions(-)
diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp
index 9003b5d58a..3e25fce5c7 100644
--- a/engines/sword25/kernel/outputpersistenceblock.cpp
+++ b/engines/sword25/kernel/outputpersistenceblock.cpp
@@ -41,6 +41,13 @@ OutputPersistenceBlock::OutputPersistenceBlock() {
_data.reserve(INITIAL_BUFFER_SIZE);
}
+void OutputPersistenceBlock::write(const void *data, uint32 size) {
+ writeMarker(BLOCK_MARKER);
+
+ write(size);
+ rawWrite(data, size);
+}
+
void OutputPersistenceBlock::write(int32 value) {
writeMarker(SINT_MARKER);
value = TO_LE_32(value);
diff --git a/engines/sword25/kernel/outputpersistenceblock.h b/engines/sword25/kernel/outputpersistenceblock.h
index c7d8dfc6aa..bdbd20d3e0 100644
--- a/engines/sword25/kernel/outputpersistenceblock.h
+++ b/engines/sword25/kernel/outputpersistenceblock.h
@@ -41,6 +41,7 @@ class OutputPersistenceBlock : public PersistenceBlock {
public:
OutputPersistenceBlock();
+ void write(const void *data, uint32 size);
void write(int32 value);
void write(uint32 value);
void write(float value);
diff --git a/engines/sword25/script/luascript.cpp b/engines/sword25/script/luascript.cpp
index f62a08005b..6cf287c643 100644
--- a/engines/sword25/script/luascript.cpp
+++ b/engines/sword25/script/luascript.cpp
@@ -29,7 +29,7 @@
*
*/
-#include "common/array.h"
+#include "common/memstream.h"
#include "common/debug-channels.h"
#include "sword25/sword25.h"
@@ -43,7 +43,7 @@
#include "sword25/util/lua/lua.h"
#include "sword25/util/lua/lualib.h"
#include "sword25/util/lua/lauxlib.h"
-#include "sword25/util/pluto/pluto.h"
+#include "sword25/util/lua_serialization.h"
namespace Sword25 {
@@ -112,10 +112,6 @@ bool LuaScriptEngine::init() {
// Place the error handler function in the Lua registry, and remember the index
_pcallErrorhandlerRegistryIndex = luaL_ref(_state, LUA_REGISTRYINDEX);
- // Initialize the Pluto-Persistence library
- luaopen_pluto(_state);
- lua_pop(_state, 1);
-
// Initialize debugging callback
if (DebugMan.isDebugChannelEnabled(kDebugScript)) {
int mask = 0;
@@ -383,19 +379,8 @@ bool pushPermanentsTable(lua_State *L, PERMANENT_TABLE_TYPE tableType) {
return true;
}
-}
-
-namespace {
-int chunkwriter(lua_State *L, const void *p, size_t sz, void *ud) {
- Common::Array & chunkData = *reinterpret_cast * >(ud);
- const byte *buffer = reinterpret_cast(p);
- while (sz--)
- chunkData.push_back(*buffer++);
-
- return 1;
-}
-}
+} // End of anonymous namespace
bool LuaScriptEngine::persist(OutputPersistenceBlock &writer) {
// Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters
@@ -409,12 +394,12 @@ bool LuaScriptEngine::persist(OutputPersistenceBlock &writer) {
pushPermanentsTable(_state, PTT_PERSIST);
lua_getglobal(_state, "_G");
- // Lua persists and stores the data in a Common::Array
- Common::Array chunkData;
- pluto_persist(_state, chunkwriter, &chunkData);
+ // Lua persists and stores the data in a WriteStream
+ Common::MemoryWriteStreamDynamic writeStream;
+ Lua::serializeLua(_state, &writeStream);
// Persistenzdaten in den Writer schreiben.
- writer.writeByteArray(chunkData);
+ writer.write(writeStream.getData(), writeStream.size());
// Die beiden Tabellen vom Stack nehmen.
lua_pop(_state, 2);
@@ -424,24 +409,6 @@ bool LuaScriptEngine::persist(OutputPersistenceBlock &writer) {
namespace {
-struct ChunkreaderData {
- void *BufferPtr;
- size_t Size;
- bool BufferReturned;
-};
-
-const char *chunkreader(lua_State *L, void *ud, size_t *sz) {
- ChunkreaderData &cd = *reinterpret_cast(ud);
-
- if (!cd.BufferReturned) {
- cd.BufferReturned = true;
- *sz = cd.Size;
- return reinterpret_cast(cd.BufferPtr);
- } else {
- return 0;
- }
-}
-
void clearGlobalTable(lua_State *L, const char **exceptions) {
// Iterate over all elements of the global table
lua_pushvalue(L, LUA_GLOBALSINDEX);
@@ -479,7 +446,8 @@ void clearGlobalTable(lua_State *L, const char **exceptions) {
// Perform garbage collection, so that all removed elements are deleted
lua_gc(L, LUA_GCCOLLECT, 0);
}
-}
+
+} // End of anonymous namespace
bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) {
// Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters
@@ -512,14 +480,9 @@ bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) {
// Persisted Lua data
Common::Array chunkData;
reader.readByteArray(chunkData);
+ Common::MemoryReadStream readStream(&chunkData[0], chunkData.size(), DisposeAfterUse::NO);
- // Chunk-Reader initialisation. It is used with pluto_unpersist to restore read data
- ChunkreaderData cd;
- cd.BufferPtr = &chunkData[0];
- cd.Size = chunkData.size();
- cd.BufferReturned = false;
-
- pluto_unpersist(_state, chunkreader, &cd);
+ Lua::unserializeLua(_state, &readStream);
// Permanents-Table is removed from stack
lua_remove(_state, -2);
@@ -527,7 +490,7 @@ bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) {
// The read elements in the global table about
lua_pushnil(_state);
while (lua_next(_state, -2) != 0) {
- // The referenec to the global table (_G) must not be overwritten, or ticks from Lua total
+ // The reference to the global table (_G) must not be overwritten, or ticks from Lua total
bool isGlobalReference = lua_isstring(_state, -2) && strcmp(lua_tostring(_state, -2), "_G") == 0;
if (!isGlobalReference) {
lua_pushvalue(_state, -2);
--
cgit v1.2.3
From 97c35714ce3986b99848a780f6b195a63f8910b7 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 15:19:29 -0600
Subject: SWORD25: Rename lua serialization functions to use 'persist' in order
to match the rest of the engine
---
engines/sword25/module.mk | 6 +-
engines/sword25/script/luascript.cpp | 6 +-
engines/sword25/util/lua_persist.cpp | 787 ++++++++++++++++++++++++
engines/sword25/util/lua_persistence.h | 44 ++
engines/sword25/util/lua_persistence_util.cpp | 346 +++++++++++
engines/sword25/util/lua_persistence_util.h | 98 +++
engines/sword25/util/lua_serialization.h | 44 --
engines/sword25/util/lua_serialization_util.cpp | 346 -----------
engines/sword25/util/lua_serialization_util.h | 98 ---
engines/sword25/util/lua_serializer.cpp | 787 ------------------------
engines/sword25/util/lua_unpersist.cpp | 698 +++++++++++++++++++++
engines/sword25/util/lua_unserializer.cpp | 698 ---------------------
12 files changed, 1979 insertions(+), 1979 deletions(-)
create mode 100644 engines/sword25/util/lua_persist.cpp
create mode 100644 engines/sword25/util/lua_persistence.h
create mode 100644 engines/sword25/util/lua_persistence_util.cpp
create mode 100644 engines/sword25/util/lua_persistence_util.h
delete mode 100644 engines/sword25/util/lua_serialization.h
delete mode 100644 engines/sword25/util/lua_serialization_util.cpp
delete mode 100644 engines/sword25/util/lua_serialization_util.h
delete mode 100644 engines/sword25/util/lua_serializer.cpp
create mode 100644 engines/sword25/util/lua_unpersist.cpp
delete mode 100644 engines/sword25/util/lua_unserializer.cpp
diff --git a/engines/sword25/module.mk b/engines/sword25/module.mk
index 0135f53783..129b4f040e 100644
--- a/engines/sword25/module.mk
+++ b/engines/sword25/module.mk
@@ -83,9 +83,9 @@ MODULE_OBJS := \
util/lua/lzio.o \
util/lua/scummvm_file.o \
util/double_serializer.o \
- util/lua_serialization_util.o \
- util/lua_serializer.o \
- util/lua_unserializer.o
+ util/lua_persistence_util.o \
+ util/lua_persist.o \
+ util/lua_unpersist.o
# This module can be built as a plugin
ifeq ($(ENABLE_SWORD25), DYNAMIC_PLUGIN)
diff --git a/engines/sword25/script/luascript.cpp b/engines/sword25/script/luascript.cpp
index 6cf287c643..e93289596b 100644
--- a/engines/sword25/script/luascript.cpp
+++ b/engines/sword25/script/luascript.cpp
@@ -43,7 +43,7 @@
#include "sword25/util/lua/lua.h"
#include "sword25/util/lua/lualib.h"
#include "sword25/util/lua/lauxlib.h"
-#include "sword25/util/lua_serialization.h"
+#include "sword25/util/lua_persistence.h"
namespace Sword25 {
@@ -396,7 +396,7 @@ bool LuaScriptEngine::persist(OutputPersistenceBlock &writer) {
// Lua persists and stores the data in a WriteStream
Common::MemoryWriteStreamDynamic writeStream;
- Lua::serializeLua(_state, &writeStream);
+ Lua::persistLua(_state, &writeStream);
// Persistenzdaten in den Writer schreiben.
writer.write(writeStream.getData(), writeStream.size());
@@ -482,7 +482,7 @@ bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) {
reader.readByteArray(chunkData);
Common::MemoryReadStream readStream(&chunkData[0], chunkData.size(), DisposeAfterUse::NO);
- Lua::unserializeLua(_state, &readStream);
+ Lua::unpersistLua(_state, &readStream);
// Permanents-Table is removed from stack
lua_remove(_state, -2);
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
new file mode 100644
index 0000000000..b9c0b13e11
--- /dev/null
+++ b/engines/sword25/util/lua_persist.cpp
@@ -0,0 +1,787 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "sword25/util/lua_persistence.h"
+
+#include "sword25/util/double_serializer.h"
+#include "sword25/util/lua_persistence_util.h"
+
+#include "common/stream.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+
+
+namespace Lua {
+
+#define PERMANENT_TYPE 101
+
+struct SerializationInfo {
+ lua_State *luaState;
+ Common::WriteStream *writeStream;
+ uint counter;
+};
+
+static void serialize(SerializationInfo *info);
+
+static void serializeBoolean(SerializationInfo *info);
+static void serializeNumber(SerializationInfo *info);
+static void serializeString(SerializationInfo *info);
+static void serializeTable(SerializationInfo *info);
+static void serializeFunction(SerializationInfo *info);
+static void serializeThread(SerializationInfo *info);
+static void serializeProto(SerializationInfo *info);
+static void serializeUpValue(SerializationInfo *info);
+static void serializeUserData(SerializationInfo *info);
+
+
+void persistLua(lua_State *luaState, Common::WriteStream *writeStream) {
+ SerializationInfo info;
+ info.luaState = luaState;
+ info.writeStream = writeStream;
+ info.counter = 0u;
+
+ // The process starts with the lua stack as follows:
+ // >>>>> permTbl rootObj
+ // That's the table of permanents and the root object to be serialized
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(luaState, 4);
+ assert(lua_gettop(luaState) == 2);
+ // And that the root isn't nil
+ assert(!lua_isnil(luaState, 2));
+
+ // Create a table to hold indexes of everything that's serialized
+ // This allows us to only serialize an object once
+ // Every other time, just reference the index
+ lua_newtable(luaState);
+ // >>>>> permTbl rootObj indexTbl
+
+ // Now we're going to make the table weakly keyed. This prevents the
+ // GC from visiting it and trying to mark things it doesn't want to
+ // mark in tables, e.g. upvalues. All objects in the table are
+ // a priori reachable, so it doesn't matter that we do this.
+
+ // Create the metatable
+ lua_newtable(luaState);
+ // >>>>> permTbl rootObj indexTbl metaTbl
+
+ lua_pushstring(luaState, "__mode");
+ // >>>>> permTbl rootObj indexTbl metaTbl "__mode"
+
+ lua_pushstring(luaState, "k");
+ // >>>>> permTbl rootObj indexTbl metaTbl "__mode" "k"
+
+ lua_settable(luaState, 4);
+ // >>>>> permTbl rootObj indexTbl metaTbl
+
+ lua_setmetatable(luaState, 3);
+ // >>>>> permTbl rootObj indexTbl
+
+ // Swap the indexTable and the rootObj
+ lua_insert(luaState, 2);
+ // >>>>> permTbl indexTbl rootObj
+
+ // Serialize the root recursively
+ serialize(&info);
+
+ // Return the stack back to the original state
+ lua_remove(luaState, 2);
+ // >>>>> permTbl rootObj
+}
+
+static void serialize(SerializationInfo *info) {
+ // The stack can potentially have many things on it
+ // The object we want to serialize is the item on the top of the stack
+ // >>>>> permTbl indexTbl rootObj ...... obj
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // If the object has already been written, don't write it again
+ // Instead write the index of the object from the indexTbl
+
+ // Check the indexTbl
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ lua_rawget(info->luaState, 2);
+ // >>>>> permTbl indexTbl rootObj ...... obj ?index?
+
+ // If the index isn't nil, the object has already been written
+ if (!lua_isnil(info->luaState, -1)) {
+ // Write out a flag that indicates that it's an index
+ info->writeStream->writeByte(0);
+
+ // Retrieve the index from the stack
+ uint *index = (uint *)lua_touserdata(info->luaState, -1);
+
+ // Write out the index
+ info->writeStream->writeUint32LE(*index);
+
+ // Pop the index off the stack
+ lua_pop(info->luaState, 1);
+
+ return;
+ }
+
+ // Pop the nil off the stack
+ lua_pop(info->luaState, 1);
+
+ // Write out a flag that indicates that this is a real object
+ info->writeStream->writeByte(1);
+
+ // If the object itself is nil, then write out a zero as a placeholder
+ if (lua_isnil(info->luaState, -1)) {
+ info->writeStream->writeByte(0);
+
+ return;
+ }
+
+ // Add the object to the indexTbl
+
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ uint *ref = (uint *)lua_newuserdata(info->luaState, sizeof(uint));
+ *ref = ++(info->counter);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj index
+
+ lua_rawset(info->luaState, 2);
+ // >>>>> permTbl indexTbl rootObj ...... obj
+
+
+ // Write out the index
+ info->writeStream->writeUint32LE(info->counter);
+
+
+ // Objects that are in the permanents table are serialized in a special way
+
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ lua_gettable(info->luaState, 1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj ?permKey?
+
+ if (!lua_isnil(info->luaState, -1)) {
+ // Write out the type
+ info->writeStream->writeSint32LE(PERMANENT_TYPE);
+
+ // Serialize the key
+ serialize(info);
+
+ // Pop the key off the stack
+ lua_pop(info->luaState, 1);
+
+ return;
+ }
+
+ // Pop the nil off the stack
+ lua_pop(info->luaState, 1);
+
+ // Query the type of the object
+ int objType = lua_type(info->luaState, -1);
+
+ // Write it out
+ info->writeStream->writeSint32LE(objType);
+
+ // Serialize the object by its type
+
+ switch (objType) {
+ case LUA_TBOOLEAN:
+ serializeBoolean(info);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ // You can't serialize a pointer
+ // It would be meaningless on the next run
+ assert(0);
+ break;
+ case LUA_TNUMBER:
+ serializeNumber(info);
+ break;
+ case LUA_TSTRING:
+ serializeString(info);
+ break;
+ case LUA_TTABLE:
+ serializeTable(info);
+ break;
+ case LUA_TFUNCTION:
+ serializeFunction(info);
+ break;
+ case LUA_TTHREAD:
+ serializeThread(info);
+ break;
+ case LUA_TPROTO:
+ serializeProto(info);
+ break;
+ case LUA_TUPVAL:
+ serializeUpValue(info);
+ break;
+ case LUA_TUSERDATA:
+ serializeUserData(info);
+ break;
+ default:
+ assert(0);
+ }
+}
+
+static void serializeBoolean(SerializationInfo *info) {
+ int value = lua_toboolean(info->luaState, -1);
+
+ info->writeStream->writeSint32LE(value);
+}
+
+static void serializeNumber(SerializationInfo *info) {
+ lua_Number value = lua_tonumber(info->luaState, -1);
+
+ #if 1
+ Util::SerializedDouble serializedValue(Util::encodeDouble(value));
+
+ info->writeStream->writeUint32LE(serializedValue.significandOne);
+ info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
+ info->writeStream->writeSint16LE(serializedValue.exponent);
+ #else
+ // NOTE: We need to store a double. Unfortunately, we have to accommodate endianness.
+ // Also, I don't know if we can assume all compilers use IEEE double
+ // Therefore, I have chosen to store the double as a string.
+ Common::String buffer = Common::String::format("%f", value);
+
+ info->writeStream->write(buffer.c_str(), buffer.size());
+ #endif
+
+}
+
+static void serializeString(SerializationInfo *info) {
+ // Hard cast to a uint32 to force size_t to an explicit size
+ // *Theoretically* this could truncate, but if we have a 4gb string, we have bigger problems
+ uint32 length = static_cast(lua_strlen(info->luaState, -1));
+ info->writeStream->writeUint32LE(length);
+
+ const char *str = lua_tostring(info->luaState, -1);
+ info->writeStream->write(str, length);
+}
+
+/* Choose whether to do a regular or special persistence based on an object's
+ * metatable. "default" is whether the object, if it doesn't have a __persist
+ * entry, is literally persistable or not.
+ * Pushes the unpersist closure and returns true if special persistence is
+ * used. */
+static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 4);
+
+ // Check whether we should persist literally, or via the __persist metafunction
+ if (!lua_getmetatable(info->luaState, -1)) {
+ if (defaction) {
+ // Write out a flag declaring that the object isn't special and should be persisted normally
+ info->writeStream->writeSint32LE(0);
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Type not literally persistable by default");
+ lua_error(info->luaState);
+
+ return false; // Not reached
+ }
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl
+ lua_pushstring(info->luaState, "__persist");
+ // >>>>> permTbl indexTbl rootObj ...... obj metaTbl "__persist"
+
+ lua_rawget(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... obj metaTbl ?__persist?
+
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... obj metaTbl nil
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ if (defaction) {
+ // Write out a flag declaring that the object isn't special and should be persisted normally
+ info->writeStream->writeSint32LE(0);
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Type not literally persistable by default");
+ lua_error(info->luaState);
+
+ return false; // Return false
+ }
+
+ } else if (lua_isboolean(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... obj metaTbl bool
+ if (lua_toboolean(info->luaState, -1)) {
+ // Write out a flag declaring that the object isn't special and should be persisted normally
+ info->writeStream->writeSint32LE(0);
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl true */
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Metatable forbade persistence");
+ lua_error(info->luaState);
+
+ return false; // Not reached
+ }
+ } else if (!lua_isfunction(info->luaState, -1)) {
+ lua_pushstring(info->luaState, "__persist not nil, boolean, or function");
+ lua_error(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl __persist
+ lua_pushvalue(info->luaState, -3);
+ // >>>>> permTbl indexTbl ...... obj metaTbl __persist obj
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl ?func?
+
+ if (!lua_isfunction(info->luaState, -1)) {
+ lua_pushstring(info->luaState, "__persist function did not return a function");
+ lua_error(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl func
+
+ // Write out a flag that the function exists
+ info->writeStream->writeSint32LE(1);
+
+ // Serialize the function
+ serialize(info);
+
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ return true;
+}
+
+static void serializeTable(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 3);
+
+ // Test if the object needs special serialization
+ if (serializeSpecialObject(info, 1)) {
+ return;
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // First, serialize the metatable (if any)
+ if (!lua_getmetatable(info->luaState, -1)) {
+ lua_pushnil(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl metaTbl/nil */
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+
+
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... tbl nil
+
+ // Now, persist all k/v pairs
+ while (lua_next(info->luaState, -2)) {
+ // >>>>> permTbl indexTbl ...... tbl k v */
+
+ lua_pushvalue(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... tbl k v k */
+
+ // Serialize the key
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl k v */
+
+ // Serialize the value
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl k */
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Terminate the list with a nil
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+}
+
+static void serializeFunction(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... func
+ Closure *cl = clvalue(getObject(info->luaState, -1));
+ lua_checkstack(info->luaState, 2);
+
+ if (cl->c.isC) {
+ /* It's a C function. For now, we aren't going to allow
+ * persistence of C closures, even if the "C proto" is
+ * already in the permanents table. */
+ lua_pushstring(info->luaState, "Attempt to persist a C function");
+ lua_error(info->luaState);
+ } else {
+ // It's a Lua closure
+
+ // We don't really _NEED_ the number of upvals, but it'll simplify things a bit
+ info->writeStream->writeByte(cl->l.p->nups);
+
+ // Serialize the prototype
+ pushProto(info->luaState, cl->l.p);
+ // >>>>> permTbl indexTbl ...... func proto */
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ // Serialize upvalue values (not the upvalue objects themselves)
+ for (byte i = 0; i < cl->l.p->nups; i++) {
+ // >>>>> permTbl indexTbl ...... func
+ pushUpValue(info->luaState, cl->l.upvals[i]);
+ // >>>>> permTbl indexTbl ...... func upval
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // >>>>> permTbl indexTbl ...... func
+
+ // Serialize function environment
+ lua_getfenv(info->luaState, -1);
+ // >>>>> permTbl indexTbl ...... func fenv
+
+ if (lua_equal(info->luaState, -1, LUA_GLOBALSINDEX)) {
+ // Function has the default fenv
+
+ // >>>>> permTbl indexTbl ...... func _G
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... func nil
+ }
+
+ // >>>>> permTbl indexTbl ...... func fenv/nil
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+}
+
+static void serializeThread(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... thread
+ lua_State *threadState = lua_tothread(info->luaState, -1);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, threadState->top - threadState->stack + 1);
+
+ if (info->luaState == threadState) {
+ lua_pushstring(info->luaState, "Can't persist currently running thread");
+ lua_error(info->luaState);
+ return; /* not reached */
+ }
+
+ // Persist the stack
+
+ // We *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
+ uint32 stackSize = static_cast(appendStackToStack_reverse(threadState, info->luaState));
+ info->writeStream->writeUint32LE(stackSize);
+
+ // >>>>> permTbl indexTbl ...... thread (reversed contents of thread stack) */
+ for (; stackSize > 0; --stackSize) {
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+
+ // Now, serialize the CallInfo stack
+
+ // Again, we *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
+ uint32 numFrames = static_cast((threadState->ci - threadState->base_ci) + 1);
+ info->writeStream->writeUint32LE(numFrames);
+
+ for (uint32 i = 0; i < numFrames; i++) {
+ CallInfo *ci = threadState->base_ci + i;
+
+ // Same argument as above about truncation
+ uint32 stackBase = static_cast(ci->base - threadState->stack);
+ uint32 stackFunc = static_cast(ci->func - threadState->stack);
+ uint32 stackTop = static_cast(ci->top - threadState->stack);
+
+ info->writeStream->writeUint32LE(stackBase);
+ info->writeStream->writeUint32LE(stackFunc);
+ info->writeStream->writeUint32LE(stackTop);
+
+ info->writeStream->writeSint32LE(ci->nresults);
+
+ uint32 savedpc = (ci != threadState->base_ci) ? static_cast(ci->savedpc - ci_func(ci)->l.p->code) : 0u;
+ info->writeStream->writeUint32LE(savedpc);
+ }
+
+
+ // Serialize the state's other parameters, with the exception of upval stuff
+
+ assert(threadState->nCcalls <= 1);
+ info->writeStream->writeByte(threadState->status);
+
+ // Same argument as above about truncation
+ uint32 stackBase = static_cast(threadState->base - threadState->stack);
+ uint32 stackFunc = static_cast(threadState->top - threadState->stack);
+ info->writeStream->writeUint32LE(stackBase);
+ info->writeStream->writeUint32LE(stackFunc);
+
+ // Same argument as above about truncation
+ uint32 stackOffset = static_cast(threadState->errfunc);
+ info->writeStream->writeUint32LE(stackOffset);
+
+ // Finally, record upvalues which need to be reopened
+ // See the comment above serializeUpVal() for why we do this
+
+ UpVal *upVal;
+
+ // >>>>> permTbl indexTbl ...... thread
+ for (GCObject *gcObject = threadState->openupval; gcObject != NULL; gcObject = upVal->next) {
+ upVal = gco2uv(gcObject);
+
+ /* Make sure upvalue is really open */
+ assert(upVal->v != &upVal->u.value);
+
+ pushUpValue(info->luaState, upVal);
+ // >>>>> permTbl indexTbl ...... thread upVal
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+
+ // Same argument as above about truncation
+ uint32 stackpos = static_cast(upVal->v - threadState->stack);
+ info->writeStream->writeUint32LE(stackpos);
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... thread nil
+
+ // Use nil as a terminator
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+}
+
+static void serializeProto(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... proto
+ Proto *proto = gco2p(getObject(info->luaState, -1)->value.gc);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // Serialize constant refs */
+ info->writeStream->writeSint32LE(proto->sizek);
+
+ for (int i = 0; i < proto->sizek; ++i) {
+ pushObject(info->luaState, &proto->k[i]);
+ // >>>>> permTbl indexTbl ...... proto const
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize inner Proto refs
+ info->writeStream->writeSint32LE(proto->sizep);
+
+ for (int i = 0; i < proto->sizep; ++i)
+ {
+ pushProto(info->luaState, proto->p[i]);
+ // >>>>> permTbl indexTbl ...... proto subProto */
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize the code
+ info->writeStream->writeSint32LE(proto->sizecode);
+
+ uint32 len = static_cast(sizeof(Instruction) * proto->sizecode);
+ info->writeStream->write(proto->code, len);
+
+
+ // Serialize upvalue names
+ info->writeStream->writeSint32LE(proto->sizeupvalues);
+
+ for (int i = 0; i < proto->sizeupvalues; ++i)
+ {
+ pushString(info->luaState, proto->upvalues[i]);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+
+ // Serialize local variable infos
+ info->writeStream->writeSint32LE(proto->sizelocvars);
+
+ for (int i = 0; i < proto->sizelocvars; ++i) {
+ pushString(info->luaState, proto->locvars[i].varname);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ info->writeStream->writeSint32LE(proto->locvars[i].startpc);
+ info->writeStream->writeSint32LE(proto->locvars[i].endpc);
+ }
+
+
+ // Serialize source string
+ pushString(info->luaState, proto->source);
+ // >>>>> permTbl indexTbl ...... proto sourceStr
+
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize line numbers
+ info->writeStream->writeSint32LE(proto->sizelineinfo);
+
+ if (proto->sizelineinfo) {
+ uint32 len = static_cast(sizeof(int) * proto->sizelineinfo);
+ info->writeStream->write(proto->lineinfo, len);
+ }
+
+ // Serialize linedefined and lastlinedefined
+ info->writeStream->writeSint32LE(proto->linedefined);
+ info->writeStream->writeSint32LE(proto->lastlinedefined);
+
+
+ // Serialize misc values
+ info->writeStream->writeByte(proto->nups);
+ info->writeStream->writeByte(proto->numparams);
+ info->writeStream->writeByte(proto->is_vararg);
+ info->writeStream->writeByte(proto->maxstacksize);
+}
+
+/* Upvalues are tricky. Here's why.
+ *
+ * A particular upvalue may be either "open", in which case its member v
+ * points into a thread's stack, or "closed" in which case it points to the
+ * upvalue itself. An upvalue is closed under any of the following conditions:
+ * -- The function that initially declared the variable "local" returns
+ * -- The thread in which the closure was created is garbage collected
+ *
+ * To make things wackier, just because a thread is reachable by Lua doesn't
+ * mean it's in our root set. We need to be able to treat an open upvalue
+ * from an unreachable thread as a closed upvalue.
+ *
+ * The solution:
+ * (a) For the purposes of serializing, don't indicate whether an upvalue is
+ * closed or not.
+ * (b) When unserializing, pretend that all upvalues are closed.
+ * (c) When serializing, persist all open upvalues referenced by a thread
+ * that is persisted, and tag each one with the corresponding stack position
+ * (d) When unserializing, "reopen" each of these upvalues as the thread is
+ * unserialized
+ */
+static void serializeUpValue(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... upval
+ assert(ttype(getObject(info->luaState, -1)) == LUA_TUPVAL);
+ UpVal *upValue = gco2uv(getObject(info->luaState, -1)->value.gc);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ // We can't permit the upValue to linger around on the stack, as Lua
+ // will bail if its GC finds it.
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ......
+
+ pushObject(info->luaState, upValue->v);
+ // >>>>> permTbl indexTbl ...... obj
+
+ serialize(info);
+ // >>>>> permTbl indexTbl ...... obj
+}
+
+static void serializeUserData(SerializationInfo *info) {
+ // >>>>> permTbl rootObj ...... udata
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // Test if the object needs special serialization
+ if (serializeSpecialObject(info, 0)) {
+ return;
+ }
+
+ // Use literal persistence
+
+ // Hard cast to a uint32 length
+ // This could lead to truncation, but if we have a 4gb block of data, we have bigger problems
+ uint32 length = static_cast(uvalue(getObject(info->luaState, -1))->len);
+ info->writeStream->writeUint32LE(length);
+
+ info->writeStream->write(lua_touserdata(info->luaState, -1), length);
+
+ // Serialize the metatable (if any)
+ if (!lua_getmetatable(info->luaState, -1)) {
+ lua_pushnil(info->luaState);
+ }
+
+ // >>>>> permTbl rootObj ...... udata metaTbl/nil
+ serialize(info);
+
+ lua_pop(info->luaState, 1);
+ /* perms reftbl ... udata */
+}
+
+
+} // End of namespace Lua
diff --git a/engines/sword25/util/lua_persistence.h b/engines/sword25/util/lua_persistence.h
new file mode 100644
index 0000000000..cf7d7e03ca
--- /dev/null
+++ b/engines/sword25/util/lua_persistence.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LUA_SERIALIZATION_H
+#define LUA_SERIALIZATION_H
+
+#include "sword25/util/lua/lua.h"
+
+
+namespace Common {
+class WriteStream;
+class ReadStream;
+}
+
+
+namespace Lua {
+
+#define PERMANENT_TYPE 101
+
+void persistLua(lua_State *luaState, Common::WriteStream *writeStream);
+void unpersistLua(lua_State *luaState, Common::ReadStream *readStream);
+
+} // End of namespace Lua
+
+#endif
diff --git a/engines/sword25/util/lua_persistence_util.cpp b/engines/sword25/util/lua_persistence_util.cpp
new file mode 100644
index 0000000000..8365f5d483
--- /dev/null
+++ b/engines/sword25/util/lua_persistence_util.cpp
@@ -0,0 +1,346 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distri8buted in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "sword25/util/lua_persistence_util.h"
+
+#include "common/scummsys.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+#include "lua/lopcodes.h"
+
+
+namespace Lua {
+
+void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize) {
+ global_State *globalState = G(luaState);
+
+ block = (*globalState->frealloc)(globalState->ud, block, osize, nsize);
+ globalState->totalbytes = (globalState->totalbytes - osize) + nsize;
+
+ return block;
+}
+
+void pushObject(lua_State *luaState, TValue *obj) {
+ setobj2s(luaState, luaState->top, obj);
+
+ api_check(luaState, luaState->top < luaState->ci->top);
+ luaState->top++;
+}
+
+void pushProto(lua_State *luaState, Proto *proto) {
+ TValue obj;
+ setptvalue(luaState, &obj, proto);
+
+ pushObject(luaState, &obj);
+}
+
+void pushUpValue(lua_State *luaState, UpVal *upval) {
+ TValue obj;
+
+ obj.value.gc = cast(GCObject *, upval);
+ obj.tt = LUA_TUPVAL;
+ checkliveness(G(L), obj);
+
+ pushObject(luaState, &obj);
+}
+
+void pushString(lua_State *luaState, TString *str) {
+ TValue o;
+ setsvalue(luaState, &o, str);
+
+ pushObject(luaState, &o);
+}
+
+/* A simple reimplementation of the unfortunately static function luaA_index.
+ * Does not support the global table, registry, or upvalues. */
+StkId getObject(lua_State *luaState, int stackpos) {
+ if (stackpos > 0) {
+ lua_assert(luaState->base + stackpos - 1 < luaState->top);
+ return luaState->base + stackpos - 1;
+ } else {
+ lua_assert(L->top - stackpos >= L->base);
+ return luaState->top + stackpos;
+ }
+}
+
+void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
+ global_State *globalState = G(luaState);
+
+ obj->gch.next = globalState->rootgc;
+ globalState->rootgc = obj;
+ obj->gch.marked = luaC_white(globalState);
+ obj->gch.tt = type;
+}
+
+Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable) {
+ Closure *c = (Closure *)lua_malloc(luaState, sizeLclosure(numElements));
+ lua_linkObjToGC(luaState, obj2gco(c), LUA_TFUNCTION);
+
+ c->l.isC = 0;
+ c->l.env = elementTable;
+ c->l.nupvalues = cast_byte(numElements);
+
+ while (numElements--) {
+ c->l.upvals[numElements] = NULL;
+ }
+
+ return c;
+}
+
+void pushClosure(lua_State *luaState, Closure *closure) {
+ TValue obj;
+ setclvalue(luaState, &obj, closure);
+ pushObject(luaState, &obj);
+}
+
+Proto *createProto(lua_State *luaState) {
+ Proto *newProto = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_linkObjToGC(luaState, obj2gco(newProto), LUA_TPROTO);
+
+ newProto->k = NULL;
+ newProto->sizek = 0;
+ newProto->p = NULL;
+ newProto->sizep = 0;
+ newProto->code = NULL;
+ newProto->sizecode = 0;
+ newProto->sizelineinfo = 0;
+ newProto->sizeupvalues = 0;
+ newProto->nups = 0;
+ newProto->upvalues = NULL;
+ newProto->numparams = 0;
+ newProto->is_vararg = 0;
+ newProto->maxstacksize = 0;
+ newProto->lineinfo = NULL;
+ newProto->sizelocvars = 0;
+ newProto->locvars = NULL;
+ newProto->linedefined = 0;
+ newProto->lastlinedefined = 0;
+ newProto->source = NULL;
+
+ return newProto;
+}
+
+TString *createString(lua_State *luaState, const char *str, size_t len) {
+ TString *res;
+ lua_pushlstring(luaState, str, len);
+
+ res = rawtsvalue(luaState->top - 1);
+ lua_pop(luaState, 1);
+
+ return res;
+}
+
+Proto *makeFakeProto(lua_State *L, lu_byte nups) {
+ Proto *p = createProto(L);
+
+ p->sizelineinfo = 1;
+ p->lineinfo = lua_newVector(L, 1, int);
+ p->lineinfo[0] = 1;
+ p->sizecode = 1;
+ p->code = lua_newVector(L, 1, Instruction);
+ p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ p->source = createString(L, "", 0);
+ p->maxstacksize = 2;
+ p->nups = nups;
+ p->sizek = 0;
+ p->sizep = 0;
+
+ return p;
+}
+
+UpVal *createUpValue(lua_State *luaState, int stackpos) {
+ UpVal *upValue = (UpVal *)lua_malloc(luaState, sizeof(UpVal));
+ lua_linkObjToGC(luaState, (GCObject *)upValue, LUA_TUPVAL);
+ upValue->tt = LUA_TUPVAL;
+ upValue->v = &upValue->u.value;
+ upValue->u.l.prev = NULL;
+ upValue->u.l.next = NULL;
+
+ const TValue *o2 = (TValue *)getObject(luaState, stackpos);
+ upValue->v->value = o2->value;
+ upValue->v->tt = o2->tt;
+ checkliveness(G(L), upValue->v);
+
+ return upValue;
+}
+
+void unboxUpValue(lua_State *luaState) {
+ // >>>>> ...... func
+ LClosure *lcl;
+ UpVal *uv;
+
+ lcl = (LClosure *)clvalue(getObject(luaState, -1));
+ uv = lcl->upvals[0];
+
+ lua_pop(luaState, 1);
+ // >>>>> ......
+
+ pushUpValue(luaState, uv);
+ // >>>>> ...... upValue
+}
+
+size_t appendStackToStack_reverse(lua_State *from, lua_State *to) {
+ for (StkId id = from->top - 1; id >= from->stack; --id) {
+ setobj2s(to, to->top, id);
+ to->top++;
+ }
+
+ return from->top - from->stack;
+}
+
+void correctStack(lua_State *L, TValue *oldstack) {
+ CallInfo *ci;
+ GCObject *up;
+ L->top = (L->top - oldstack) + L->stack;
+ for (up = L->openupval; up != NULL; up = up->gch.next)
+ gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
+ for (ci = L->base_ci; ci <= L->ci; ci++) {
+ ci->top = (ci->top - oldstack) + L->stack;
+ ci->base = (ci->base - oldstack) + L->stack;
+ ci->func = (ci->func - oldstack) + L->stack;
+ }
+ L->base = (L->base - oldstack) + L->stack;
+}
+
+void lua_reallocstack(lua_State *L, int newsize) {
+ TValue *oldstack = L->stack;
+ int realsize = newsize + 1 + EXTRA_STACK;
+
+ lua_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
+ L->stacksize = realsize;
+ L->stack_last = L->stack + newsize;
+ correctStack(L, oldstack);
+}
+
+void lua_growstack(lua_State *L, int n) {
+ // Double size is enough?
+ if (n <= L->stacksize) {
+ lua_reallocstack(L, 2 * L->stacksize);
+ } else {
+ lua_reallocstack(L, L->stacksize + n);
+ }
+}
+
+void lua_reallocCallInfo(lua_State *lauState, int newsize) {
+ CallInfo *oldci = lauState->base_ci;
+ lua_reallocvector(lauState, lauState->base_ci, lauState->size_ci, newsize, CallInfo);
+
+ lauState->size_ci = newsize;
+ lauState->ci = (lauState->ci - oldci) + lauState->base_ci;
+ lauState->end_ci = lauState->base_ci + lauState->size_ci - 1;
+}
+
+void GCUnlink(lua_State *luaState, GCObject *gco) {
+ GCObject *prevslot;
+ if (G(luaState)->rootgc == gco) {
+ G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
+ return;
+ }
+
+ prevslot = G(luaState)->rootgc;
+ while (prevslot->gch.next != gco) {
+ prevslot = prevslot->gch.next;
+ }
+
+ prevslot->gch.next = prevslot->gch.next->gch.next;
+}
+
+TString *lua_newlstr(lua_State *luaState, const char *str, size_t len) {
+ lua_pushlstring(luaState, str, len);
+ TString *luaStr = &(luaState->top - 1)->value.gc->ts;
+
+ lua_pop(luaState, 1);
+
+ return luaStr;
+}
+
+void lua_link(lua_State *luaState, GCObject *o, lu_byte tt) {
+ global_State *g = G(luaState);
+ o->gch.next = g->rootgc;
+ g->rootgc = o;
+ o->gch.marked = luaC_white(g);
+ o->gch.tt = tt;
+}
+
+Proto *lua_newproto(lua_State *luaState) {
+ Proto *f = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_link(luaState, obj2gco(f), LUA_TPROTO);
+ f->k = NULL;
+ f->sizek = 0;
+ f->p = NULL;
+ f->sizep = 0;
+ f->code = NULL;
+ f->sizecode = 0;
+ f->sizelineinfo = 0;
+ f->sizeupvalues = 0;
+ f->nups = 0;
+ f->upvalues = NULL;
+ f->numparams = 0;
+ f->is_vararg = 0;
+ f->maxstacksize = 0;
+ f->lineinfo = NULL;
+ f->sizelocvars = 0;
+ f->locvars = NULL;
+ f->linedefined = 0;
+ f->lastlinedefined = 0;
+ f->source = NULL;
+ return f;
+}
+
+UpVal *makeUpValue(lua_State *luaState, int stackPos) {
+ UpVal *uv = lua_new(luaState, UpVal);
+ lua_link(luaState, (GCObject *)uv, LUA_TUPVAL);
+ uv->tt = LUA_TUPVAL;
+ uv->v = &uv->u.value;
+ uv->u.l.prev = NULL;
+ uv->u.l.next = NULL;
+
+ setobj(luaState, uv->v, getObject(luaState, stackPos));
+
+ return uv;
+}
+
+void boxUpValue_start(lua_State *luaState) {
+ LClosure *closure;
+ closure = (LClosure *)lua_newLclosure(luaState, 1, hvalue(&luaState->l_gt));
+ pushClosure(luaState, (Closure *)closure);
+ // >>>>> ...... func
+ closure->p = makeFakeProto(luaState, 1);
+
+ // Temporarily initialize the upvalue to nil
+ lua_pushnil(luaState);
+ closure->upvals[0] = makeUpValue(luaState, -1);
+ lua_pop(luaState, 1);
+}
+
+void boxUpValue_finish(lua_State *luaState) {
+ // >>>>> ...... func obj
+ LClosure *lcl = (LClosure *)clvalue(getObject(luaState, -2));
+
+ lcl->upvals[0]->u.value = *getObject(luaState, -1);
+ lua_pop(luaState, 1);
+ // >>>>> ...... func
+}
+
+} // End of namespace Lua
diff --git a/engines/sword25/util/lua_persistence_util.h b/engines/sword25/util/lua_persistence_util.h
new file mode 100644
index 0000000000..345996f606
--- /dev/null
+++ b/engines/sword25/util/lua_persistence_util.h
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distri8buted in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 LUA_SERIALIZATION_UTIL_H
+#define LUA_SERIALIZATION_UTIL_H
+
+
+struct lua_State;
+
+#include "lua/lobject.h"
+
+typedef TValue *StkId;
+
+namespace Lua {
+
+#define lua_malloc(luaState, nsize) lua_realloc(luaState, nullptr, 0, nsize)
+#define lua_reallocv(luaState, block, on, n, e) lua_realloc(luaState, block, (on) * (e), (n) * (e))
+#define lua_reallocvector(luaState, vec, oldn, n, T) ((vec) = (T *)(lua_reallocv(luaState, vec, oldn, n, sizeof(T))))
+#define lua_newVector(luaState, num, T) ((T *)lua_reallocv(luaState, nullptr, 0, num, sizeof(T)))
+#define lua_new(luaState,T) (T *)lua_malloc(luaState, sizeof(T))
+
+void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize);
+
+void pushObject(lua_State *luaState, TValue *obj);
+void pushProto(lua_State *luaState, Proto *proto);
+void pushUpValue(lua_State *luaState, UpVal *upval);
+void pushString(lua_State *luaState, TString *str);
+
+StkId getObject(lua_State *luaState, int stackpos);
+
+void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type);
+
+#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
+
+Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable);
+void pushClosure(lua_State *luaState, Closure *closure);
+
+Proto *createProto(lua_State *luaState);
+Proto *makeFakeProto(lua_State *L, lu_byte nups);
+
+TString *createString(lua_State *luaState, const char *str, size_t len);
+
+UpVal *createUpValue(lua_State *luaState, int stackpos);
+void unboxUpValue(lua_State *luaState);
+
+/* Appends one stack to another stack, but the stack is reversed in the process */
+size_t appendStackToStack_reverse(lua_State *from, lua_State *to);
+void correctStack(lua_State *L, TValue *oldstack);
+void lua_reallocstack(lua_State *L, int newsize);
+void lua_growstack(lua_State *L, int n);
+
+void lua_reallocCallInfo(lua_State *lauState, int newsize);
+
+/* Does basically the opposite of luaC_link().
+ * Right now this function is rather inefficient; it requires traversing the
+ * entire root GC set in order to find one object. If the GC list were doubly
+ * linked this would be much easier, but there's no reason for Lua to have
+ * that. */
+void GCUnlink(lua_State *luaState, GCObject *gco);
+
+TString *lua_newlstr(lua_State *luaState, const char *str, size_t len);
+void lua_link(lua_State *luaState, GCObject *o, lu_byte tt);
+Proto *lua_newproto(lua_State *luaState) ;
+
+UpVal *makeUpValue(lua_State *luaState, int stackPos);
+/**
+ * The GC is not fond of finding upvalues in tables. We get around this
+ * during persistence using a weakly keyed table, so that the GC doesn't
+ * bother to mark them. This won't work in unpersisting, however, since
+ * if we make the values weak they'll be collected (since nothing else
+ * references them). Our solution, during unpersisting, is to represent
+ * upvalues as dummy functions, each with one upvalue.
+ */
+void boxUpValue_start(lua_State *luaState);
+void boxUpValue_finish(lua_State *luaState);
+
+} // End of namespace Lua
+
+#endif
diff --git a/engines/sword25/util/lua_serialization.h b/engines/sword25/util/lua_serialization.h
deleted file mode 100644
index 549ea7968d..0000000000
--- a/engines/sword25/util/lua_serialization.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef LUA_SERIALIZATION_H
-#define LUA_SERIALIZATION_H
-
-#include "sword25/util/lua/lua.h"
-
-
-namespace Common {
-class WriteStream;
-class ReadStream;
-}
-
-
-namespace Lua {
-
-#define PERMANENT_TYPE 101
-
-void serializeLua(lua_State *luaState, Common::WriteStream *writeStream);
-void unserializeLua(lua_State *luaState, Common::ReadStream *readStream);
-
-} // End of namespace Lua
-
-#endif
diff --git a/engines/sword25/util/lua_serialization_util.cpp b/engines/sword25/util/lua_serialization_util.cpp
deleted file mode 100644
index fc3f73eca6..0000000000
--- a/engines/sword25/util/lua_serialization_util.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distri8buted in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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 "sword25/util/lua_serialization_util.h"
-
-#include "common/scummsys.h"
-
-#include "lua/lobject.h"
-#include "lua/lstate.h"
-#include "lua/lgc.h"
-#include "lua/lopcodes.h"
-
-
-namespace Lua {
-
-void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize) {
- global_State *globalState = G(luaState);
-
- block = (*globalState->frealloc)(globalState->ud, block, osize, nsize);
- globalState->totalbytes = (globalState->totalbytes - osize) + nsize;
-
- return block;
-}
-
-void pushObject(lua_State *luaState, TValue *obj) {
- setobj2s(luaState, luaState->top, obj);
-
- api_check(luaState, luaState->top < luaState->ci->top);
- luaState->top++;
-}
-
-void pushProto(lua_State *luaState, Proto *proto) {
- TValue obj;
- setptvalue(luaState, &obj, proto);
-
- pushObject(luaState, &obj);
-}
-
-void pushUpValue(lua_State *luaState, UpVal *upval) {
- TValue obj;
-
- obj.value.gc = cast(GCObject *, upval);
- obj.tt = LUA_TUPVAL;
- checkliveness(G(L), obj);
-
- pushObject(luaState, &obj);
-}
-
-void pushString(lua_State *luaState, TString *str) {
- TValue o;
- setsvalue(luaState, &o, str);
-
- pushObject(luaState, &o);
-}
-
-/* A simple reimplementation of the unfortunately static function luaA_index.
- * Does not support the global table, registry, or upvalues. */
-StkId getObject(lua_State *luaState, int stackpos) {
- if (stackpos > 0) {
- lua_assert(luaState->base + stackpos - 1 < luaState->top);
- return luaState->base + stackpos - 1;
- } else {
- lua_assert(L->top - stackpos >= L->base);
- return luaState->top + stackpos;
- }
-}
-
-void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
- global_State *globalState = G(luaState);
-
- obj->gch.next = globalState->rootgc;
- globalState->rootgc = obj;
- obj->gch.marked = luaC_white(globalState);
- obj->gch.tt = type;
-}
-
-Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable) {
- Closure *c = (Closure *)lua_malloc(luaState, sizeLclosure(numElements));
- lua_linkObjToGC(luaState, obj2gco(c), LUA_TFUNCTION);
-
- c->l.isC = 0;
- c->l.env = elementTable;
- c->l.nupvalues = cast_byte(numElements);
-
- while (numElements--) {
- c->l.upvals[numElements] = NULL;
- }
-
- return c;
-}
-
-void pushClosure(lua_State *luaState, Closure *closure) {
- TValue obj;
- setclvalue(luaState, &obj, closure);
- pushObject(luaState, &obj);
-}
-
-Proto *createProto(lua_State *luaState) {
- Proto *newProto = (Proto *)lua_malloc(luaState, sizeof(Proto));
- lua_linkObjToGC(luaState, obj2gco(newProto), LUA_TPROTO);
-
- newProto->k = NULL;
- newProto->sizek = 0;
- newProto->p = NULL;
- newProto->sizep = 0;
- newProto->code = NULL;
- newProto->sizecode = 0;
- newProto->sizelineinfo = 0;
- newProto->sizeupvalues = 0;
- newProto->nups = 0;
- newProto->upvalues = NULL;
- newProto->numparams = 0;
- newProto->is_vararg = 0;
- newProto->maxstacksize = 0;
- newProto->lineinfo = NULL;
- newProto->sizelocvars = 0;
- newProto->locvars = NULL;
- newProto->linedefined = 0;
- newProto->lastlinedefined = 0;
- newProto->source = NULL;
-
- return newProto;
-}
-
-TString *createString(lua_State *luaState, const char *str, size_t len) {
- TString *res;
- lua_pushlstring(luaState, str, len);
-
- res = rawtsvalue(luaState->top - 1);
- lua_pop(luaState, 1);
-
- return res;
-}
-
-Proto *makeFakeProto(lua_State *L, lu_byte nups) {
- Proto *p = createProto(L);
-
- p->sizelineinfo = 1;
- p->lineinfo = lua_newVector(L, 1, int);
- p->lineinfo[0] = 1;
- p->sizecode = 1;
- p->code = lua_newVector(L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->source = createString(L, "", 0);
- p->maxstacksize = 2;
- p->nups = nups;
- p->sizek = 0;
- p->sizep = 0;
-
- return p;
-}
-
-UpVal *createUpValue(lua_State *luaState, int stackpos) {
- UpVal *upValue = (UpVal *)lua_malloc(luaState, sizeof(UpVal));
- lua_linkObjToGC(luaState, (GCObject *)upValue, LUA_TUPVAL);
- upValue->tt = LUA_TUPVAL;
- upValue->v = &upValue->u.value;
- upValue->u.l.prev = NULL;
- upValue->u.l.next = NULL;
-
- const TValue *o2 = (TValue *)getObject(luaState, stackpos);
- upValue->v->value = o2->value;
- upValue->v->tt = o2->tt;
- checkliveness(G(L), upValue->v);
-
- return upValue;
-}
-
-void unboxUpValue(lua_State *luaState) {
- // >>>>> ...... func
- LClosure *lcl;
- UpVal *uv;
-
- lcl = (LClosure *)clvalue(getObject(luaState, -1));
- uv = lcl->upvals[0];
-
- lua_pop(luaState, 1);
- // >>>>> ......
-
- pushUpValue(luaState, uv);
- // >>>>> ...... upValue
-}
-
-size_t appendStackToStack_reverse(lua_State *from, lua_State *to) {
- for (StkId id = from->top - 1; id >= from->stack; --id) {
- setobj2s(to, to->top, id);
- to->top++;
- }
-
- return from->top - from->stack;
-}
-
-void correctStack(lua_State *L, TValue *oldstack) {
- CallInfo *ci;
- GCObject *up;
- L->top = (L->top - oldstack) + L->stack;
- for (up = L->openupval; up != NULL; up = up->gch.next)
- gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
- for (ci = L->base_ci; ci <= L->ci; ci++) {
- ci->top = (ci->top - oldstack) + L->stack;
- ci->base = (ci->base - oldstack) + L->stack;
- ci->func = (ci->func - oldstack) + L->stack;
- }
- L->base = (L->base - oldstack) + L->stack;
-}
-
-void lua_reallocstack(lua_State *L, int newsize) {
- TValue *oldstack = L->stack;
- int realsize = newsize + 1 + EXTRA_STACK;
-
- lua_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
- L->stacksize = realsize;
- L->stack_last = L->stack + newsize;
- correctStack(L, oldstack);
-}
-
-void lua_growstack(lua_State *L, int n) {
- // Double size is enough?
- if (n <= L->stacksize) {
- lua_reallocstack(L, 2 * L->stacksize);
- } else {
- lua_reallocstack(L, L->stacksize + n);
- }
-}
-
-void lua_reallocCallInfo(lua_State *lauState, int newsize) {
- CallInfo *oldci = lauState->base_ci;
- lua_reallocvector(lauState, lauState->base_ci, lauState->size_ci, newsize, CallInfo);
-
- lauState->size_ci = newsize;
- lauState->ci = (lauState->ci - oldci) + lauState->base_ci;
- lauState->end_ci = lauState->base_ci + lauState->size_ci - 1;
-}
-
-void GCUnlink(lua_State *luaState, GCObject *gco) {
- GCObject *prevslot;
- if (G(luaState)->rootgc == gco) {
- G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
- return;
- }
-
- prevslot = G(luaState)->rootgc;
- while (prevslot->gch.next != gco) {
- prevslot = prevslot->gch.next;
- }
-
- prevslot->gch.next = prevslot->gch.next->gch.next;
-}
-
-TString *lua_newlstr(lua_State *luaState, const char *str, size_t len) {
- lua_pushlstring(luaState, str, len);
- TString *luaStr = &(luaState->top - 1)->value.gc->ts;
-
- lua_pop(luaState, 1);
-
- return luaStr;
-}
-
-void lua_link(lua_State *luaState, GCObject *o, lu_byte tt) {
- global_State *g = G(luaState);
- o->gch.next = g->rootgc;
- g->rootgc = o;
- o->gch.marked = luaC_white(g);
- o->gch.tt = tt;
-}
-
-Proto *lua_newproto(lua_State *luaState) {
- Proto *f = (Proto *)lua_malloc(luaState, sizeof(Proto));
- lua_link(luaState, obj2gco(f), LUA_TPROTO);
- f->k = NULL;
- f->sizek = 0;
- f->p = NULL;
- f->sizep = 0;
- f->code = NULL;
- f->sizecode = 0;
- f->sizelineinfo = 0;
- f->sizeupvalues = 0;
- f->nups = 0;
- f->upvalues = NULL;
- f->numparams = 0;
- f->is_vararg = 0;
- f->maxstacksize = 0;
- f->lineinfo = NULL;
- f->sizelocvars = 0;
- f->locvars = NULL;
- f->linedefined = 0;
- f->lastlinedefined = 0;
- f->source = NULL;
- return f;
-}
-
-UpVal *makeUpValue(lua_State *luaState, int stackPos) {
- UpVal *uv = lua_new(luaState, UpVal);
- lua_link(luaState, (GCObject *)uv, LUA_TUPVAL);
- uv->tt = LUA_TUPVAL;
- uv->v = &uv->u.value;
- uv->u.l.prev = NULL;
- uv->u.l.next = NULL;
-
- setobj(luaState, uv->v, getObject(luaState, stackPos));
-
- return uv;
-}
-
-void boxUpValue_start(lua_State *luaState) {
- LClosure *closure;
- closure = (LClosure *)lua_newLclosure(luaState, 1, hvalue(&luaState->l_gt));
- pushClosure(luaState, (Closure *)closure);
- // >>>>> ...... func
- closure->p = makeFakeProto(luaState, 1);
-
- // Temporarily initialize the upvalue to nil
- lua_pushnil(luaState);
- closure->upvals[0] = makeUpValue(luaState, -1);
- lua_pop(luaState, 1);
-}
-
-void boxUpValue_finish(lua_State *luaState) {
- // >>>>> ...... func obj
- LClosure *lcl = (LClosure *)clvalue(getObject(luaState, -2));
-
- lcl->upvals[0]->u.value = *getObject(luaState, -1);
- lua_pop(luaState, 1);
- // >>>>> ...... func
-}
-
-} // End of namespace Lua
diff --git a/engines/sword25/util/lua_serialization_util.h b/engines/sword25/util/lua_serialization_util.h
deleted file mode 100644
index 345996f606..0000000000
--- a/engines/sword25/util/lua_serialization_util.h
+++ /dev/null
@@ -1,98 +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 distri8buted in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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 LUA_SERIALIZATION_UTIL_H
-#define LUA_SERIALIZATION_UTIL_H
-
-
-struct lua_State;
-
-#include "lua/lobject.h"
-
-typedef TValue *StkId;
-
-namespace Lua {
-
-#define lua_malloc(luaState, nsize) lua_realloc(luaState, nullptr, 0, nsize)
-#define lua_reallocv(luaState, block, on, n, e) lua_realloc(luaState, block, (on) * (e), (n) * (e))
-#define lua_reallocvector(luaState, vec, oldn, n, T) ((vec) = (T *)(lua_reallocv(luaState, vec, oldn, n, sizeof(T))))
-#define lua_newVector(luaState, num, T) ((T *)lua_reallocv(luaState, nullptr, 0, num, sizeof(T)))
-#define lua_new(luaState,T) (T *)lua_malloc(luaState, sizeof(T))
-
-void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize);
-
-void pushObject(lua_State *luaState, TValue *obj);
-void pushProto(lua_State *luaState, Proto *proto);
-void pushUpValue(lua_State *luaState, UpVal *upval);
-void pushString(lua_State *luaState, TString *str);
-
-StkId getObject(lua_State *luaState, int stackpos);
-
-void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type);
-
-#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
-
-Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable);
-void pushClosure(lua_State *luaState, Closure *closure);
-
-Proto *createProto(lua_State *luaState);
-Proto *makeFakeProto(lua_State *L, lu_byte nups);
-
-TString *createString(lua_State *luaState, const char *str, size_t len);
-
-UpVal *createUpValue(lua_State *luaState, int stackpos);
-void unboxUpValue(lua_State *luaState);
-
-/* Appends one stack to another stack, but the stack is reversed in the process */
-size_t appendStackToStack_reverse(lua_State *from, lua_State *to);
-void correctStack(lua_State *L, TValue *oldstack);
-void lua_reallocstack(lua_State *L, int newsize);
-void lua_growstack(lua_State *L, int n);
-
-void lua_reallocCallInfo(lua_State *lauState, int newsize);
-
-/* Does basically the opposite of luaC_link().
- * Right now this function is rather inefficient; it requires traversing the
- * entire root GC set in order to find one object. If the GC list were doubly
- * linked this would be much easier, but there's no reason for Lua to have
- * that. */
-void GCUnlink(lua_State *luaState, GCObject *gco);
-
-TString *lua_newlstr(lua_State *luaState, const char *str, size_t len);
-void lua_link(lua_State *luaState, GCObject *o, lu_byte tt);
-Proto *lua_newproto(lua_State *luaState) ;
-
-UpVal *makeUpValue(lua_State *luaState, int stackPos);
-/**
- * The GC is not fond of finding upvalues in tables. We get around this
- * during persistence using a weakly keyed table, so that the GC doesn't
- * bother to mark them. This won't work in unpersisting, however, since
- * if we make the values weak they'll be collected (since nothing else
- * references them). Our solution, during unpersisting, is to represent
- * upvalues as dummy functions, each with one upvalue.
- */
-void boxUpValue_start(lua_State *luaState);
-void boxUpValue_finish(lua_State *luaState);
-
-} // End of namespace Lua
-
-#endif
diff --git a/engines/sword25/util/lua_serializer.cpp b/engines/sword25/util/lua_serializer.cpp
deleted file mode 100644
index 55b6257324..0000000000
--- a/engines/sword25/util/lua_serializer.cpp
+++ /dev/null
@@ -1,787 +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 "sword25/util/lua_serialization.h"
-
-#include "sword25/util/double_serializer.h"
-#include "sword25/util/lua_serialization_util.h"
-
-#include "common/stream.h"
-
-#include "lua/lobject.h"
-#include "lua/lstate.h"
-#include "lua/lgc.h"
-
-
-namespace Lua {
-
-#define PERMANENT_TYPE 101
-
-struct SerializationInfo {
- lua_State *luaState;
- Common::WriteStream *writeStream;
- uint counter;
-};
-
-static void serialize(SerializationInfo *info);
-
-static void serializeBoolean(SerializationInfo *info);
-static void serializeNumber(SerializationInfo *info);
-static void serializeString(SerializationInfo *info);
-static void serializeTable(SerializationInfo *info);
-static void serializeFunction(SerializationInfo *info);
-static void serializeThread(SerializationInfo *info);
-static void serializeProto(SerializationInfo *info);
-static void serializeUpValue(SerializationInfo *info);
-static void serializeUserData(SerializationInfo *info);
-
-
-void serializeLua(lua_State *luaState, Common::WriteStream *writeStream) {
- SerializationInfo info;
- info.luaState = luaState;
- info.writeStream = writeStream;
- info.counter = 0u;
-
- // The process starts with the lua stack as follows:
- // >>>>> permTbl rootObj
- // That's the table of permanents and the root object to be serialized
-
- // Make sure there is enough room on the stack
- lua_checkstack(luaState, 4);
- assert(lua_gettop(luaState) == 2);
- // And that the root isn't nil
- assert(!lua_isnil(luaState, 2));
-
- // Create a table to hold indexes of everything that's serialized
- // This allows us to only serialize an object once
- // Every other time, just reference the index
- lua_newtable(luaState);
- // >>>>> permTbl rootObj indexTbl
-
- // Now we're going to make the table weakly keyed. This prevents the
- // GC from visiting it and trying to mark things it doesn't want to
- // mark in tables, e.g. upvalues. All objects in the table are
- // a priori reachable, so it doesn't matter that we do this.
-
- // Create the metatable
- lua_newtable(luaState);
- // >>>>> permTbl rootObj indexTbl metaTbl
-
- lua_pushstring(luaState, "__mode");
- // >>>>> permTbl rootObj indexTbl metaTbl "__mode"
-
- lua_pushstring(luaState, "k");
- // >>>>> permTbl rootObj indexTbl metaTbl "__mode" "k"
-
- lua_settable(luaState, 4);
- // >>>>> permTbl rootObj indexTbl metaTbl
-
- lua_setmetatable(luaState, 3);
- // >>>>> permTbl rootObj indexTbl
-
- // Swap the indexTable and the rootObj
- lua_insert(luaState, 2);
- // >>>>> permTbl indexTbl rootObj
-
- // Serialize the root recursively
- serialize(&info);
-
- // Return the stack back to the original state
- lua_remove(luaState, 2);
- // >>>>> permTbl rootObj
-}
-
-static void serialize(SerializationInfo *info) {
- // The stack can potentially have many things on it
- // The object we want to serialize is the item on the top of the stack
- // >>>>> permTbl indexTbl rootObj ...... obj
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- // If the object has already been written, don't write it again
- // Instead write the index of the object from the indexTbl
-
- // Check the indexTbl
- lua_pushvalue(info->luaState, -1);
- // >>>>> permTbl indexTbl rootObj ...... obj obj
-
- lua_rawget(info->luaState, 2);
- // >>>>> permTbl indexTbl rootObj ...... obj ?index?
-
- // If the index isn't nil, the object has already been written
- if (!lua_isnil(info->luaState, -1)) {
- // Write out a flag that indicates that it's an index
- info->writeStream->writeByte(0);
-
- // Retrieve the index from the stack
- uint *index = (uint *)lua_touserdata(info->luaState, -1);
-
- // Write out the index
- info->writeStream->writeUint32LE(*index);
-
- // Pop the index off the stack
- lua_pop(info->luaState, 1);
-
- return;
- }
-
- // Pop the nil off the stack
- lua_pop(info->luaState, 1);
-
- // Write out a flag that indicates that this is a real object
- info->writeStream->writeByte(1);
-
- // If the object itself is nil, then write out a zero as a placeholder
- if (lua_isnil(info->luaState, -1)) {
- info->writeStream->writeByte(0);
-
- return;
- }
-
- // Add the object to the indexTbl
-
- lua_pushvalue(info->luaState, -1);
- // >>>>> permTbl indexTbl rootObj ...... obj obj
-
- uint *ref = (uint *)lua_newuserdata(info->luaState, sizeof(uint));
- *ref = ++(info->counter);
- // >>>>> permTbl indexTbl rootObj ...... obj obj index
-
- lua_rawset(info->luaState, 2);
- // >>>>> permTbl indexTbl rootObj ...... obj
-
-
- // Write out the index
- info->writeStream->writeUint32LE(info->counter);
-
-
- // Objects that are in the permanents table are serialized in a special way
-
- lua_pushvalue(info->luaState, -1);
- // >>>>> permTbl indexTbl rootObj ...... obj obj
-
- lua_gettable(info->luaState, 1);
- // >>>>> permTbl indexTbl rootObj ...... obj obj ?permKey?
-
- if (!lua_isnil(info->luaState, -1)) {
- // Write out the type
- info->writeStream->writeSint32LE(PERMANENT_TYPE);
-
- // Serialize the key
- serialize(info);
-
- // Pop the key off the stack
- lua_pop(info->luaState, 1);
-
- return;
- }
-
- // Pop the nil off the stack
- lua_pop(info->luaState, 1);
-
- // Query the type of the object
- int objType = lua_type(info->luaState, -1);
-
- // Write it out
- info->writeStream->writeSint32LE(objType);
-
- // Serialize the object by its type
-
- switch (objType) {
- case LUA_TBOOLEAN:
- serializeBoolean(info);
- break;
- case LUA_TLIGHTUSERDATA:
- // You can't serialize a pointer
- // It would be meaningless on the next run
- assert(0);
- break;
- case LUA_TNUMBER:
- serializeNumber(info);
- break;
- case LUA_TSTRING:
- serializeString(info);
- break;
- case LUA_TTABLE:
- serializeTable(info);
- break;
- case LUA_TFUNCTION:
- serializeFunction(info);
- break;
- case LUA_TTHREAD:
- serializeThread(info);
- break;
- case LUA_TPROTO:
- serializeProto(info);
- break;
- case LUA_TUPVAL:
- serializeUpValue(info);
- break;
- case LUA_TUSERDATA:
- serializeUserData(info);
- break;
- default:
- assert(0);
- }
-}
-
-static void serializeBoolean(SerializationInfo *info) {
- int value = lua_toboolean(info->luaState, -1);
-
- info->writeStream->writeSint32LE(value);
-}
-
-static void serializeNumber(SerializationInfo *info) {
- lua_Number value = lua_tonumber(info->luaState, -1);
-
- #if 1
- Util::SerializedDouble serializedValue(Util::encodeDouble(value));
-
- info->writeStream->writeUint32LE(serializedValue.significandOne);
- info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
- info->writeStream->writeSint16LE(serializedValue.exponent);
- #else
- // NOTE: We need to store a double. Unfortunately, we have to accommodate endianness.
- // Also, I don't know if we can assume all compilers use IEEE double
- // Therefore, I have chosen to store the double as a string.
- Common::String buffer = Common::String::format("%f", value);
-
- info->writeStream->write(buffer.c_str(), buffer.size());
- #endif
-
-}
-
-static void serializeString(SerializationInfo *info) {
- // Hard cast to a uint32 to force size_t to an explicit size
- // *Theoretically* this could truncate, but if we have a 4gb string, we have bigger problems
- uint32 length = static_cast(lua_strlen(info->luaState, -1));
- info->writeStream->writeUint32LE(length);
-
- const char *str = lua_tostring(info->luaState, -1);
- info->writeStream->write(str, length);
-}
-
-/* Choose whether to do a regular or special persistence based on an object's
- * metatable. "default" is whether the object, if it doesn't have a __persist
- * entry, is literally persistable or not.
- * Pushes the unpersist closure and returns true if special persistence is
- * used. */
-static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 4);
-
- // Check whether we should persist literally, or via the __persist metafunction
- if (!lua_getmetatable(info->luaState, -1)) {
- if (defaction) {
- // Write out a flag declaring that the object isn't special and should be persisted normally
- info->writeStream->writeSint32LE(0);
-
- return false;
- } else {
- lua_pushstring(info->luaState, "Type not literally persistable by default");
- lua_error(info->luaState);
-
- return false; // Not reached
- }
- }
-
- // >>>>> permTbl indexTbl ...... obj metaTbl
- lua_pushstring(info->luaState, "__persist");
- // >>>>> permTbl indexTbl rootObj ...... obj metaTbl "__persist"
-
- lua_rawget(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... obj metaTbl ?__persist?
-
- if (lua_isnil(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... obj metaTbl nil
- lua_pop(info->luaState, 2);
- // >>>>> permTbl indexTbl ...... obj
-
- if (defaction) {
- // Write out a flag declaring that the object isn't special and should be persisted normally
- info->writeStream->writeSint32LE(0);
-
- return false;
- } else {
- lua_pushstring(info->luaState, "Type not literally persistable by default");
- lua_error(info->luaState);
-
- return false; // Return false
- }
-
- } else if (lua_isboolean(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... obj metaTbl bool
- if (lua_toboolean(info->luaState, -1)) {
- // Write out a flag declaring that the object isn't special and should be persisted normally
- info->writeStream->writeSint32LE(0);
-
- // >>>>> permTbl indexTbl ...... obj metaTbl true */
- lua_pop(info->luaState, 2);
- // >>>>> permTbl indexTbl ...... obj
-
- return false;
- } else {
- lua_pushstring(info->luaState, "Metatable forbade persistence");
- lua_error(info->luaState);
-
- return false; // Not reached
- }
- } else if (!lua_isfunction(info->luaState, -1)) {
- lua_pushstring(info->luaState, "__persist not nil, boolean, or function");
- lua_error(info->luaState);
- }
-
- // >>>>> permTbl indexTbl ...... obj metaTbl __persist
- lua_pushvalue(info->luaState, -3);
- // >>>>> permTbl indexTbl ...... obj metaTbl __persist obj
-
- // >>>>> permTbl indexTbl ...... obj metaTbl ?func?
-
- if (!lua_isfunction(info->luaState, -1)) {
- lua_pushstring(info->luaState, "__persist function did not return a function");
- lua_error(info->luaState);
- }
-
- // >>>>> permTbl indexTbl ...... obj metaTbl func
-
- // Write out a flag that the function exists
- info->writeStream->writeSint32LE(1);
-
- // Serialize the function
- serialize(info);
-
- lua_pop(info->luaState, 2);
- // >>>>> permTbl indexTbl ...... obj
-
- return true;
-}
-
-static void serializeTable(SerializationInfo *info) {
- // >>>>> permTbl indexTbl ...... tbl
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 3);
-
- // Test if the object needs special serialization
- if (serializeSpecialObject(info, 1)) {
- return;
- }
-
- // >>>>> permTbl indexTbl ...... tbl
-
- // First, serialize the metatable (if any)
- if (!lua_getmetatable(info->luaState, -1)) {
- lua_pushnil(info->luaState);
- }
-
- // >>>>> permTbl indexTbl ...... tbl metaTbl/nil */
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl
-
-
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... tbl nil
-
- // Now, persist all k/v pairs
- while (lua_next(info->luaState, -2)) {
- // >>>>> permTbl indexTbl ...... tbl k v */
-
- lua_pushvalue(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... tbl k v k */
-
- // Serialize the key
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl k v */
-
- // Serialize the value
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl k */
- }
-
- // >>>>> permTbl indexTbl ...... tbl
-
- // Terminate the list with a nil
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... tbl
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl
-}
-
-static void serializeFunction(SerializationInfo *info) {
- // >>>>> permTbl indexTbl ...... func
- Closure *cl = clvalue(getObject(info->luaState, -1));
- lua_checkstack(info->luaState, 2);
-
- if (cl->c.isC) {
- /* It's a C function. For now, we aren't going to allow
- * persistence of C closures, even if the "C proto" is
- * already in the permanents table. */
- lua_pushstring(info->luaState, "Attempt to persist a C function");
- lua_error(info->luaState);
- } else {
- // It's a Lua closure
-
- // We don't really _NEED_ the number of upvals, but it'll simplify things a bit
- info->writeStream->writeByte(cl->l.p->nups);
-
- // Serialize the prototype
- pushProto(info->luaState, cl->l.p);
- // >>>>> permTbl indexTbl ...... func proto */
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
-
- // Serialize upvalue values (not the upvalue objects themselves)
- for (byte i = 0; i < cl->l.p->nups; i++) {
- // >>>>> permTbl indexTbl ...... func
- pushUpValue(info->luaState, cl->l.upvals[i]);
- // >>>>> permTbl indexTbl ...... func upval
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
- }
-
- // >>>>> permTbl indexTbl ...... func
-
- // Serialize function environment
- lua_getfenv(info->luaState, -1);
- // >>>>> permTbl indexTbl ...... func fenv
-
- if (lua_equal(info->luaState, -1, LUA_GLOBALSINDEX)) {
- // Function has the default fenv
-
- // >>>>> permTbl indexTbl ...... func _G
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
-
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... func nil
- }
-
- // >>>>> permTbl indexTbl ...... func fenv/nil
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
- }
-}
-
-static void serializeThread(SerializationInfo *info) {
- // >>>>> permTbl indexTbl ...... thread
- lua_State *threadState = lua_tothread(info->luaState, -1);
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, threadState->top - threadState->stack + 1);
-
- if (info->luaState == threadState) {
- lua_pushstring(info->luaState, "Can't persist currently running thread");
- lua_error(info->luaState);
- return; /* not reached */
- }
-
- // Persist the stack
-
- // We *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
- uint32 stackSize = static_cast(appendStackToStack_reverse(threadState, info->luaState));
- info->writeStream->writeUint32LE(stackSize);
-
- // >>>>> permTbl indexTbl ...... thread (reversed contents of thread stack) */
- for (; stackSize > 0; --stackSize) {
- serialize(info);
-
- lua_pop(info->luaState, 1);
- }
-
- // >>>>> permTbl indexTbl ...... thread
-
- // Now, serialize the CallInfo stack
-
- // Again, we *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
- uint32 numFrames = static_cast((threadState->ci - threadState->base_ci) + 1);
- info->writeStream->writeUint32LE(numFrames);
-
- for (uint32 i = 0; i < numFrames; i++) {
- CallInfo *ci = threadState->base_ci + i;
-
- // Same argument as above about truncation
- uint32 stackBase = static_cast(ci->base - threadState->stack);
- uint32 stackFunc = static_cast(ci->func - threadState->stack);
- uint32 stackTop = static_cast(ci->top - threadState->stack);
-
- info->writeStream->writeUint32LE(stackBase);
- info->writeStream->writeUint32LE(stackFunc);
- info->writeStream->writeUint32LE(stackTop);
-
- info->writeStream->writeSint32LE(ci->nresults);
-
- uint32 savedpc = (ci != threadState->base_ci) ? static_cast(ci->savedpc - ci_func(ci)->l.p->code) : 0u;
- info->writeStream->writeUint32LE(savedpc);
- }
-
-
- // Serialize the state's other parameters, with the exception of upval stuff
-
- assert(threadState->nCcalls <= 1);
- info->writeStream->writeByte(threadState->status);
-
- // Same argument as above about truncation
- uint32 stackBase = static_cast(threadState->base - threadState->stack);
- uint32 stackFunc = static_cast(threadState->top - threadState->stack);
- info->writeStream->writeUint32LE(stackBase);
- info->writeStream->writeUint32LE(stackFunc);
-
- // Same argument as above about truncation
- uint32 stackOffset = static_cast(threadState->errfunc);
- info->writeStream->writeUint32LE(stackOffset);
-
- // Finally, record upvalues which need to be reopened
- // See the comment above serializeUpVal() for why we do this
-
- UpVal *upVal;
-
- // >>>>> permTbl indexTbl ...... thread
- for (GCObject *gcObject = threadState->openupval; gcObject != NULL; gcObject = upVal->next) {
- upVal = gco2uv(gcObject);
-
- /* Make sure upvalue is really open */
- assert(upVal->v != &upVal->u.value);
-
- pushUpValue(info->luaState, upVal);
- // >>>>> permTbl indexTbl ...... thread upVal
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... thread
-
- // Same argument as above about truncation
- uint32 stackpos = static_cast(upVal->v - threadState->stack);
- info->writeStream->writeUint32LE(stackpos);
- }
-
- // >>>>> permTbl indexTbl ...... thread
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... thread nil
-
- // Use nil as a terminator
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... thread
-}
-
-static void serializeProto(SerializationInfo *info) {
- // >>>>> permTbl indexTbl ...... proto
- Proto *proto = gco2p(getObject(info->luaState, -1)->value.gc);
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- // Serialize constant refs */
- info->writeStream->writeSint32LE(proto->sizek);
-
- for (int i = 0; i < proto->sizek; ++i) {
- pushObject(info->luaState, &proto->k[i]);
- // >>>>> permTbl indexTbl ...... proto const
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
-
- // >>>>> permTbl indexTbl ...... proto
-
- // Serialize inner Proto refs
- info->writeStream->writeSint32LE(proto->sizep);
-
- for (int i = 0; i < proto->sizep; ++i)
- {
- pushProto(info->luaState, proto->p[i]);
- // >>>>> permTbl indexTbl ...... proto subProto */
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
-
- // >>>>> permTbl indexTbl ...... proto
-
- // Serialize the code
- info->writeStream->writeSint32LE(proto->sizecode);
-
- uint32 len = static_cast(sizeof(Instruction) * proto->sizecode);
- info->writeStream->write(proto->code, len);
-
-
- // Serialize upvalue names
- info->writeStream->writeSint32LE(proto->sizeupvalues);
-
- for (int i = 0; i < proto->sizeupvalues; ++i)
- {
- pushString(info->luaState, proto->upvalues[i]);
- // >>>>> permTbl indexTbl ...... proto str
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
-
-
- // Serialize local variable infos
- info->writeStream->writeSint32LE(proto->sizelocvars);
-
- for (int i = 0; i < proto->sizelocvars; ++i) {
- pushString(info->luaState, proto->locvars[i].varname);
- // >>>>> permTbl indexTbl ...... proto str
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
-
- info->writeStream->writeSint32LE(proto->locvars[i].startpc);
- info->writeStream->writeSint32LE(proto->locvars[i].endpc);
- }
-
-
- // Serialize source string
- pushString(info->luaState, proto->source);
- // >>>>> permTbl indexTbl ...... proto sourceStr
-
- serialize(info);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
-
- // Serialize line numbers
- info->writeStream->writeSint32LE(proto->sizelineinfo);
-
- if (proto->sizelineinfo) {
- uint32 len = static_cast(sizeof(int) * proto->sizelineinfo);
- info->writeStream->write(proto->lineinfo, len);
- }
-
- // Serialize linedefined and lastlinedefined
- info->writeStream->writeSint32LE(proto->linedefined);
- info->writeStream->writeSint32LE(proto->lastlinedefined);
-
-
- // Serialize misc values
- info->writeStream->writeByte(proto->nups);
- info->writeStream->writeByte(proto->numparams);
- info->writeStream->writeByte(proto->is_vararg);
- info->writeStream->writeByte(proto->maxstacksize);
-}
-
-/* Upvalues are tricky. Here's why.
- *
- * A particular upvalue may be either "open", in which case its member v
- * points into a thread's stack, or "closed" in which case it points to the
- * upvalue itself. An upvalue is closed under any of the following conditions:
- * -- The function that initially declared the variable "local" returns
- * -- The thread in which the closure was created is garbage collected
- *
- * To make things wackier, just because a thread is reachable by Lua doesn't
- * mean it's in our root set. We need to be able to treat an open upvalue
- * from an unreachable thread as a closed upvalue.
- *
- * The solution:
- * (a) For the purposes of serializing, don't indicate whether an upvalue is
- * closed or not.
- * (b) When unserializing, pretend that all upvalues are closed.
- * (c) When serializing, persist all open upvalues referenced by a thread
- * that is persisted, and tag each one with the corresponding stack position
- * (d) When unserializing, "reopen" each of these upvalues as the thread is
- * unserialized
- */
-static void serializeUpValue(SerializationInfo *info) {
- // >>>>> permTbl indexTbl ...... upval
- assert(ttype(getObject(info->luaState, -1)) == LUA_TUPVAL);
- UpVal *upValue = gco2uv(getObject(info->luaState, -1)->value.gc);
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- // We can't permit the upValue to linger around on the stack, as Lua
- // will bail if its GC finds it.
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ......
-
- pushObject(info->luaState, upValue->v);
- // >>>>> permTbl indexTbl ...... obj
-
- serialize(info);
- // >>>>> permTbl indexTbl ...... obj
-}
-
-static void serializeUserData(SerializationInfo *info) {
- // >>>>> permTbl rootObj ...... udata
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- // Test if the object needs special serialization
- if (serializeSpecialObject(info, 0)) {
- return;
- }
-
- // Use literal persistence
-
- // Hard cast to a uint32 length
- // This could lead to truncation, but if we have a 4gb block of data, we have bigger problems
- uint32 length = static_cast(uvalue(getObject(info->luaState, -1))->len);
- info->writeStream->writeUint32LE(length);
-
- info->writeStream->write(lua_touserdata(info->luaState, -1), length);
-
- // Serialize the metatable (if any)
- if (!lua_getmetatable(info->luaState, -1)) {
- lua_pushnil(info->luaState);
- }
-
- // >>>>> permTbl rootObj ...... udata metaTbl/nil
- serialize(info);
-
- lua_pop(info->luaState, 1);
- /* perms reftbl ... udata */
-}
-
-
-} // End of namespace Lua
diff --git a/engines/sword25/util/lua_unpersist.cpp b/engines/sword25/util/lua_unpersist.cpp
new file mode 100644
index 0000000000..aa924ff7c5
--- /dev/null
+++ b/engines/sword25/util/lua_unpersist.cpp
@@ -0,0 +1,698 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "sword25/util/lua_persistence.h"
+
+#include "sword25/util/double_serializer.h"
+#include "sword25/util/lua_persistence_util.h"
+
+#include "common/stream.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+#include "lua/lopcodes.h"
+
+
+namespace Lua {
+
+struct UnSerializationInfo {
+ lua_State *luaState;
+ Common::ReadStream *readStream;
+};
+
+static void unserialize(UnSerializationInfo *info);
+
+static void unserializeBoolean(UnSerializationInfo *info);
+static void unserializeNumber(UnSerializationInfo *info);
+static void unserializeString(UnSerializationInfo *info);
+static void unserializeTable(UnSerializationInfo *info, int index);
+static void unserializeFunction(UnSerializationInfo *info, int index);
+static void unserializeThread(UnSerializationInfo *info, int index);
+static void unserializeProto(UnSerializationInfo *info, int index);
+static void unserializeUpValue(UnSerializationInfo *info, int index);
+static void unserializeUserData(UnSerializationInfo *info, int index);
+static void unserializePermanent(UnSerializationInfo *info, int index);
+
+
+void unpersistLua(lua_State *luaState, Common::ReadStream *readStream) {
+ UnSerializationInfo info;
+ info.luaState = luaState;
+ info.readStream = readStream;
+
+ // The process starts with the lua stack as follows:
+ // >>>>> permTbl
+ // That's the table of permanents
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(luaState, 3);
+
+ // Create a table to hold indexes of everything thats already been read
+ lua_newtable(luaState);
+ // >>>>> permTbl indexTbl
+
+ // Prevent garbage collection while we unserialize
+ lua_gc(luaState, LUA_GCSTOP, 0);
+
+ // Unserialize the root object
+ unserialize(&info);
+ // >>>>> permTbl indexTbl rootObj
+
+ // Re-start garbage collection
+ lua_gc(luaState, LUA_GCRESTART, 0);
+
+ // Remove the indexTbl
+ lua_replace(luaState, 2);
+ // >>>>> permTbl rootObj
+}
+
+/* The object is left on the stack. This is primarily used by unserialize, but
+ * may be used by GCed objects that may incur cycles in order to preregister
+ * the object. */
+static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ...... obj
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ lua_pushlightuserdata(info->luaState, (void *)index);
+ // >>>>> permTbl indexTbl ...... obj index
+
+ lua_pushvalue(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... obj index obj
+
+ // Push the k/v pair into the indexTbl
+ lua_settable(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+}
+
+static void unserialize(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ byte isARealValue = info->readStream->readByte();
+ if (isARealValue) {
+ int index = info->readStream->readSint32LE();
+ int type = info->readStream->readSint32LE();
+
+ switch (type) {
+ case LUA_TBOOLEAN:
+ unserializeBoolean(info);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ // You can't serialize a pointer
+ // It would be meaningless on the next run
+ assert(0);
+ break;
+ case LUA_TNUMBER:
+ unserializeNumber(info);
+ break;
+ case LUA_TSTRING:
+ unserializeString(info);
+ break;
+ case LUA_TTABLE:
+ unserializeTable(info, index);
+ break;
+ case LUA_TFUNCTION:
+ unserializeFunction(info, index);
+ break;
+ case LUA_TTHREAD:
+ unserializeThread(info, index);
+ break;
+ case LUA_TPROTO:
+ unserializeProto(info, index);
+ break;
+ case LUA_TUPVAL:
+ unserializeUpValue(info, index);
+ break;
+ case LUA_TUSERDATA:
+ unserializeUserData(info, index);
+ break;
+ case PERMANENT_TYPE:
+ unserializePermanent(info, index);
+ break;
+ default:
+ assert(0);
+ }
+
+
+ // >>>>> permTbl indexTbl ...... obj
+ assert(lua_type(info->luaState, -1) == type ||
+ type == PERMANENT_TYPE ||
+ // Remember, upvalues get a special dispensation, as described in boxUpValue
+ (lua_type(info->luaState, -1) == LUA_TFUNCTION && type == LUA_TUPVAL));
+
+ registerObjectInIndexTable(info, index);
+ // >>>>> permTbl indexTbl ...... obj
+ } else {
+ int index = info->readStream->readSint32LE();
+
+ if (index == 0) {
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... nil
+ } else {
+ // Fetch the object from the indexTbl
+
+ lua_pushlightuserdata(info->luaState, (void *)index);
+ // >>>>> permTbl indexTbl ...... index
+
+ lua_gettable(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... ?obj?
+
+ assert(!lua_isnil(info->luaState, -1));
+ }
+ // >>>>> permTbl indexTbl ...... obj/nil
+ }
+
+ // >>>>> permTbl indexTbl ...... obj/nil
+}
+
+static void unserializeBoolean(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ int value = info->readStream->readSint32LE();
+
+ lua_pushboolean(info->luaState, value);
+ // >>>>> permTbl indexTbl ...... bool
+}
+
+static void unserializeNumber(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ // Read the serialized double
+ Util::SerializedDouble serializedValue;
+ serializedValue.significandOne = info->readStream->readUint32LE();
+ serializedValue.signAndSignificandTwo = info->readStream->readUint32LE();
+ serializedValue.exponent = info->readStream->readSint16LE();
+
+ lua_Number value = Util::decodeDouble(serializedValue);
+
+ lua_pushnumber(info->luaState, value);
+ // >>>>> permTbl indexTbl ...... num
+}
+
+static void unserializeString(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ uint32 length = info->readStream->readUint32LE();
+ char *string = new char[length];
+
+ info->readStream->read(string, length);
+ lua_pushlstring(info->luaState, string, length);
+
+ // >>>>> permTbl indexTbl ...... string
+
+ delete[] string;
+}
+
+static void unserializeSpecialTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ unserialize(info);
+
+ // >>>>> permTbl indexTbl ...... spfunc
+ lua_call(info->luaState, 0, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+}
+
+static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 3);
+
+ // Preregister table for handling of cycles
+ lua_newtable(info->luaState);
+
+ // >>>>> permTbl indexTbl ...... tbl
+ registerObjectInIndexTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Unserialize metatable
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
+
+ if (lua_istable(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... tbl metaTbl
+ lua_setmetatable(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... tbl
+ } else {
+ // >>>>> permTbl indexTbl ...... tbl nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+ // >>>>> permTbl indexTbl ...... tbl
+
+
+ while (1) {
+ // >>>>> permTbl indexTbl ...... tbl
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... tbl key/nil
+
+ // The table serialization is nil terminated
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... tbl nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ break;
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl key
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... tbl value
+
+ lua_rawset(info->luaState, -3);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+}
+
+void unserializeTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ int isSpecial = info->readStream->readSint32LE();
+
+ if (isSpecial) {
+ unserializeSpecialTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+ } else {
+ unserializeLiteralTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+}
+
+void unserializeFunction(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ byte numUpValues = info->readStream->readByte();
+
+ LClosure *lclosure = (LClosure *)lua_newLclosure(info->luaState, numUpValues, hvalue(&info->luaState->l_gt));
+ pushClosure(info->luaState, (Closure *)lclosure);
+ // >>>>> permTbl indexTbl ...... func
+
+ // Put *some* proto in the closure, before the GC can find it
+ lclosure->p = makeFakeProto(info->luaState, numUpValues);
+
+ //Also, we need to temporarily fill the upvalues
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... func nil
+
+ for (byte i = 0; i < numUpValues; ++i) {
+ lclosure->upvals[i] = createUpValue(info->luaState, -1);
+ }
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ // I can't see offhand how a function would ever get to be self-
+ // referential, but just in case let's register it early
+ registerObjectInIndexTable(info, index);
+
+ // Now that it's safe, we can get the real proto
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... func proto
+
+ lclosure->p = gco2p(getObject(info->luaState, -1)->value.gc);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ for (byte i = 0; i < numUpValues; ++i) {
+ // >>>>> permTbl indexTbl ...... func
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... func func2
+
+ unboxUpValue(info->luaState);
+ // >>>>> permTbl indexTbl ...... func upValue
+ lclosure->upvals[i] = gco2uv(getObject(info->luaState, -1)->value.gc);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // Finally, the fenv
+ unserialize(info);
+
+ // >>>>> permTbl indexTbl ...... func ?fenv/nil?
+ if (!lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... func fenv
+ lua_setfenv(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... func
+ } else {
+ // >>>>> permTbl indexTbl ...... func nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // >>>>> permTbl indexTbl ...... func
+}
+
+void unserializeThread(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ lua_State *L2;
+ uint32 stacklimit = 0;
+
+ L2 = lua_newthread(info->luaState);
+ lua_checkstack(info->luaState, 3);
+
+ // L1: permTbl indexTbl ...... thread
+ // L2: (empty)
+ registerObjectInIndexTable(info, index);
+
+ // First, deserialize the object stack
+ uint32 stackSize = info->readStream->readUint32LE();
+ lua_growstack(info->luaState, (int)stackSize);
+
+ // Make sure that the first stack element (a nil, representing
+ // the imaginary top-level C function) is written to the very,
+ // very bottom of the stack
+ L2->top--;
+ for (uint32 i = 0; i < stackSize; ++i) {
+ unserialize(info);
+ // L1: permTbl indexTbl ...... thread obj*
+ }
+
+ lua_xmove(info->luaState, L2, stackSize);
+ // L1: permTbl indexTbl ...... thread
+ // L2: obj*
+
+ // Hereafter, stacks refer to L1
+
+
+ // Now, deserialize the CallInfo stack
+
+ uint32 numFrames = info->readStream->readUint32LE();
+
+ lua_reallocCallInfo(L2, numFrames * 2);
+ for (uint32 i = 0; i < numFrames; ++i) {
+ CallInfo *ci = L2->base_ci + i;
+ uint32 stackbase = info->readStream->readUint32LE();
+ uint32 stackfunc = info->readStream->readUint32LE();
+ uint32 stacktop = info->readStream->readUint32LE();
+
+ ci->nresults = info->readStream->readSint32LE();
+
+ uint32 savedpc = info->readStream->readUint32LE();
+
+ if (stacklimit < stacktop) {
+ stacklimit = stacktop;
+ }
+
+ ci->base = L2->stack + stackbase;
+ ci->func = L2->stack + stackfunc;
+ ci->top = L2->stack + stacktop;
+ ci->savedpc = (ci != L2->base_ci) ? ci_func(ci)->l.p->code + savedpc : 0;
+ ci->tailcalls = 0;
+
+ // Update the pointer each time, to keep the GC happy
+ L2->ci = ci;
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+ // Deserialize the state's other parameters, with the exception of upval stuff
+
+ L2->savedpc = L2->ci->savedpc;
+ L2->status = info->readStream->readByte();
+ uint32 stackbase = info->readStream->readUint32LE();
+ uint32 stacktop = info->readStream->readUint32LE();
+
+
+ L2->errfunc = info->readStream->readUint32LE();
+
+ L2->base = L2->stack + stackbase;
+ L2->top = L2->stack + stacktop;
+
+ // Finally, "reopen" upvalues. See serializeUpVal() for why we do this
+ UpVal *uv;
+ GCObject **nextslot = &L2->openupval;
+ global_State *g = G(L2);
+
+ while (true) {
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... thread upVal/nil
+
+ // The list is terminated by a nil
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... thread nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+ break;
+ }
+
+ // >>>>> permTbl indexTbl ...... thread boxedUpVal
+ unboxUpValue(info->luaState);
+ // >>>>> permTbl indexTbl ...... thread boxedUpVal
+
+ uv = &(getObject(info->luaState, -1)->value.gc->uv);
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+
+ uint32 stackpos = info->readStream->readUint32LE();
+ uv->v = L2->stack + stackpos;
+
+ GCUnlink(info->luaState, (GCObject *)uv);
+
+ uv->marked = luaC_white(g);
+ *nextslot = (GCObject *)uv;
+ nextslot = &uv->next;
+ uv->u.l.prev = &G(L2)->uvhead;
+ uv->u.l.next = G(L2)->uvhead.u.l.next;
+ uv->u.l.next->u.l.prev = uv;
+ G(L2)->uvhead.u.l.next = uv;
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ }
+ *nextslot = NULL;
+
+ // The stack must be valid at least to the highest value among the CallInfos
+ // 'top' and the values up to there must be filled with 'nil'
+ lua_checkstack(L2, (int)stacklimit);
+ for (StkId o = L2->top; o <= L2->top + stacklimit; ++o) {
+ setnilvalue(o);
+ }
+}
+
+void unserializeProto(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // We have to be careful. The GC expects a lot out of protos. In particular, we need
+ // to give the function a valid string for its source, and valid code, even before we
+ // actually read in the real code.
+ TString *source = lua_newlstr(info->luaState, "", 0);
+ Proto *p = lua_newproto(info->luaState);
+ p->source = source;
+ p->sizecode = 1;
+ p->code = (Instruction *)lua_reallocv(info->luaState, NULL, 0, 1, sizeof(Instruction));
+ p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ p->maxstacksize = 2;
+ p->sizek = 0;
+ p->sizep = 0;
+
+ lua_checkstack(info->luaState, 2);
+
+ pushProto(info->luaState, p);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // We don't need to register early, since protos can never ever be
+ // involved in cyclic references
+
+ // Read in constant references
+ int sizek = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
+ for (int i = 0; i < sizek; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... proto k
+
+ setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
+ p->sizek++;
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in sub-proto references
+
+ int sizep = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
+ for (int i = 0; i < sizep; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... proto subproto
+
+ p->p[i] = (Proto *)getObject(info->luaState, -1)->value.gc;
+ p->sizep++;
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+
+ // Read in code
+ p->sizecode = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->code, 1, p->sizecode, Instruction);
+ info->readStream->read(p->code, sizeof(Instruction) * p->sizecode);
+
+
+ /* Read in upvalue names */
+ p->sizeupvalues = info->readStream->readSint32LE();
+ if (p->sizeupvalues) {
+ lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
+ for (int i = 0; i < p->sizeupvalues; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ p->upvalues[i] = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in local variable infos
+ p->sizelocvars = info->readStream->readSint32LE();
+ if (p->sizelocvars) {
+ lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
+ for (int i = 0; i < p->sizelocvars; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ p->locvars[i].varname = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ p->locvars[i].startpc = info->readStream->readSint32LE();
+ p->locvars[i].endpc = info->readStream->readSint32LE();
+ }
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in source string
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... proto sourceStr
+
+ p->source = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in line numbers
+ p->sizelineinfo = info->readStream->readSint32LE();
+ if (p->sizelineinfo) {
+ lua_reallocvector(info->luaState, p->lineinfo, 0, p->sizelineinfo, int);
+ info->readStream->read(p->lineinfo, sizeof(int) * p->sizelineinfo);
+ }
+
+
+ /* Read in linedefined and lastlinedefined */
+ p->linedefined = info->readStream->readSint32LE();
+ p->lastlinedefined = info->readStream->readSint32LE();
+
+ // Read in misc values
+ p->nups = info->readStream->readByte();
+ p->numparams = info->readStream->readByte();
+ p->is_vararg = info->readStream->readByte();
+ p->maxstacksize = info->readStream->readByte();
+}
+
+void unserializeUpValue(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+ lua_checkstack(info->luaState, 2);
+
+ boxUpValue_start(info->luaState);
+ // >>>>> permTbl indexTbl ...... func
+ registerObjectInIndexTable(info, index);
+
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... func obj
+
+ boxUpValue_finish(info->luaState);
+ // >>>>> permTbl indexTbl ...... func
+}
+
+void unserializeUserData(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ int isspecial = info->readStream->readSint32LE();
+ if (isspecial) {
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... specialFunc
+
+ lua_call(info->luaState, 0, 1);
+ // >>>>> permTbl indexTbl ...... udata
+ } else {
+ uint32 length = info->readStream->readUint32LE();
+ lua_newuserdata(info->luaState, length);
+ // >>>>> permTbl indexTbl ...... udata
+ registerObjectInIndexTable(info, index);
+
+ info->readStream->read(lua_touserdata(info->luaState, -1), length);
+
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... udata metaTable/nil
+
+ lua_setmetatable(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... udata
+ }
+ // >>>>> permTbl indexTbl ...... udata
+}
+
+void unserializePermanent(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ unserialize(info);
+ // >>>>> permTbl indexTbl ...... permKey
+
+ lua_gettable(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... perm
+}
+
+} // End of namespace Lua
diff --git a/engines/sword25/util/lua_unserializer.cpp b/engines/sword25/util/lua_unserializer.cpp
deleted file mode 100644
index 803c79c8c2..0000000000
--- a/engines/sword25/util/lua_unserializer.cpp
+++ /dev/null
@@ -1,698 +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 "sword25/util/lua_serialization.h"
-
-#include "sword25/util/double_serializer.h"
-#include "sword25/util/lua_serialization_util.h"
-
-#include "common/stream.h"
-
-#include "lua/lobject.h"
-#include "lua/lstate.h"
-#include "lua/lgc.h"
-#include "lua/lopcodes.h"
-
-
-namespace Lua {
-
-struct UnSerializationInfo {
- lua_State *luaState;
- Common::ReadStream *readStream;
-};
-
-static void unserialize(UnSerializationInfo *info);
-
-static void unserializeBoolean(UnSerializationInfo *info);
-static void unserializeNumber(UnSerializationInfo *info);
-static void unserializeString(UnSerializationInfo *info);
-static void unserializeTable(UnSerializationInfo *info, int index);
-static void unserializeFunction(UnSerializationInfo *info, int index);
-static void unserializeThread(UnSerializationInfo *info, int index);
-static void unserializeProto(UnSerializationInfo *info, int index);
-static void unserializeUpValue(UnSerializationInfo *info, int index);
-static void unserializeUserData(UnSerializationInfo *info, int index);
-static void unserializePermanent(UnSerializationInfo *info, int index);
-
-
-void unserializeLua(lua_State *luaState, Common::ReadStream *readStream) {
- UnSerializationInfo info;
- info.luaState = luaState;
- info.readStream = readStream;
-
- // The process starts with the lua stack as follows:
- // >>>>> permTbl
- // That's the table of permanents
-
- // Make sure there is enough room on the stack
- lua_checkstack(luaState, 3);
-
- // Create a table to hold indexes of everything thats already been read
- lua_newtable(luaState);
- // >>>>> permTbl indexTbl
-
- // Prevent garbage collection while we unserialize
- lua_gc(luaState, LUA_GCSTOP, 0);
-
- // Unserialize the root object
- unserialize(&info);
- // >>>>> permTbl indexTbl rootObj
-
- // Re-start garbage collection
- lua_gc(luaState, LUA_GCRESTART, 0);
-
- // Remove the indexTbl
- lua_replace(luaState, 2);
- // >>>>> permTbl rootObj
-}
-
-/* The object is left on the stack. This is primarily used by unserialize, but
- * may be used by GCed objects that may incur cycles in order to preregister
- * the object. */
-static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ...... obj
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- lua_pushlightuserdata(info->luaState, (void *)index);
- // >>>>> permTbl indexTbl ...... obj index
-
- lua_pushvalue(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... obj index obj
-
- // Push the k/v pair into the indexTbl
- lua_settable(info->luaState, 2);
- // >>>>> permTbl indexTbl ...... obj
-}
-
-static void unserialize(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- byte isARealValue = info->readStream->readByte();
- if (isARealValue) {
- int index = info->readStream->readSint32LE();
- int type = info->readStream->readSint32LE();
-
- switch (type) {
- case LUA_TBOOLEAN:
- unserializeBoolean(info);
- break;
- case LUA_TLIGHTUSERDATA:
- // You can't serialize a pointer
- // It would be meaningless on the next run
- assert(0);
- break;
- case LUA_TNUMBER:
- unserializeNumber(info);
- break;
- case LUA_TSTRING:
- unserializeString(info);
- break;
- case LUA_TTABLE:
- unserializeTable(info, index);
- break;
- case LUA_TFUNCTION:
- unserializeFunction(info, index);
- break;
- case LUA_TTHREAD:
- unserializeThread(info, index);
- break;
- case LUA_TPROTO:
- unserializeProto(info, index);
- break;
- case LUA_TUPVAL:
- unserializeUpValue(info, index);
- break;
- case LUA_TUSERDATA:
- unserializeUserData(info, index);
- break;
- case PERMANENT_TYPE:
- unserializePermanent(info, index);
- break;
- default:
- assert(0);
- }
-
-
- // >>>>> permTbl indexTbl ...... obj
- assert(lua_type(info->luaState, -1) == type ||
- type == PERMANENT_TYPE ||
- // Remember, upvalues get a special dispensation, as described in boxUpValue
- (lua_type(info->luaState, -1) == LUA_TFUNCTION && type == LUA_TUPVAL));
-
- registerObjectInIndexTable(info, index);
- // >>>>> permTbl indexTbl ...... obj
- } else {
- int index = info->readStream->readSint32LE();
-
- if (index == 0) {
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... nil
- } else {
- // Fetch the object from the indexTbl
-
- lua_pushlightuserdata(info->luaState, (void *)index);
- // >>>>> permTbl indexTbl ...... index
-
- lua_gettable(info->luaState, 2);
- // >>>>> permTbl indexTbl ...... ?obj?
-
- assert(!lua_isnil(info->luaState, -1));
- }
- // >>>>> permTbl indexTbl ...... obj/nil
- }
-
- // >>>>> permTbl indexTbl ...... obj/nil
-}
-
-static void unserializeBoolean(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- int value = info->readStream->readSint32LE();
-
- lua_pushboolean(info->luaState, value);
- // >>>>> permTbl indexTbl ...... bool
-}
-
-static void unserializeNumber(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- // Read the serialized double
- Util::SerializedDouble serializedValue;
- serializedValue.significandOne = info->readStream->readUint32LE();
- serializedValue.signAndSignificandTwo = info->readStream->readUint32LE();
- serializedValue.exponent = info->readStream->readSint16LE();
-
- lua_Number value = Util::decodeDouble(serializedValue);
-
- lua_pushnumber(info->luaState, value);
- // >>>>> permTbl indexTbl ...... num
-}
-
-static void unserializeString(UnSerializationInfo *info) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- uint32 length = info->readStream->readUint32LE();
- char *string = new char[length];
-
- info->readStream->read(string, length);
- lua_pushlstring(info->luaState, string, length);
-
- // >>>>> permTbl indexTbl ...... string
-
- delete[] string;
-}
-
-static void unserializeSpecialTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- unserialize(info);
-
- // >>>>> permTbl indexTbl ...... spfunc
- lua_call(info->luaState, 0, 1);
- // >>>>> permTbl indexTbl ...... tbl
-}
-
-static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 3);
-
- // Preregister table for handling of cycles
- lua_newtable(info->luaState);
-
- // >>>>> permTbl indexTbl ...... tbl
- registerObjectInIndexTable(info, index);
- // >>>>> permTbl indexTbl ...... tbl
-
- // Unserialize metatable
- unserialize(info);
- // >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
-
- if (lua_istable(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... tbl metaTbl
- lua_setmetatable(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... tbl
- } else {
- // >>>>> permTbl indexTbl ...... tbl nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl
- }
- // >>>>> permTbl indexTbl ...... tbl
-
-
- while (1) {
- // >>>>> permTbl indexTbl ...... tbl
- unserialize(info);
- // >>>>> permTbl indexTbl ...... tbl key/nil
-
- // The table serialization is nil terminated
- if (lua_isnil(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... tbl nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... tbl
-
- break;
- }
-
- // >>>>> permTbl indexTbl ...... tbl key
- unserialize(info);
- // >>>>> permTbl indexTbl ...... tbl value
-
- lua_rawset(info->luaState, -3);
- // >>>>> permTbl indexTbl ...... tbl
- }
-}
-
-void unserializeTable(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 1);
-
- int isSpecial = info->readStream->readSint32LE();
-
- if (isSpecial) {
- unserializeSpecialTable(info, index);
- // >>>>> permTbl indexTbl ...... tbl
- } else {
- unserializeLiteralTable(info, index);
- // >>>>> permTbl indexTbl ...... tbl
- }
-}
-
-void unserializeFunction(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- byte numUpValues = info->readStream->readByte();
-
- LClosure *lclosure = (LClosure *)lua_newLclosure(info->luaState, numUpValues, hvalue(&info->luaState->l_gt));
- pushClosure(info->luaState, (Closure *)lclosure);
- // >>>>> permTbl indexTbl ...... func
-
- // Put *some* proto in the closure, before the GC can find it
- lclosure->p = makeFakeProto(info->luaState, numUpValues);
-
- //Also, we need to temporarily fill the upvalues
- lua_pushnil(info->luaState);
- // >>>>> permTbl indexTbl ...... func nil
-
- for (byte i = 0; i < numUpValues; ++i) {
- lclosure->upvals[i] = createUpValue(info->luaState, -1);
- }
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
-
- // I can't see offhand how a function would ever get to be self-
- // referential, but just in case let's register it early
- registerObjectInIndexTable(info, index);
-
- // Now that it's safe, we can get the real proto
- unserialize(info);
- // >>>>> permTbl indexTbl ...... func proto
-
- lclosure->p = gco2p(getObject(info->luaState, -1)->value.gc);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
-
- for (byte i = 0; i < numUpValues; ++i) {
- // >>>>> permTbl indexTbl ...... func
- unserialize(info);
- // >>>>> permTbl indexTbl ...... func func2
-
- unboxUpValue(info->luaState);
- // >>>>> permTbl indexTbl ...... func upValue
- lclosure->upvals[i] = gco2uv(getObject(info->luaState, -1)->value.gc);
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
- }
-
- // Finally, the fenv
- unserialize(info);
-
- // >>>>> permTbl indexTbl ...... func ?fenv/nil?
- if (!lua_isnil(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... func fenv
- lua_setfenv(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... func
- } else {
- // >>>>> permTbl indexTbl ...... func nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... func
- }
-
- // >>>>> permTbl indexTbl ...... func
-}
-
-void unserializeThread(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- lua_State *L2;
- uint32 stacklimit = 0;
-
- L2 = lua_newthread(info->luaState);
- lua_checkstack(info->luaState, 3);
-
- // L1: permTbl indexTbl ...... thread
- // L2: (empty)
- registerObjectInIndexTable(info, index);
-
- // First, deserialize the object stack
- uint32 stackSize = info->readStream->readUint32LE();
- lua_growstack(info->luaState, (int)stackSize);
-
- // Make sure that the first stack element (a nil, representing
- // the imaginary top-level C function) is written to the very,
- // very bottom of the stack
- L2->top--;
- for (uint32 i = 0; i < stackSize; ++i) {
- unserialize(info);
- // L1: permTbl indexTbl ...... thread obj*
- }
-
- lua_xmove(info->luaState, L2, stackSize);
- // L1: permTbl indexTbl ...... thread
- // L2: obj*
-
- // Hereafter, stacks refer to L1
-
-
- // Now, deserialize the CallInfo stack
-
- uint32 numFrames = info->readStream->readUint32LE();
-
- lua_reallocCallInfo(L2, numFrames * 2);
- for (uint32 i = 0; i < numFrames; ++i) {
- CallInfo *ci = L2->base_ci + i;
- uint32 stackbase = info->readStream->readUint32LE();
- uint32 stackfunc = info->readStream->readUint32LE();
- uint32 stacktop = info->readStream->readUint32LE();
-
- ci->nresults = info->readStream->readSint32LE();
-
- uint32 savedpc = info->readStream->readUint32LE();
-
- if (stacklimit < stacktop) {
- stacklimit = stacktop;
- }
-
- ci->base = L2->stack + stackbase;
- ci->func = L2->stack + stackfunc;
- ci->top = L2->stack + stacktop;
- ci->savedpc = (ci != L2->base_ci) ? ci_func(ci)->l.p->code + savedpc : 0;
- ci->tailcalls = 0;
-
- // Update the pointer each time, to keep the GC happy
- L2->ci = ci;
- }
-
- // >>>>> permTbl indexTbl ...... thread
- // Deserialize the state's other parameters, with the exception of upval stuff
-
- L2->savedpc = L2->ci->savedpc;
- L2->status = info->readStream->readByte();
- uint32 stackbase = info->readStream->readUint32LE();
- uint32 stacktop = info->readStream->readUint32LE();
-
-
- L2->errfunc = info->readStream->readUint32LE();
-
- L2->base = L2->stack + stackbase;
- L2->top = L2->stack + stacktop;
-
- // Finally, "reopen" upvalues. See serializeUpVal() for why we do this
- UpVal *uv;
- GCObject **nextslot = &L2->openupval;
- global_State *g = G(L2);
-
- while (true) {
- unserialize(info);
- // >>>>> permTbl indexTbl ...... thread upVal/nil
-
- // The list is terminated by a nil
- if (lua_isnil(info->luaState, -1)) {
- // >>>>> permTbl indexTbl ...... thread nil
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... thread
- break;
- }
-
- // >>>>> permTbl indexTbl ...... thread boxedUpVal
- unboxUpValue(info->luaState);
- // >>>>> permTbl indexTbl ...... thread boxedUpVal
-
- uv = &(getObject(info->luaState, -1)->value.gc->uv);
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... thread
-
- uint32 stackpos = info->readStream->readUint32LE();
- uv->v = L2->stack + stackpos;
-
- GCUnlink(info->luaState, (GCObject *)uv);
-
- uv->marked = luaC_white(g);
- *nextslot = (GCObject *)uv;
- nextslot = &uv->next;
- uv->u.l.prev = &G(L2)->uvhead;
- uv->u.l.next = G(L2)->uvhead.u.l.next;
- uv->u.l.next->u.l.prev = uv;
- G(L2)->uvhead.u.l.next = uv;
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- }
- *nextslot = NULL;
-
- // The stack must be valid at least to the highest value among the CallInfos
- // 'top' and the values up to there must be filled with 'nil'
- lua_checkstack(L2, (int)stacklimit);
- for (StkId o = L2->top; o <= L2->top + stacklimit; ++o) {
- setnilvalue(o);
- }
-}
-
-void unserializeProto(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // We have to be careful. The GC expects a lot out of protos. In particular, we need
- // to give the function a valid string for its source, and valid code, even before we
- // actually read in the real code.
- TString *source = lua_newlstr(info->luaState, "", 0);
- Proto *p = lua_newproto(info->luaState);
- p->source = source;
- p->sizecode = 1;
- p->code = (Instruction *)lua_reallocv(info->luaState, NULL, 0, 1, sizeof(Instruction));
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->maxstacksize = 2;
- p->sizek = 0;
- p->sizep = 0;
-
- lua_checkstack(info->luaState, 2);
-
- pushProto(info->luaState, p);
- // >>>>> permTbl indexTbl ...... proto
-
- // We don't need to register early, since protos can never ever be
- // involved in cyclic references
-
- // Read in constant references
- int sizek = info->readStream->readSint32LE();
- lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
- for (int i = 0; i < sizek; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unserialize(info);
- // >>>>> permTbl indexTbl ...... proto k
-
- setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
- p->sizek++;
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in sub-proto references
-
- int sizep = info->readStream->readSint32LE();
- lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
- for (int i = 0; i < sizep; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unserialize(info);
- // >>>>> permTbl indexTbl ...... proto subproto
-
- p->p[i] = (Proto *)getObject(info->luaState, -1)->value.gc;
- p->sizep++;
-
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
- // >>>>> permTbl indexTbl ...... proto
-
-
- // Read in code
- p->sizecode = info->readStream->readSint32LE();
- lua_reallocvector(info->luaState, p->code, 1, p->sizecode, Instruction);
- info->readStream->read(p->code, sizeof(Instruction) * p->sizecode);
-
-
- /* Read in upvalue names */
- p->sizeupvalues = info->readStream->readSint32LE();
- if (p->sizeupvalues) {
- lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
- for (int i = 0; i < p->sizeupvalues; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unserialize(info);
- // >>>>> permTbl indexTbl ...... proto str
-
- p->upvalues[i] = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
- }
- }
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in local variable infos
- p->sizelocvars = info->readStream->readSint32LE();
- if (p->sizelocvars) {
- lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
- for (int i = 0; i < p->sizelocvars; ++i) {
- // >>>>> permTbl indexTbl ...... proto
- unserialize(info);
- // >>>>> permTbl indexTbl ...... proto str
-
- p->locvars[i].varname = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
-
- p->locvars[i].startpc = info->readStream->readSint32LE();
- p->locvars[i].endpc = info->readStream->readSint32LE();
- }
- }
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in source string
- unserialize(info);
- // >>>>> permTbl indexTbl ...... proto sourceStr
-
- p->source = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
- lua_pop(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... proto
-
- // Read in line numbers
- p->sizelineinfo = info->readStream->readSint32LE();
- if (p->sizelineinfo) {
- lua_reallocvector(info->luaState, p->lineinfo, 0, p->sizelineinfo, int);
- info->readStream->read(p->lineinfo, sizeof(int) * p->sizelineinfo);
- }
-
-
- /* Read in linedefined and lastlinedefined */
- p->linedefined = info->readStream->readSint32LE();
- p->lastlinedefined = info->readStream->readSint32LE();
-
- // Read in misc values
- p->nups = info->readStream->readByte();
- p->numparams = info->readStream->readByte();
- p->is_vararg = info->readStream->readByte();
- p->maxstacksize = info->readStream->readByte();
-}
-
-void unserializeUpValue(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
- lua_checkstack(info->luaState, 2);
-
- boxUpValue_start(info->luaState);
- // >>>>> permTbl indexTbl ...... func
- registerObjectInIndexTable(info, index);
-
- unserialize(info);
- // >>>>> permTbl indexTbl ...... func obj
-
- boxUpValue_finish(info->luaState);
- // >>>>> permTbl indexTbl ...... func
-}
-
-void unserializeUserData(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- int isspecial = info->readStream->readSint32LE();
- if (isspecial) {
- unserialize(info);
- // >>>>> permTbl indexTbl ...... specialFunc
-
- lua_call(info->luaState, 0, 1);
- // >>>>> permTbl indexTbl ...... udata
- } else {
- uint32 length = info->readStream->readUint32LE();
- lua_newuserdata(info->luaState, length);
- // >>>>> permTbl indexTbl ...... udata
- registerObjectInIndexTable(info, index);
-
- info->readStream->read(lua_touserdata(info->luaState, -1), length);
-
- unserialize(info);
- // >>>>> permTbl indexTbl ...... udata metaTable/nil
-
- lua_setmetatable(info->luaState, -2);
- // >>>>> permTbl indexTbl ...... udata
- }
- // >>>>> permTbl indexTbl ...... udata
-}
-
-void unserializePermanent(UnSerializationInfo *info, int index) {
- // >>>>> permTbl indexTbl ......
-
- // Make sure there is enough room on the stack
- lua_checkstack(info->luaState, 2);
-
- unserialize(info);
- // >>>>> permTbl indexTbl ...... permKey
-
- lua_gettable(info->luaState, 1);
- // >>>>> permTbl indexTbl ...... perm
-}
-
-} // End of namespace Lua
--
cgit v1.2.3
From 08e3f21a8df184bc697e6c03adf968d0cbdbac21 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 15:22:43 -0600
Subject: SWORD25: Rename double serialization file to better represent what it
is
AKA functions, rather than a class
---
engines/sword25/module.mk | 2 +-
engines/sword25/util/double_serialization.cpp | 138 ++++++++++++++++++++++++++
engines/sword25/util/double_serialization.h | 95 ++++++++++++++++++
engines/sword25/util/double_serializer.cpp | 138 --------------------------
engines/sword25/util/double_serializer.h | 95 ------------------
engines/sword25/util/lua_persist.cpp | 2 +-
engines/sword25/util/lua_unpersist.cpp | 2 +-
7 files changed, 236 insertions(+), 236 deletions(-)
create mode 100644 engines/sword25/util/double_serialization.cpp
create mode 100644 engines/sword25/util/double_serialization.h
delete mode 100644 engines/sword25/util/double_serializer.cpp
delete mode 100644 engines/sword25/util/double_serializer.h
diff --git a/engines/sword25/module.mk b/engines/sword25/module.mk
index 129b4f040e..0842eb9aa8 100644
--- a/engines/sword25/module.mk
+++ b/engines/sword25/module.mk
@@ -82,7 +82,7 @@ MODULE_OBJS := \
util/lua/lvm.o \
util/lua/lzio.o \
util/lua/scummvm_file.o \
- util/double_serializer.o \
+ util/double_serialization.o \
util/lua_persistence_util.o \
util/lua_persist.o \
util/lua_unpersist.o
diff --git a/engines/sword25/util/double_serialization.cpp b/engines/sword25/util/double_serialization.cpp
new file mode 100644
index 0000000000..48fd75cb33
--- /dev/null
+++ b/engines/sword25/util/double_serialization.cpp
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sword25/util/double_serialization.h"
+
+#include "common/scummsys.h"
+
+
+namespace Util {
+
+SerializedDouble encodeDouble(double value) {
+ // Split the value into its significand and exponent
+ int exponent;
+ double significand = frexp(value, &exponent);
+
+ // Shift the the first part of the significand into the integer range
+ double shiftedsignificandPart = ldexp(abs(significand), 32);
+ uint32 significandOne = uint32(floor(shiftedsignificandPart));
+
+ // Shift the remainder of the significand into the integer range
+ shiftedsignificandPart -= significandOne;
+ uint32 significandTwo = (uint32)(ldexp(shiftedsignificandPart, 31));
+
+ SerializedDouble returnValue;
+ returnValue.significandOne = significandOne; // SignificandOne
+ returnValue.signAndSignificandTwo = ((uint32)(value < 0 ? 1 : 0) << 31) | // Sign
+ significandTwo; // SignificandTwo
+ returnValue.exponent = (int16)exponent;
+ return returnValue;
+}
+
+double decodeDouble(SerializedDouble value) {
+ // Expand the exponent and the parts of the significand
+ int exponent = (int)value.exponent;
+ double expandedsignificandOne = (double)value.significandOne;
+ double expandedsignificandTwo = (double)(value.signAndSignificandTwo & 0x7FFFFFFF);
+
+ // Deflate the significand
+ double shiftedsignificand = ldexp(expandedsignificandTwo, -21);
+ double significand = ldexp(expandedsignificandOne + shiftedsignificand, -32);
+
+ // Re-calculate the actual double
+ double returnValue = ldexp(significand, exponent);
+
+ // Check the sign bit and return
+ return ((value.signAndSignificandTwo & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
+}
+
+uint64 encodeDouble_64(double value) {
+ // Split the value into its significand and exponent
+ int exponent;
+ double significand = frexp(value, &exponent);
+
+ // Shift the significand into the integer range
+ double shiftedsignificand = ldexp(abs(significand), 53);
+
+ // Combine everything using the IEEE standard
+ uint64 uintsignificand = (uint64)shiftedsignificand;
+ return ((uint64)(value < 0 ? 1 : 0) << 63) | // Sign
+ ((uint64)(exponent + 1023) << 52) | // Exponent stored as an offset to 1023
+ (uintsignificand & 0x000FFFFFFFFFFFFF); // significand with MSB inferred
+}
+
+double decodeDouble_64(uint64 value) {
+ // Expand the exponent and significand
+ int exponent = (int)((value >> 52) & 0x7FF) - 1023;
+ double expandedsignificand = (double)(0x10000000000000 /* Inferred MSB */ | (value & 0x000FFFFFFFFFFFFF));
+
+ // Deflate the significand
+ int temp;
+ double significand = frexp(expandedsignificand, &temp);
+
+ // Re-calculate the actual double
+ double returnValue = ldexp(significand, exponent);
+
+ // Check the sign bit and return
+ return ((value & 0x8000000000000000) == 0x8000000000000000) ? -returnValue : returnValue;
+}
+
+CompactSerializedDouble encodeDouble_Compact(double value) {
+ // Split the value into its significand and exponent
+ int exponent;
+ double significand = frexp(value, &exponent);
+
+ // Shift the the first part of the significand into the integer range
+ double shiftedsignificandPart = ldexp(abs(significand), 32);
+ uint32 significandOne = uint32(floor(shiftedsignificandPart));
+
+ // Shift the remainder of the significand into the integer range
+ shiftedsignificandPart -= significandOne;
+ uint32 significandTwo = (uint32)(ldexp(shiftedsignificandPart, 21));
+
+ CompactSerializedDouble returnValue;
+ returnValue.signAndSignificandOne = ((uint32)(value < 0 ? 1 : 0) << 31) | // Sign
+ (significandOne & 0x7FFFFFFF); // significandOne with MSB inferred
+ // Exponent stored as an offset to 1023
+ returnValue.exponentAndSignificandTwo = ((uint32)(exponent + 1023) << 21) | significandTwo;
+
+ return returnValue;
+}
+
+double decodeDouble_Compact(CompactSerializedDouble value) {
+ // Expand the exponent and the parts of the significand
+ int exponent = (int)(value.exponentAndSignificandTwo >> 21) - 1023;
+ double expandedsignificandOne = (double)(0x80000000 /* Inferred MSB */ | (value.signAndSignificandOne & 0x7FFFFFFF));
+ double expandedsignificandTwo = (double)(value.exponentAndSignificandTwo & 0x1FFFFF);
+
+ // Deflate the significand
+ double shiftedsignificand = ldexp(expandedsignificandTwo, -21);
+ double significand = ldexp(expandedsignificandOne + shiftedsignificand, -32);
+
+ // Re-calculate the actual double
+ double returnValue = ldexp(significand, exponent);
+
+ // Check the sign bit and return
+ return ((value.signAndSignificandOne & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/util/double_serialization.h b/engines/sword25/util/double_serialization.h
new file mode 100644
index 0000000000..e90338c369
--- /dev/null
+++ b/engines/sword25/util/double_serialization.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 DOUBLE_SERIALIZATION_H
+#define DOUBLE_SERIALIZATION_H
+
+#include "common/types.h"
+
+
+namespace Util {
+
+struct SerializedDouble {
+ uint32 significandOne;
+ uint32 signAndSignificandTwo;
+ int16 exponent;
+};
+
+struct CompactSerializedDouble {
+ uint32 signAndSignificandOne;
+ uint32 exponentAndSignificandTwo;
+};
+
+/**
+ * Encodes a double as two uint32 and a one int16
+ *
+ * Supports denormalized numbers. Does NOT support NaN, or Inf
+ *
+ * @param value The value to encode
+ * @return The encoded value
+ */
+SerializedDouble encodeDouble(double value);
+/**
+ * Decodes a previously encoded double
+ *
+ * @param value The value to decode
+ * @return The decoded value
+ */
+double decodeDouble(SerializedDouble value);
+
+/**
+ * Encodes a double as a uint64
+ *
+ * Does NOT support denormalized numbers. Does NOT support NaN, or Inf
+ *
+ * @param value The value to encode
+ * @return The encoded value
+ */
+uint64 encodeDouble_64(double value);
+/**
+ * Decodes a previously encoded double
+ *
+ * @param value The value to decode
+ * @return The decoded value
+ */
+double decodeDouble_64(uint64 value);
+
+/**
+ * Encodes a double as two uint32
+ *
+ * Does NOT support denormalized numbers. Does NOT support NaN, or Inf
+ *
+ * @param value The value to encode
+ * @return The encoded value
+ */
+CompactSerializedDouble encodeDouble_Compact(double value);
+/**
+ * Decodes a previously encoded double
+ *
+ * @param value The value to decode
+ * @return The decoded value
+ */
+double decodeDouble_Compact(CompactSerializedDouble value);
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/util/double_serializer.cpp b/engines/sword25/util/double_serializer.cpp
deleted file mode 100644
index d7ba4f3052..0000000000
--- a/engines/sword25/util/double_serializer.cpp
+++ /dev/null
@@ -1,138 +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 "sword25/util/double_serializer.h"
-
-#include "common/scummsys.h"
-
-
-namespace Util {
-
-SerializedDouble encodeDouble(double value) {
- // Split the value into its significand and exponent
- int exponent;
- double significand = frexp(value, &exponent);
-
- // Shift the the first part of the significand into the integer range
- double shiftedsignificandPart = ldexp(abs(significand), 32);
- uint32 significandOne = uint32(floor(shiftedsignificandPart));
-
- // Shift the remainder of the significand into the integer range
- shiftedsignificandPart -= significandOne;
- uint32 significandTwo = (uint32)(ldexp(shiftedsignificandPart, 31));
-
- SerializedDouble returnValue;
- returnValue.significandOne = significandOne; // SignificandOne
- returnValue.signAndSignificandTwo = ((uint32)(value < 0 ? 1 : 0) << 31) | // Sign
- significandTwo; // SignificandTwo
- returnValue.exponent = (int16)exponent;
- return returnValue;
-}
-
-double decodeDouble(SerializedDouble value) {
- // Expand the exponent and the parts of the significand
- int exponent = (int)value.exponent;
- double expandedsignificandOne = (double)value.significandOne;
- double expandedsignificandTwo = (double)(value.signAndSignificandTwo & 0x7FFFFFFF);
-
- // Deflate the significand
- double shiftedsignificand = ldexp(expandedsignificandTwo, -21);
- double significand = ldexp(expandedsignificandOne + shiftedsignificand, -32);
-
- // Re-calculate the actual double
- double returnValue = ldexp(significand, exponent);
-
- // Check the sign bit and return
- return ((value.signAndSignificandTwo & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
-}
-
-uint64 encodeDouble_64(double value) {
- // Split the value into its significand and exponent
- int exponent;
- double significand = frexp(value, &exponent);
-
- // Shift the significand into the integer range
- double shiftedsignificand = ldexp(abs(significand), 53);
-
- // Combine everything using the IEEE standard
- uint64 uintsignificand = (uint64)shiftedsignificand;
- return ((uint64)(value < 0 ? 1 : 0) << 63) | // Sign
- ((uint64)(exponent + 1023) << 52) | // Exponent stored as an offset to 1023
- (uintsignificand & 0x000FFFFFFFFFFFFF); // significand with MSB inferred
-}
-
-double decodeDouble_64(uint64 value) {
- // Expand the exponent and significand
- int exponent = (int)((value >> 52) & 0x7FF) - 1023;
- double expandedsignificand = (double)(0x10000000000000 /* Inferred MSB */ | (value & 0x000FFFFFFFFFFFFF));
-
- // Deflate the significand
- int temp;
- double significand = frexp(expandedsignificand, &temp);
-
- // Re-calculate the actual double
- double returnValue = ldexp(significand, exponent);
-
- // Check the sign bit and return
- return ((value & 0x8000000000000000) == 0x8000000000000000) ? -returnValue : returnValue;
-}
-
-CompactSerializedDouble encodeDouble_Compact(double value) {
- // Split the value into its significand and exponent
- int exponent;
- double significand = frexp(value, &exponent);
-
- // Shift the the first part of the significand into the integer range
- double shiftedsignificandPart = ldexp(abs(significand), 32);
- uint32 significandOne = uint32(floor(shiftedsignificandPart));
-
- // Shift the remainder of the significand into the integer range
- shiftedsignificandPart -= significandOne;
- uint32 significandTwo = (uint32)(ldexp(shiftedsignificandPart, 21));
-
- CompactSerializedDouble returnValue;
- returnValue.signAndSignificandOne = ((uint32)(value < 0 ? 1 : 0) << 31) | // Sign
- (significandOne & 0x7FFFFFFF); // significandOne with MSB inferred
- // Exponent stored as an offset to 1023
- returnValue.exponentAndSignificandTwo = ((uint32)(exponent + 1023) << 21) | significandTwo;
-
- return returnValue;
-}
-
-double decodeDouble_Compact(CompactSerializedDouble value) {
- // Expand the exponent and the parts of the significand
- int exponent = (int)(value.exponentAndSignificandTwo >> 21) - 1023;
- double expandedsignificandOne = (double)(0x80000000 /* Inferred MSB */ | (value.signAndSignificandOne & 0x7FFFFFFF));
- double expandedsignificandTwo = (double)(value.exponentAndSignificandTwo & 0x1FFFFF);
-
- // Deflate the significand
- double shiftedsignificand = ldexp(expandedsignificandTwo, -21);
- double significand = ldexp(expandedsignificandOne + shiftedsignificand, -32);
-
- // Re-calculate the actual double
- double returnValue = ldexp(significand, exponent);
-
- // Check the sign bit and return
- return ((value.signAndSignificandOne & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
-}
-
-} // End of namespace Sword25
diff --git a/engines/sword25/util/double_serializer.h b/engines/sword25/util/double_serializer.h
deleted file mode 100644
index e90338c369..0000000000
--- a/engines/sword25/util/double_serializer.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef DOUBLE_SERIALIZATION_H
-#define DOUBLE_SERIALIZATION_H
-
-#include "common/types.h"
-
-
-namespace Util {
-
-struct SerializedDouble {
- uint32 significandOne;
- uint32 signAndSignificandTwo;
- int16 exponent;
-};
-
-struct CompactSerializedDouble {
- uint32 signAndSignificandOne;
- uint32 exponentAndSignificandTwo;
-};
-
-/**
- * Encodes a double as two uint32 and a one int16
- *
- * Supports denormalized numbers. Does NOT support NaN, or Inf
- *
- * @param value The value to encode
- * @return The encoded value
- */
-SerializedDouble encodeDouble(double value);
-/**
- * Decodes a previously encoded double
- *
- * @param value The value to decode
- * @return The decoded value
- */
-double decodeDouble(SerializedDouble value);
-
-/**
- * Encodes a double as a uint64
- *
- * Does NOT support denormalized numbers. Does NOT support NaN, or Inf
- *
- * @param value The value to encode
- * @return The encoded value
- */
-uint64 encodeDouble_64(double value);
-/**
- * Decodes a previously encoded double
- *
- * @param value The value to decode
- * @return The decoded value
- */
-double decodeDouble_64(uint64 value);
-
-/**
- * Encodes a double as two uint32
- *
- * Does NOT support denormalized numbers. Does NOT support NaN, or Inf
- *
- * @param value The value to encode
- * @return The encoded value
- */
-CompactSerializedDouble encodeDouble_Compact(double value);
-/**
- * Decodes a previously encoded double
- *
- * @param value The value to decode
- * @return The decoded value
- */
-double decodeDouble_Compact(CompactSerializedDouble value);
-
-} // End of namespace Sword25
-
-#endif
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
index b9c0b13e11..939dbf38a8 100644
--- a/engines/sword25/util/lua_persist.cpp
+++ b/engines/sword25/util/lua_persist.cpp
@@ -22,7 +22,7 @@
#include "sword25/util/lua_persistence.h"
-#include "sword25/util/double_serializer.h"
+#include "sword25/util/double_serialization.h"
#include "sword25/util/lua_persistence_util.h"
#include "common/stream.h"
diff --git a/engines/sword25/util/lua_unpersist.cpp b/engines/sword25/util/lua_unpersist.cpp
index aa924ff7c5..8d644302f9 100644
--- a/engines/sword25/util/lua_unpersist.cpp
+++ b/engines/sword25/util/lua_unpersist.cpp
@@ -22,7 +22,7 @@
#include "sword25/util/lua_persistence.h"
-#include "sword25/util/double_serializer.h"
+#include "sword25/util/double_serialization.h"
#include "sword25/util/lua_persistence_util.h"
#include "common/stream.h"
--
cgit v1.2.3
From 8668707f160fa171edfa68df036f28c7ba4e9a88 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 15:11:17 -0600
Subject: SWORD25: Fix how nils are persisted
The unpersist code expects nils to be represented as an index with value 0.
The persist code incorrectly wrote out this data
---
engines/sword25/util/lua_persist.cpp | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
index 939dbf38a8..6d758067ad 100644
--- a/engines/sword25/util/lua_persist.cpp
+++ b/engines/sword25/util/lua_persist.cpp
@@ -59,7 +59,7 @@ void persistLua(lua_State *luaState, Common::WriteStream *writeStream) {
SerializationInfo info;
info.luaState = luaState;
info.writeStream = writeStream;
- info.counter = 0u;
+ info.counter = 1u;
// The process starts with the lua stack as follows:
// >>>>> permTbl rootObj
@@ -145,19 +145,22 @@ static void serialize(SerializationInfo *info) {
return;
}
- // Pop the nil off the stack
+ // Pop the index/nil off the stack
lua_pop(info->luaState, 1);
- // Write out a flag that indicates that this is a real object
- info->writeStream->writeByte(1);
-
- // If the object itself is nil, then write out a zero as a placeholder
+ // If the obj itself is nil, we represent it as an index of 0
if (lua_isnil(info->luaState, -1)) {
+ // Write out a flag that indicates that it's an index
info->writeStream->writeByte(0);
+ // Write out the index
+ info->writeStream->writeUint32LE(0);
return;
}
+ // Write out a flag that indicates that this is a real object
+ info->writeStream->writeByte(1);
+
// Add the object to the indexTbl
lua_pushvalue(info->luaState, -1);
--
cgit v1.2.3
From 67114c3e7eafdd6ba8c7bc799a40f789acc1efa3 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 15:30:55 -0600
Subject: SWORD25: Remove old lua persistence files
---
engines/sword25/util/pluto/CHANGELOG | 37 -
engines/sword25/util/pluto/FILEFORMAT | 168 ---
engines/sword25/util/pluto/README | 133 --
engines/sword25/util/pluto/THANKS | 9 -
engines/sword25/util/pluto/pdep.cpp | 112 --
engines/sword25/util/pluto/pdep/README | 5 -
engines/sword25/util/pluto/pdep/lzio.h | 65 -
engines/sword25/util/pluto/pdep/pdep.h | 42 -
engines/sword25/util/pluto/pluto.cpp | 2083 --------------------------------
engines/sword25/util/pluto/pluto.h | 25 -
engines/sword25/util/pluto/plzio.cpp | 74 --
11 files changed, 2753 deletions(-)
delete mode 100644 engines/sword25/util/pluto/CHANGELOG
delete mode 100644 engines/sword25/util/pluto/FILEFORMAT
delete mode 100644 engines/sword25/util/pluto/README
delete mode 100644 engines/sword25/util/pluto/THANKS
delete mode 100644 engines/sword25/util/pluto/pdep.cpp
delete mode 100644 engines/sword25/util/pluto/pdep/README
delete mode 100644 engines/sword25/util/pluto/pdep/lzio.h
delete mode 100644 engines/sword25/util/pluto/pdep/pdep.h
delete mode 100644 engines/sword25/util/pluto/pluto.cpp
delete mode 100644 engines/sword25/util/pluto/pluto.h
delete mode 100644 engines/sword25/util/pluto/plzio.cpp
diff --git a/engines/sword25/util/pluto/CHANGELOG b/engines/sword25/util/pluto/CHANGELOG
deleted file mode 100644
index 1be321f898..0000000000
--- a/engines/sword25/util/pluto/CHANGELOG
+++ /dev/null
@@ -1,37 +0,0 @@
-$Id$
-
--- 2.4 --
-* Changed upval unboxing to allow upvals which contain func-housed cycles
-* Added stack checking to all stack-growing functions
-* Serialized debug information for functions
-
--- 2.3 --
-* Added LUALIB_API declaration for luaopen_pluto
-
--- 2.2 --
-* Rolled all internal Lua dependencies into the Pluto distribution
-* Made the unit tests depend on dynamically loading Pluto
-
--- 2.1 --
-* Various fixes to make the GC happy
-* stack size always expanded where necessary
-* fixed some memory leaks
-* GC disabled during unpersist
-* callstack initialized for traversal
-
-This changelog is maintained as of version 2.0alpha1.
-Earlier versions are changelogged on the LuaForge site.
-
--- 2.0 --
-* Fixed a few format changes to 5.1.3
-* Fixed myriad warnings
-* GCC compliance: not incrementing cast results
-* Fix for self-referring upvals
-* Renamed loading function to work with Lua module system
-* Loading tables with __newindex works
-* unpersist makes buffer copy
-
--- 2.0alpha1 --
-* Fixed all outstanding 5.0->5.1 conversion issues
-* Made heavier use of size_t in preference to int
-* Fixed GC/Upval issue (thanks to Eric Jacobs)
diff --git a/engines/sword25/util/pluto/FILEFORMAT b/engines/sword25/util/pluto/FILEFORMAT
deleted file mode 100644
index e7716675c7..0000000000
--- a/engines/sword25/util/pluto/FILEFORMAT
+++ /dev/null
@@ -1,168 +0,0 @@
-$Id$
-
-pluto_persist() produces a "hunk" of objects. Here's the file format adhered
-to by the function, and expected by pluto_unpersist().
-
-As a developer, I feel that where file format information is given it is of
-utmost importance that that information precisely and accurately reflects the
-actual operation of the application. Therefore, if you find any discrepancy
-between this and actual operation, please lambast me thoroughly over email.
-
-Pseudo-C is used to express the file format. Padding is assumed to be
-nonexistent. The keyword "one_of" is used to express a concept similar to
-"union", except that its size is the size of the actual datatype chosen. Thus,
-objects which contain, directly or indirectly, a one_of, may vary in size.
-
-
-struct Object {
- int firstTime; /* Whether this is the first time the object
- is being referenced */
- one_of {
- RealObject o; /* if firstTime == 1 */
- Reference r; /* if firstTime == 0 */
- };
-};
-
-struct Reference {
- int ref; /* The index the object was registered with */
-};
-
-struct RealObject {
- int type; /* The type of the object */
- one_of {
- Boolean b; /* If type == LUA_TBOOLEAN */
- LightUserData l; /* If type == LUA_TLIGHTUSERDATA */
- Number n; /* If type == LUA_TNUMBER */
- String s; /* If type == LUA_TSTRING */
- Table t; /* If type == LUA_TTABLE */
- Function f; /* If type == LUA_TFUNCTION */
- Userdata u; /* If type == LUA_TUSERDATA */
- Thread th; /* If type == LUA_TTHREAD */
- Proto p; /* If type == LUA_TPROTO (from lobject.h) */
- Upval uv; /* If type == LUA_TUPVAL (from lobject.h) */
- }; /* The actual object */
-};
-
-struct Boolean {
- int32 bvalue; /* 0 for false, 1 for true */
-};
-
-struct LightUserData {
- void* luvalue; /* The actual, literal pointer */
-};
-
-struct Number {
- lua_Number nvalue; /* The actual number */
-};
-
-struct String {
- int length; /* The length of the string */
- char str[length]; /* The actual string (not null terminated) */
-};
-
-struct Table {
- int isspecial; /* 1 if SP is used; 0 otherwise */
- one_of {
- Closure c; /* if isspecial == 1; closure to refill the table */
- LiteralTable t; /* if isspecial == 0; literal table info */
- };
-};
-
-struct LiteralTable {
- Object metatable; /* nil for default metatable */
- Pair p[]; /* key/value pairs */
- Object nil = nil; /* Nil reference to terminate */
-};
-
-struct Pair {
- Object key;
- Object value;
-};
-
-struct Function { /* Actually a closure */
- lu_byte nups; /* Number of upvalues the function uses */
- Object proto; /* The proto this function uses */
- Object upvals[nups]; /* All upvalues */
- Object fenv; /* The FEnv (nil for the global table)
-};
-
-struct Upval {
- Object obj; /* The object this upval refers to */
-}
-
-struct Userdata {
- int isSpecial; /* 1 for special persistence, 0 for literal
- one_of {
- LiteralUserdata lu; /* if is_special is 0 */
- SpecialUserdata su; /* if is_special is 1 */
- };
-};
-
-struct LiteralUserdata {
- Object metatable; /* The metatable (nil for default) */
- int length; /* Size of the data */
- char data[length]; /* The actual data */
-};
-
-struct SpecialUserdata {
- int length; /* The size of the data */
- Object func; /* The closure used to fill the userdata */
-};
-
-struct Thread {
- int stacksize; /* The size of the stack filled with objects,
- * including the "nil" that is hidden below
- * the bottom of the stack visible to C */
- Object stack[stacksize];/* Indices of all stack values, bottom up */
- int callinfosize; /* Number of elements in the CallInfo stack */
- CallInfo callinfostack[callinfosize]; /* The CallInfo stack */
- int base; /* base = L->base - L->stack; */
- int top; /* top = L->top - L->stack; */
- OpenUpval openupvals[]; /* Upvalues to open */
- Object nil = nil; /* To terminate the open upvalues list */
-};
-
-struct OpenUpval {
- Object upval; /* The upvalue */
- int stackpos; /* The stack position to "reopen" it to */
-
-};
-
-struct CallInfo {
- int base; /* base = ci->base - L->stack; */
- int top; /* top = ci->top - L->stack; */
- int pc; /* pc = ci->pc - proto->code; */
- int state; /* flags used by the CallInfo */
-};
-
-struct Proto {
- int sizek; /* Number of constants referenced */
- Object k[sizek]; /* Constants referenced */
- int sizep; /* Number of inner Protos referenced */
- Object p[sizep]; /* Inner Protos referenced */
- int sizecode; /* Number of instructions in code */
- Instruction code[sizecode]; /* The proto's code */
- ProtoDebug debuginfo; /* Debug information for the proto */
- lu_byte nups; /* Number of upvalues used */
- lu_byte numparams; /* Number of parameters taken */
- lu_byte is_vararg; /* 1 if function accepts varargs, 0 otherwise */
- lu_byte maxstacksize; /* Size of stack reserved for the function */
-};
-
-struct ProtoDebug {
- int sizeupvals; /* Number of upvalue names */
- Object upvals; /* Upvalue names */
- int sizelocvars; /* Number of local variable names */
- LocVar[sizelocvars]; /* Local variable names */
- Object source; /* The source code */
- int sizelineinfo; /* Number of opcode-line mappings */
- int lineinfo[sizelineinfo]; /* opcode-line mappings */
- int linedefined; /* Start of line range */
- int lastlinedefined; /* End of line range */
-};
-
-struct LocVar {
- Object name; /* Name of the local variable */
- int startpc; /* Point where variable is active */
- int endpc; /* Point where variable is dead */
-};
diff --git a/engines/sword25/util/pluto/README b/engines/sword25/util/pluto/README
deleted file mode 100644
index 838fce498b..0000000000
--- a/engines/sword25/util/pluto/README
+++ /dev/null
@@ -1,133 +0,0 @@
-$Id$
-
-PLUTO - Heavy duty persistence for Lua
-
-Pluto is a library which allows users to write arbitrarily large portions
-of the "Lua universe" into a flat file, and later read them back into the
-same or a different Lua universe. Object references are appropriately
-handled, such that the file contains everything needed to recreate the
-objects in question.
-
-Pluto has the following major features:
-* Can persist any Lua function
-* Can persist threads
-* Works with any Lua chunkreader/chunkwriter
-* Support for "invariant" permanent objects, of all datatypes
-* Can invoke metafunctions for custom persistence of tables and userdata
-
-Pluto 2.2 requires Lua 5.1.3. If you need to use Pluto with Lua
-5.0, please use version 1.2 of Pluto.
-
-Starting with version 2.2, Pluto no longer depends on the Lua sources.
-Instead, it subsumes the required headers into its own codebase.
-As a result, it may not work properly with Lua version 5.1.4 or later.
-
-Pluto may have bugs. Users are advised to define lua_assert in
-luaconf.h to something useful when compiling in debug mode, to catch
-assertions by Pluto and Lua.
-
-The Pluto library consists of two public functions.
-
-int pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud)
-
-This function recursively persists the Lua object in stack position 2
-and all other objects which are directly or indirectly referenced by
-it, except those referenced in the permanent object table. The data
-is written using the chunk-writer given, and that writer is passed
-the arbitrary pointer value ud.
-
-The Lua stack must contain exactly and only these two items, in order:
-
-1. A table of permanent objects, that should not be persisted. For each
-permanent object, the object itself should be the key, and a unique
-object of any type should be the value. Likely candidates for this table
-include Lua functions (including those in the Lua libraries) that are
-loaded at load-time. It must include all non-persistable objects that
-are referenced by the object to be persisted. The table is not modified
-by the function. Objects in this table are considered "opaque" and are
-not examined or descended into. Objects should not appear in the table
-multiple times; the result of doing this is undefined (though probably
-harmless). NOTE: If you are planning to persist threads, keep in mind
-that all yielded threads have coroutine.yield on the tops of their
-stacks. Since it's a C function, it should be put here. For complex
-permanents, it may be a good idea to use the __index meta-function of
-the permanents table to "search" for permanents.
-
-2. The single object to be persisted. In many cases, this will be the
-global table. For more flexibility, however, it may be something like a
-table built for the occasion, with various values to keep track of. The
-object may not be nil.
-
-
-int pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud)
-
-This function loads in a Lua object and places it on top of the stack. All
-objects directly or indirectly referenced by it are also loaded.
-
-The Lua stack must contain, as its top value, a table of permanent
-objects. This table should be like the permanent object table used when
-persisting, but with the key and value of each pair reversed. These
-objects are used as substitutes for those referenced in their positions
-when persisting, and under most circumstances should be identical objects
-to those referenced in the permanents table used for persisting. It's
-okay for multiple keys to refer to the same object.
-
-
-RUNNING PLUTO FROM LUA:
-It is also possible to invoke pluto from a Lua script. The C function
-pluto_open() will register pluto.persist and pluto.unpersist, lua functions
-which operate on strings. The first takes a permanents table and a root
-object, and returns a string; the second takes a permanents table and a
-string, and returns the root object.
-
-An error will be raised if pluto.persist is called from a thread which is
-itself referenced by the root object.
-
-SPECIAL PERSISTENCE:
-Tables and userdata have special persistence semantics. These semantics are
-keyed to the value of the object's metatable's __persist member, if any. This
-member may be any of the following four values:
-1. Boolean "true": The table or userdata is persisted literally; tables are
-persisted member-by-member, and userdata are written out as literal data.
-2. Boolean "false": An error is returned, indicating that the object cannot
-be persisted.
-3. A function: This function should take one argument, the object in question,
-and return one result, a closure. This "fixup closure", in turn, will be
-persisted, and during unpersistence will be called. The closure will be
-responsible for recreating the object with the appropriate data, based on
-its upvalues.
-4. Nil, or no metatable. In the case of tables, the table is literally
-persisted. In the case of userdata, an error is returned.
-
-Here's an example of special persistence for a simple 3d vector object:
-
-vec = { x = 2, y = 1, z = 4 }
-setmetatable(vec, { __persist = function(oldtbl)
- local x = oldtbl.x
- local y = oldtbl.y
- local z = oldtbl.z
- local mt = getmetatable(oldtbl)
- return function()
- newtbl = {}
- newtbl.x = x
- newtbl.y = y
- newtbl.z = z
- setmetatable(newtbl, mt)
- return newtbl
- end
-end })
-
-Note how x, y, z, and the mt are explicitly pulled out of the table. It is
-important that the fixup closure returned not reference the original table
-directly, as that table would again be persisted as an upvalue, leading to an
-infinite loop. Also note that the object's metatable is NOT automatically
-persisted; it is necessary for the fixup closure to reset it, if it wants.
-
-LIMITATIONS/TODO:
-* Light userdata are persisted literally, as their pointer values. This
-may or may not be what you want.
-* Closures of C functions may not be persisted. Once it becomes possible
-to specify a C function "proto" as a permanent object, this restriction
-will be relaxed.
-
-BUGS: None known. Emphasis on the 'known'.
diff --git a/engines/sword25/util/pluto/THANKS b/engines/sword25/util/pluto/THANKS
deleted file mode 100644
index 443713fa61..0000000000
--- a/engines/sword25/util/pluto/THANKS
+++ /dev/null
@@ -1,9 +0,0 @@
-Pluto is surprisingly robust and useful. This would not be the case without
-the hard work and helpfulness of the following people, mentioned in no
-particular order:
-
-Ivko Stanilov
-Goran Adrinek
-Eric Jacobs
-Anolan Milanes
-Malte Thiesen
diff --git a/engines/sword25/util/pluto/pdep.cpp b/engines/sword25/util/pluto/pdep.cpp
deleted file mode 100644
index a32c43b42d..0000000000
--- a/engines/sword25/util/pluto/pdep.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* This file is derived from the Lua source code. Please see lua.h for
-the copyright statement.
-*/
-
-#include "pdep/pdep.h"
-
-#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
-
-void pdep_pushobject (lua_State *L, const TValue *o) {
- setobj2s(L, L->top, o);
- api_incr_top(L);
-}
-
-void *pdep_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
- global_State *g = G(L);
- lua_assert((osize == 0) == (block == NULL));
- block = (*g->frealloc)(g->ud, block, osize, nsize);
- lua_assert((nsize == 0) == (block == NULL));
- g->totalbytes = (g->totalbytes - osize) + nsize;
- return block;
-}
-
-void pdep_link (lua_State *L, GCObject *o, lu_byte tt) {
- global_State *g = G(L);
- o->gch.next = g->rootgc;
- g->rootgc = o;
- o->gch.marked = luaC_white(g);
- o->gch.tt = tt;
-}
-
-Proto *pdep_newproto (lua_State *L) {
- Proto *f = pdep_new(L, Proto);
- pdep_link(L, obj2gco(f), LUA_TPROTO);
- f->k = NULL;
- f->sizek = 0;
- f->p = NULL;
- f->sizep = 0;
- f->code = NULL;
- f->sizecode = 0;
- f->sizelineinfo = 0;
- f->sizeupvalues = 0;
- f->nups = 0;
- f->upvalues = NULL;
- f->numparams = 0;
- f->is_vararg = 0;
- f->maxstacksize = 0;
- f->lineinfo = NULL;
- f->sizelocvars = 0;
- f->locvars = NULL;
- f->linedefined = 0;
- f->lastlinedefined = 0;
- f->source = NULL;
- return f;
-}
-
-Closure *pdep_newLclosure (lua_State *L, int nelems, Table *e) {
- Closure *c = cast(Closure *, pdep_malloc(L, sizeLclosure(nelems)));
- pdep_link(L, obj2gco(c), LUA_TFUNCTION);
- c->l.isC = 0;
- c->l.env = e;
- c->l.nupvalues = cast_byte(nelems);
- while (nelems--) c->l.upvals[nelems] = NULL;
- return c;
-}
-
-static void correctstack (lua_State *L, TValue *oldstack) {
- CallInfo *ci;
- GCObject *up;
- L->top = (L->top - oldstack) + L->stack;
- for (up = L->openupval; up != NULL; up = up->gch.next)
- gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
- for (ci = L->base_ci; ci <= L->ci; ci++) {
- ci->top = (ci->top - oldstack) + L->stack;
- ci->base = (ci->base - oldstack) + L->stack;
- ci->func = (ci->func - oldstack) + L->stack;
- }
- L->base = (L->base - oldstack) + L->stack;
-}
-
-
-void pdep_reallocstack (lua_State *L, int newsize) {
- TValue *oldstack = L->stack;
- int realsize = newsize + 1 + EXTRA_STACK;
- lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
- pdep_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
- L->stacksize = realsize;
- L->stack_last = L->stack+newsize;
- correctstack(L, oldstack);
-}
-
-void pdep_growstack (lua_State *L, int n) {
- if (n <= L->stacksize) /* double size is enough? */
- pdep_reallocstack(L, 2*L->stacksize);
- else
- pdep_reallocstack(L, L->stacksize + n);
-}
-
-void pdep_reallocCI (lua_State *L, int newsize) {
- CallInfo *oldci = L->base_ci;
- pdep_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
- L->size_ci = newsize;
- L->ci = (L->ci - oldci) + L->base_ci;
- L->end_ci = L->base_ci + L->size_ci - 1;
-}
-
-TString *pdep_newlstr (lua_State *L, const char *str, size_t l) {
- TString *res;
- lua_pushlstring(L, str, l);
- res = rawtsvalue(L->top-1);
- lua_pop(L, 1);
- return res;
-}
diff --git a/engines/sword25/util/pluto/pdep/README b/engines/sword25/util/pluto/pdep/README
deleted file mode 100644
index 3592754da0..0000000000
--- a/engines/sword25/util/pluto/pdep/README
+++ /dev/null
@@ -1,5 +0,0 @@
-These files are directly copied from the Lua distribution, with the
-exception of lzio.h, which is s/lua{ZM}/pdep/g and has an include removed.
-
-As such, unlike the rest of Pluto, they are released under the
-same terms as Lua. See "lua.h" for the copyright notice.
diff --git a/engines/sword25/util/pluto/pdep/lzio.h b/engines/sword25/util/pluto/pdep/lzio.h
deleted file mode 100644
index 2e37f8d202..0000000000
--- a/engines/sword25/util/pluto/pdep/lzio.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-** $Id$
-** Buffered streams
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lzio_h
-#define lzio_h
-
-#include "sword25/util/lua/lua.h"
-
-
-#define EOZ (-1) /* end of stream */
-
-typedef struct Zio ZIO;
-
-#define char2int(c) cast(int, cast(unsigned char, (c)))
-
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : pdep_fill(z))
-
-typedef struct Mbuffer {
- char *buffer;
- size_t n;
- size_t buffsize;
-} Mbuffer;
-
-#define pdep_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
-
-#define pdep_buffer(buff) ((buff)->buffer)
-#define pdep_sizebuffer(buff) ((buff)->buffsize)
-#define pdep_bufflen(buff) ((buff)->n)
-
-#define pdep_resetbuffer(buff) ((buff)->n = 0)
-
-
-#define pdep_resizebuffer(L, buff, size) \
- (pdep_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
- (buff)->buffsize = size)
-
-#define pdep_freebuffer(L, buff) pdep_resizebuffer(L, buff, 0)
-
-
-LUAI_FUNC char *pdep_openspace (lua_State *L, Mbuffer *buff, size_t n);
-LUAI_FUNC void pdep_init (lua_State *L, ZIO *z, lua_Reader reader,
- void *data);
-LUAI_FUNC size_t pdep_read (ZIO* z, void* b, size_t n); /* read next n bytes */
-LUAI_FUNC int pdep_lookahead (ZIO *z);
-
-
-
-/* --------- Private Part ------------------ */
-
-struct Zio {
- size_t n; /* bytes still unread */
- const char *p; /* current position in buffer */
- lua_Reader reader;
- void* data; /* additional data */
- lua_State *L; /* Lua state (for reader) */
-};
-
-
-LUAI_FUNC int pdep_fill (ZIO *z);
-
-#endif
diff --git a/engines/sword25/util/pluto/pdep/pdep.h b/engines/sword25/util/pluto/pdep/pdep.h
deleted file mode 100644
index 664fc812b5..0000000000
--- a/engines/sword25/util/pluto/pdep/pdep.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef PDEP_H
-#define PDEP_H
-
-#include "sword25/util/lua/lua.h"
-#include "sword25/util/pluto/pdep/lzio.h"
-#include "sword25/util/lua/ldo.h"
-#include "sword25/util/lua/lfunc.h"
-#include "sword25/util/lua/lgc.h"
-#include "sword25/util/lua/llimits.h"
-#include "sword25/util/lua/lobject.h"
-#include "sword25/util/lua/lopcodes.h"
-#include "sword25/util/lua/lstate.h"
-#include "sword25/util/lua/lstring.h"
-#include "sword25/util/lua/lauxlib.h"
-
-
-#define pdep_reallocv(L,b,on,n,e) \
- pdep_realloc_(L, (b), (on)*(e), (n)*(e))
-#define pdep_reallocvector(L, v,oldn,n,t) \
- ((v)=cast(t *, pdep_reallocv(L, v, oldn, n, sizeof(t))))
-#define pdep_freearray(L, b, n, t) pdep_reallocv(L, (b), n, 0, sizeof(t))
-#define pdep_newvector(L,n,t) \
- cast(t *, pdep_reallocv(L, NULL, 0, n, sizeof(t)))
-#define pdep_new(L,t) cast(t *, pdep_malloc(L, sizeof(t)))
-#define pdep_malloc(L,t) pdep_realloc_(L, NULL, 0, (t))
-#define pdep_checkstack(L,n) \
- if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
- pdep_growstack(L, n); \
- else pdep_reallocstack(L, L->stacksize - EXTRA_STACK - 1);
-
-
-void pdep_pushobject (lua_State *L, const TValue *o);
-void *pdep_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize);
-void pdep_link (lua_State *L, GCObject *o, lu_byte tt);
-Proto *pdep_newproto (lua_State *L);
-Closure *pdep_newLclosure (lua_State *L, int nelems, Table *e);
-void pdep_reallocstack (lua_State *L, int newsize);
-void pdep_growstack (lua_State *L, int n);
-void pdep_reallocCI (lua_State *L, int newsize);
-TString *pdep_newlstr (lua_State *L, const char *str, size_t l);
-
-#endif
diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp
deleted file mode 100644
index cbe16b0d5b..0000000000
--- a/engines/sword25/util/pluto/pluto.cpp
+++ /dev/null
@@ -1,2083 +0,0 @@
-/* $Id$ */
-
-/* Tamed Pluto - Heavy-duty persistence for Lua
- * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
- * domain. People making use of this software as part of an application
- * are politely requested to email the author at sneftel@gmail.com
- * with a brief description of the application, primarily to satisfy his
- * curiosity.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Instrumented by Stefan Reich (info@luaos.net)
- * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
- */
-
-#include "sword25/util/lua/lua.h"
-#include "pluto.h"
-
-#undef TOTEXT
-
-#define USE_PDEP
-
-#ifdef USE_PDEP
-#include "pdep/pdep.h"
-#define LIF(prefix, name) pdep ## _ ## name
-#else
-#include "lapi.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "llimits.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "lauxlib.h"
-#define LIF(prefix, name) lua ## prefix ## _ ## name
-#endif
-
-#include
-
-
-/* Define this if you want size_t values to be written in 64-bit
- (even on 32-bit systems). Should eliminate at least one source of
- 32/64 bit incompatibility. */
-#define SIZES64
-
-
-/* #define PLUTO_DEBUG */
-
-
-#ifdef SIZES64
-#define VERSION "Tamed Pluto 1.0 with SIZES64 flag"
-#else
-#define VERSION "Tamed Pluto 1.0"
-#endif
-
-
-#ifdef PLUTO_DEBUG
-#include
-#endif
-
-#define PLUTO_TPERMANENT 101
-
-#define verify(x) { int v = (int)((x)); v=v; lua_assert(v); }
-
-#define NUMTYPES 9
-static const char* typenames[] = {
- "nil",
- "boolean",
- "lightuserdata",
- "number",
- "string",
- "table",
- "function",
- "userdata",
- "thread"
-};
-
-static int humanReadable = 0;
-#define hrBufSize 200
-static char hrBuf[hrBufSize];
-
-typedef struct PersistInfo_t {
- lua_State *L;
- int counter;
- lua_Chunkwriter writer;
- void *ud;
-#ifdef PLUTO_DEBUG
- int level;
-#endif
-} PersistInfo;
-
-#ifdef PLUTO_DEBUG
-void printindent(int indent)
-{
- int il;
- for(il=0; ilwriter(pi->L, hrBuf, strlen(hrBuf), ud);
- for (i = 0; i < size; i++) {
- char b = ((char *)p)[i];
- snprintf(hrBuf, hrBufSize, "%X%X", (b >> 4) & 0xF, b & 0xF);
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- }
- snprintf(hrBuf, hrBufSize, "\n");
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- } else {
- pi->writer(pi->L, p, size, ud);
- }
-#ifdef TOTEXT
- int i;
- printf(" pi_write %d ", (int) size);
- for (i = 0; i < size; i++) {
- char b = ((char *)p)[i];
- printf("%X%X", (b >> 4) & 0xF, b & 0xF);
- }
- printf("\n");
-#endif
-}
-
-static void hrOut(PersistInfo *pi) {
- pi->writer(pi->L, hrBuf, strlen(hrBuf), pi->ud);
-}
-
-static void write_size(PersistInfo *pi, size_t *val)
-{
-#ifdef SIZES64
- int64 longval; /* yeah, you really need long long to get 8 bytes on win32... duh. */
- longval = *val;
- pi_write(pi, &longval, 8, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "write_size64 %ld\n", longval);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("write_size64 %ld\n", longval);
-#endif
-#else
- pi_write(pi, val, sizeof(size_t), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "write_size %ld\n", *((size_t *)val));
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("write_size %ld\n", *val);
-#endif
-#endif
-}
-
-static void read_size(ZIO *zio, size_t *val)
-{
-#ifdef SIZES64
- int64 longval;
- verify(LIF(Z,read)(zio, &longval, 8) == 0);
- *val = longval;
-#else
- verify(LIF(Z,read)(zio, val, sizeof(size_t)) == 0);
-#endif
-}
-
-
-/* Mutual recursion requires prototype */
-static void persist(PersistInfo *pi);
-
-/* A simple reimplementation of the unfortunately static function luaA_index.
- * Does not support the global table, registry, or upvalues. */
-static StkId getobject(lua_State *L, int stackpos)
-{
- if(stackpos > 0) {
- lua_assert(L->base+stackpos-1 < L->top);
- return L->base+stackpos-1;
- } else {
- lua_assert(L->top-stackpos >= L->base);
- return L->top+stackpos;
- }
-}
-
-/* Choose whether to do a regular or special persistence based on an object's
- * metatable. "default" is whether the object, if it doesn't have a __persist
- * entry, is literally persistable or not.
- * Pushes the unpersist closure and returns true if special persistence is
- * used. */
-static int persistspecialobject(PersistInfo *pi, int defaction)
-{
- /* perms reftbl ... obj */
- lua_checkstack(pi->L, 4);
- /* Check whether we should persist literally, or via the __persist
- * metafunction */
- if(!lua_getmetatable(pi->L, -1)) {
- if(defaction) {
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Type not literally persistable by default");
- lua_error(pi->L);
- }
- }
- /* perms reftbl sptbl ... obj mt */
- lua_pushstring(pi->L, "__persist");
- /* perms reftbl sptbl ... obj mt "__persist" */
- lua_rawget(pi->L, -2);
- /* perms reftbl sptbl ... obj mt __persist? */
- if(lua_isnil(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt nil */
- lua_pop(pi->L, 2);
- /* perms reftbl sptbl ... obj */
- if(defaction) {
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero2\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero2\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Type not literally persistable by default");
- lua_error(pi->L);
- return 0; /* not reached */
- }
- } else if(lua_isboolean(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt bool */
- if(lua_toboolean(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt true */
- lua_pop(pi->L, 2);
- /* perms reftbl sptbl ... obj */
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero3\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero3\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Metatable forbade persistence");
- lua_error(pi->L);
- return 0; /* not reached */
- }
- } else if(!lua_isfunction(pi->L, -1)) {
- lua_pushstring(pi->L, "__persist not nil, boolean, or function");
- lua_error(pi->L);
- }
- /* perms reftbl ... obj mt __persist */
- lua_pushvalue(pi->L, -3);
- /* perms reftbl ... obj mt __persist obj */
-#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
- lua_pushlightuserdata(pi->L, (void *)pi->writer);
- lua_pushlightuserdata(pi->L, pi->ud);
- /* perms reftbl ... obj mt __persist obj ud */
- lua_call(pi->L, 3, 1);
- /* perms reftbl ... obj mt func? */
-#else
- lua_call(pi->L, 1, 1);
- /* perms reftbl ... obj mt func? */
-#endif
- /* perms reftbl ... obj mt func? */
- if(!lua_isfunction(pi->L, -1)) {
- lua_pushstring(pi->L, "__persist function did not return a function");
- lua_error(pi->L);
- }
- /* perms reftbl ... obj mt func */
- {
- int one = 1;
- pi_write(pi, &one, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_one\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_one\n");
-#endif
- }
- persist(pi);
- /* perms reftbl ... obj mt func */
- lua_pop(pi->L, 2);
- /* perms reftbl ... obj */
- return 1;
-}
-
-static void persisttable(PersistInfo *pi)
-{
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persisttable\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persisttable\n");
-#endif
-
- /* perms reftbl ... tbl */
- lua_checkstack(pi->L, 3);
- if(persistspecialobject(pi, 1)) {
- /* perms reftbl ... tbl */
- return;
- }
- /* perms reftbl ... tbl */
- /* First, persist the metatable (if any) */
- if(!lua_getmetatable(pi->L, -1)) {
- lua_pushnil(pi->L);
- }
- /* perms reftbl ... tbl mt/nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl */
-
- /* Now, persist all k/v pairs */
- lua_pushnil(pi->L);
- /* perms reftbl ... tbl nil */
- while(lua_next(pi->L, -2)) {
- /* perms reftbl ... tbl k v */
- lua_pushvalue(pi->L, -2);
- /* perms reftbl ... tbl k v k */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl k v */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl k */
- }
- /* perms reftbl ... tbl */
- /* Terminate list */
- lua_pushnil(pi->L);
- /* perms reftbl ... tbl nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl */
-}
-
-static void persistuserdata(PersistInfo *pi) {
- /* perms reftbl ... udata */
- lua_checkstack(pi->L, 2);
- if(persistspecialobject(pi, 0)) {
- /* perms reftbl ... udata */
- return;
- } else {
- /* Use literal persistence */
- size_t length = uvalue(getobject(pi->L, -1))->len;
- write_size(pi, &length);
- pi_write(pi, lua_touserdata(pi->L, -1), length, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistuserdata %ld\n", (long) length);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistuserdata %ld\n", (long) length);
-#endif
- if(!lua_getmetatable(pi->L, -1)) {
- /* perms reftbl ... udata */
- lua_pushnil(pi->L);
- /* perms reftbl ... udata mt/nil */
- }
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... udata */
- }
-}
-
-
-static Proto *toproto(lua_State *L, int stackpos)
-{
- return gco2p(getobject(L, stackpos)->value.gc);
-}
-
-static UpVal *toupval(lua_State *L, int stackpos)
-{
- lua_assert(ttype(getobject(L, stackpos)) == LUA_TUPVAL);
- return gco2uv(getobject(L, stackpos)->value.gc);
-}
-
-static void pushproto(lua_State *L, Proto *proto)
-{
- TValue o;
- setptvalue(L, &o, proto);
- LIF(A,pushobject)(L, &o);
-}
-
-#define setuvvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUPVAL; \
- checkliveness(G(L),i_o); }
-
-static void pushupval(lua_State *L, UpVal *upval)
-{
- TValue o;
- setuvvalue(L, &o, upval);
- LIF(A,pushobject)(L, &o);
-}
-
-static void pushclosure(lua_State *L, Closure *closure)
-{
- TValue o;
- setclvalue(L, &o, closure);
- LIF(A,pushobject)(L, &o);
-}
-
-static void pushstring(lua_State *L, TString *s)
-{
- TValue o;
- setsvalue(L, &o, s);
- LIF(A,pushobject)(L, &o);
-}
-
-static void persistfunction(PersistInfo *pi)
-{
- /* perms reftbl ... func */
- Closure *cl = clvalue(getobject(pi->L, -1));
- lua_checkstack(pi->L, 2);
- if(cl->c.isC) {
- /* It's a C function. For now, we aren't going to allow
- * persistence of C closures, even if the "C proto" is
- * already in the permanents table. */
- lua_pushstring(pi->L, "Attempt to persist a C function");
- lua_error(pi->L);
- } else {
- /* It's a Lua closure. */
- {
- /* We don't really _NEED_ the number of upvals,
- * but it'll simplify things a bit */
- pi_write(pi, &cl->l.p->nups, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
-#endif
- }
- /* Persist prototype */
- {
- pushproto(pi->L, cl->l.p);
- /* perms reftbl ... func proto */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- /* Persist upvalue values (not the upvalue objects
- * themselves) */
- {
- int i;
- for(i=0; il.p->nups; i++) {
- /* perms reftbl ... func */
- pushupval(pi->L, cl->l.upvals[i]);
- /* perms reftbl ... func upval */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
- }
- /* Persist function environment */
- {
- lua_getfenv(pi->L, -1);
- /* perms reftbl ... func fenv */
- if(lua_equal(pi->L, -1, LUA_GLOBALSINDEX)) {
- /* Function has the default fenv */
- /* perms reftbl ... func _G */
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- lua_pushnil(pi->L);
- /* perms reftbl ... func nil */
- }
- /* perms reftbl ... func fenv/nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- }
-}
-
-
-/* Upvalues are tricky. Here's why.
- *
- * A particular upvalue may be either "open", in which case its member v
- * points into a thread's stack, or "closed" in which case it points to the
- * upvalue itself. An upvalue is closed under any of the following conditions:
- * -- The function that initially declared the variable "local" returns
- * -- The thread in which the closure was created is garbage collected
- *
- * To make things wackier, just because a thread is reachable by Lua doesn't
- * mean it's in our root set. We need to be able to treat an open upvalue
- * from an unreachable thread as a closed upvalue.
- *
- * The solution:
- * (a) For the purposes of persisting, don't indicate whether an upvalue is
- * closed or not.
- * (b) When unpersisting, pretend that all upvalues are closed.
- * (c) When persisting, persist all open upvalues referenced by a thread
- * that is persisted, and tag each one with the corresponding stack position
- * (d) When unpersisting, "reopen" each of these upvalues as the thread is
- * unpersisted
- */
-static void persistupval(PersistInfo *pi)
-{
- /* perms reftbl ... upval */
- UpVal *uv = toupval(pi->L, -1);
- lua_checkstack(pi->L, 1);
-
- /* We can't permit the upval to linger around on the stack, as Lua
- * will bail if its GC finds it. */
-
- lua_pop(pi->L, 1);
- /* perms reftbl ... */
- LIF(A,pushobject)(pi->L, uv->v);
- /* perms reftbl ... obj */
- persist(pi);
- /* perms reftbl ... obj */
-}
-
-static void persistproto(PersistInfo *pi)
-{
- /* perms reftbl ... proto */
- Proto *p = toproto(pi->L, -1);
- lua_checkstack(pi->L, 2);
-
- /* Persist constant refs */
- {
- int i;
- pi_write(pi, &p->sizek, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizek %d\n", p->sizek);
- hrOut(pi);
- }
- #ifdef TOTEXT
- printf("persistproto_sizek %d\n", p->sizek);
- #endif
- for(i=0; isizek; i++) {
- LIF(A,pushobject)(pi->L, &p->k[i]);
- /* perms reftbl ... proto const */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... proto */
- }
- }
- /* perms reftbl ... proto */
-
- /* serialize inner Proto refs */
- {
- int i;
- pi_write(pi, &p->sizep, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizep %d\n", p->sizep);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizep %d\n", p->sizep);
-#endif
- for(i=0; isizep; i++)
- {
- pushproto(pi->L, p->p[i]);
- /* perms reftbl ... proto subproto */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... proto */
- }
- }
- /* perms reftbl ... proto */
-
- /* Serialize code */
- {
- int len;
- pi_write(pi, &p->sizecode, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizecode %d\n", p->sizecode);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizecode %d\n", p->sizecode);
-#endif
- len = sizeof(Instruction) * p->sizecode;
- pi_write(pi, p->code, len, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_code %d\n", len);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_code %d\n", len);
-#endif
- }
-
- /* Serialize upvalue names */
- {
- int i;
- pi_write(pi, &p->sizeupvalues, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_upvalues %d\n", p->sizeupvalues);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_upvalues %d\n", p->sizeupvalues);
-#endif
- for(i=0; isizeupvalues; i++)
- {
- pushstring(pi->L, p->upvalues[i]);
- persist(pi);
- lua_pop(pi->L, 1);
- }
- }
- /* Serialize local variable infos */
- {
- int i;
- pi_write(pi, &p->sizelocvars, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizelocvars %d\n", p->sizelocvars);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizelocvars %d\n", p->sizelocvars);
-#endif
- for(i=0; isizelocvars; i++)
- {
- pushstring(pi->L, p->locvars[i].varname);
- persist(pi);
- lua_pop(pi->L, 1);
-
- pi_write(pi, &p->locvars[i].startpc, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_startpc %d\n", p->locvars[i].startpc);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_startpc %d\n", p->locvars[i].startpc);
-#endif
- pi_write(pi, &p->locvars[i].endpc, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_endpc %d\n", p->locvars[i].endpc);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_endpc %d\n", p->locvars[i].endpc);
-#endif
- }
- }
-
- /* Serialize source string */
- pushstring(pi->L, p->source);
- persist(pi);
- lua_pop(pi->L, 1);
-
- /* Serialize line numbers */
- {
- pi_write(pi, &p->sizelineinfo, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizelineinfo %d\n", p->sizelineinfo);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizelineinfo %d\n", p->sizelineinfo);
-#endif
- if (p->sizelineinfo)
- {
- int len;
- len = sizeof(int) * p->sizelineinfo;
- pi_write(pi, p->lineinfo, len, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_lineinfo %d\n", len);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_lineinfo %d\n", len);
-#endif
- }
- }
-
- /* Serialize linedefined and lastlinedefined */
- pi_write(pi, &p->linedefined, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_linedefined %d\n", p->linedefined);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_linedefined %d\n", p->linedefined);
-#endif
- pi_write(pi, &p->lastlinedefined, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_lastlinedefined %d\n", p->lastlinedefined);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_lastlinedefined %d\n", p->lastlinedefined);
-#endif
-
- /* Serialize misc values */
- {
- pi_write(pi, &p->nups, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_nups %d\n", (int) p->nups);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_nups %d\n", (int) p->nups);
-#endif
- pi_write(pi, &p->numparams, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_numparams %d\n", (int) p->numparams);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_numparams %d\n", (int) p->numparams);
-#endif
- pi_write(pi, &p->is_vararg, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_is_vararg %d\n", (int) p->is_vararg);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_is_vararg %d\n", (int) p->is_vararg);
-#endif
- pi_write(pi, &p->maxstacksize, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_maxstacksize %d\n", (int) p->maxstacksize);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_maxstacksize %d\n", (int) p->maxstacksize);
-#endif
- }
- /* We do not currently persist upvalue names, local variable names,
- * variable lifetimes, line info, or source code. */
-}
-
-/* Copies a stack, but the stack is reversed in the process
- */
-static size_t revappendstack(lua_State *from, lua_State *to)
-{
- StkId o;
- for(o=from->top-1; o>=from->stack; o--) {
- setobj2s(to, to->top, o);
- to->top++;
- }
- return from->top - from->stack;
-}
-
-/* Persist all stack members
- */
-static void persistthread(PersistInfo *pi)
-{
- size_t posremaining;
- lua_State *L2;
- /* perms reftbl ... thr */
- L2 = lua_tothread(pi->L, -1);
- lua_checkstack(pi->L, L2->top - L2->stack + 1);
- if(pi->L == L2) {
- lua_pushstring(pi->L, "Can't persist currently running thread");
- lua_error(pi->L);
- return; /* not reached */
- }
-
- /* Persist the stack */
- posremaining = revappendstack(L2, pi->L);
- /* perms reftbl ... thr (rev'ed contents of L2) */
- write_size(pi, &posremaining);
- for(; posremaining > 0; posremaining--) {
- persist(pi);
- lua_pop(pi->L, 1);
- }
- /* perms reftbl ... thr */
- /* Now, persist the CallInfo stack. */
- {
- size_t i, numframes = (L2->ci - L2->base_ci) + 1;
- write_size(pi, &numframes);
- for(i=0; ibase_ci + i;
- size_t stackbase = ci->base - L2->stack;
- size_t stackfunc = ci->func - L2->stack;
- size_t stacktop = ci->top - L2->stack;
- size_t savedpc = (ci != L2->base_ci) ?
- ci->savedpc - ci_func(ci)->l.p->code :
- 0;
- write_size(pi, &stackbase);
- write_size(pi, &stackfunc);
- write_size(pi, &stacktop);
- pi_write(pi, &ci->nresults, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistthread %d\n", ci->nresults);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistthread %d\n", ci->nresults);
-#endif
- write_size(pi, &savedpc);
- }
- }
-
- /* Serialize the state's other parameters, with the exception of upval stuff */
- {
- size_t stackbase = L2->base - L2->stack;
- size_t stacktop = L2->top - L2->stack;
- lua_assert(L2->nCcalls <= 1);
- pi_write(pi, &L2->status, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistthread_status %d\n", (int) L2->status);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistthread_status %d\n", (int) L2->status);
-#endif
- write_size(pi, &stackbase);
- write_size(pi, &stacktop);
-
- // ptrdiff_t changes sizes based on 32/64 bit
- // Hard cast to 64 bit size if SIZE64 is defined
-#ifdef SIZES64
- uint64 ptrIndex = static_cast(L2->errfunc);
- pi_write(pi, &ptrIndex, sizeof(uint64), pi->ud);
-#else
- pi_write(pi, &L2->errfunc, sizeof(ptrdiff_t), pi->ud);
-#endif
- //write_size(pi, (size_t *)&L2->errfunc);
- }
-
- /* Finally, record upvalues which need to be reopened */
- /* See the comment above persistupval() for why we do this */
- {
- GCObject *gco;
- UpVal *uv;
- /* perms reftbl ... thr */
- for(gco = L2->openupval; gco != NULL; gco = uv->next) {
- size_t stackpos;
- uv = gco2uv(gco);
-
- /* Make sure upvalue is really open */
- lua_assert(uv->v != &uv->u.value);
- pushupval(pi->L, uv);
- /* perms reftbl ... thr uv */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... thr */
- stackpos = uv->v - L2->stack;
- write_size(pi, &stackpos);
- }
- /* perms reftbl ... thr */
- lua_pushnil(pi->L);
- /* perms reftbl ... thr nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... thr */
- }
- /* perms reftbl ... thr */
-}
-
-static void persistboolean(PersistInfo *pi)
-{
- int b = lua_toboolean(pi->L, -1);
- pi_write(pi, &b, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistboolean %d\n", b);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistboolean %d\n", b);
-#endif
-}
-
-static void persistlightuserdata(PersistInfo *pi)
-{
- void *p = lua_touserdata(pi->L, -1);
- pi_write(pi, &p, sizeof(void *), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistlightuserdata %p\n", p);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistlightuserdata %d\n", (int) p);
-#endif
-}
-
-static void persistnumber(PersistInfo *pi)
-{
- lua_Number n = lua_tonumber(pi->L, -1);
- pi_write(pi, &n, sizeof(lua_Number), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
-#endif
-}
-
-static void persiststring(PersistInfo *pi)
-{
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persiststring\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persiststring\n");
-#endif
- size_t length = lua_strlen(pi->L, -1);
- write_size(pi, &length);
- const char* s = lua_tostring(pi->L, -1);
- pi_write(pi, s, length, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persiststring %d \"%s\"\n", (int)length, s);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persiststring %d \"%s\"\n", length, s);
-#endif
-}
-
-/* Top-level delegating persist function
- */
-static void persist(PersistInfo *pi)
-{
- /* perms reftbl ... obj */
- lua_checkstack(pi->L, 2);
- /* If the object has already been written, write a reference to it */
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- lua_rawget(pi->L, 2);
- /* perms reftbl ... obj ref? */
- if(!lua_isnil(pi->L, -1)) {
- /* perms reftbl ... obj ref */
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_seenobject\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_seenobject\n");
-#endif
- int *ref = (int *)lua_touserdata(pi->L, -1);
- pi_write(pi, ref, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_touserdata_ref %d\n", ref);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_touserdata_ref %d\n", ref);
-#endif
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj ref */
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("0 %d\n", ref);
-#endif
- return;
- }
- /* perms reftbl ... obj nil */
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
- /* If the object is nil, write the pseudoreference 0 */
- if(lua_isnil(pi->L, -1)) {
- int zero = 0;
- /* firsttime */
- pi_write(pi, &zero, sizeof(int), pi->ud);
- /* ref */
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_nil (last 2 lines)\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_nil (last 2 lines)\n");
-#endif
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("0 0\n");
-#endif
- return;
- }
- {
- /* indicate that it's the first time */
- int one = 1;
- pi_write(pi, &one, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_newobject\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_newobject\n");
-#endif
- }
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- int *ref = (int *)lua_newuserdata(pi->L, sizeof(int));
- *ref = ++(pi->counter);
- /* perms reftbl ... obj obj ref */
- lua_rawset(pi->L, 2);
- /* perms reftbl ... obj */
-
- pi_write(pi, &pi->counter, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_counter %d\n", pi->counter);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_counter %d\n", pi->counter);
-#endif
-
-
- /* At this point, we'll give the permanents table a chance to play. */
- {
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- lua_gettable(pi->L, 1);
- /* perms reftbl ... obj permkey? */
- if(!lua_isnil(pi->L, -1)) {
- /* perms reftbl ... obj permkey */
- int type = PLUTO_TPERMANENT;
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("1 %d PERM\n", pi->counter);
- pi->level++;
-#endif
- pi_write(pi, &type, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_permtype %d\n", type);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_permtype %d\n", type);
-#endif
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
-#ifdef PLUTO_DEBUG
- pi->level--;
-#endif
- return;
- } else {
- /* perms reftbl ... obj nil */
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
- }
- /* perms reftbl ... obj */
- }
- {
- int type = lua_type(pi->L, -1);
- pi_write(pi, &type, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
-#endif
-
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("1 %d %d\n", pi->counter, type);
- pi->level++;
-#endif
- }
-
- switch(lua_type(pi->L, -1)) {
- case LUA_TBOOLEAN:
- persistboolean(pi);
- break;
- case LUA_TLIGHTUSERDATA:
- persistlightuserdata(pi);
- break;
- case LUA_TNUMBER:
- persistnumber(pi);
- break;
- case LUA_TSTRING:
- persiststring(pi);
- break;
- case LUA_TTABLE:
- persisttable(pi);
- break;
- case LUA_TFUNCTION:
- persistfunction(pi);
- break;
- case LUA_TTHREAD:
- persistthread(pi);
- break;
- case LUA_TPROTO:
- persistproto(pi);
- break;
- case LUA_TUPVAL:
- persistupval(pi);
- break;
- case LUA_TUSERDATA:
- persistuserdata(pi);
- break;
- default:
- lua_assert(0);
- }
-#ifdef PLUTO_DEBUG
- pi->level--;
-#endif
-}
-
-void pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud)
-{
- PersistInfo pi;
-
- pi.counter = 0;
- pi.L = L;
- pi.writer = writer;
- pi.ud = ud;
-#ifdef PLUTO_DEBUG
- pi.level = 0;
-#endif
-
- lua_checkstack(L, 4);
- /* perms? rootobj? ...? */
- lua_assert(lua_gettop(L) == 2);
- /* perms rootobj */
- lua_assert(!lua_isnil(L, 2));
- /* perms rootobj */
- lua_newtable(L);
- /* perms rootobj reftbl */
-
- /* Now we're going to make the table weakly keyed. This prevents the
- * GC from visiting it and trying to mark things it doesn't want to
- * mark in tables, e.g. upvalues. All objects in the table are
- * a priori reachable, so it doesn't matter that we do this. */
- lua_newtable(L);
- /* perms rootobj reftbl mt */
- lua_pushstring(L, "__mode");
- /* perms rootobj reftbl mt "__mode" */
- lua_pushstring(L, "k");
- /* perms rootobj reftbl mt "__mode" "k" */
- lua_settable(L, 4);
- /* perms rootobj reftbl mt */
- lua_setmetatable(L, 3);
- /* perms rootobj reftbl */
- lua_insert(L, 2);
- /* perms reftbl rootobj */
- persist(&pi);
- /* perms reftbl rootobj */
- lua_remove(L, 2);
- /* perms rootobj */
-}
-
-typedef struct WriterInfo_t {
- char* buf;
- size_t buflen;
-} WriterInfo;
-
-static int bufwriter (lua_State *L, const void *p, size_t sz, void *ud) {
- const char *cp = (const char *)p;
- WriterInfo *wi = (WriterInfo *)ud;
-
- LIF(M,reallocvector)(L, wi->buf, wi->buflen, wi->buflen+sz, char);
- while(sz)
- {
- /* how dearly I love ugly C pointer twiddling */
- wi->buf[wi->buflen++] = *cp++;
- sz--;
- }
- return 0;
-}
-
-int persist_l(lua_State *L)
-{
- /* perms? rootobj? ...? */
- WriterInfo wi;
-
- wi.buf = NULL;
- wi.buflen = 0;
-
- lua_settop(L, 2);
- /* perms? rootobj? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms rootobj? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms rootobj */
-
- pluto_persist(L, bufwriter, &wi);
-
- lua_settop(L, 0);
- /* (empty) */
- lua_pushlstring(L, wi.buf, wi.buflen);
- /* str */
- pdep_freearray(L, wi.buf, wi.buflen, char);
- return 1;
-}
-
-typedef struct UnpersistInfo_t {
- lua_State *L;
- ZIO zio;
-#ifdef PLUTO_DEBUG
- int level;
-#endif
-} UnpersistInfo;
-
-static void unpersist(UnpersistInfo *upi);
-
-/* The object is left on the stack. This is primarily used by unpersist, but
- * may be used by GCed objects that may incur cycles in order to preregister
- * the object. */
-static void registerobject(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... obj */
- lua_checkstack(upi->L, 2);
- lua_pushlightuserdata(upi->L, (void *)ref);
- /* perms reftbl ... obj ref */
- lua_pushvalue(upi->L, -2);
- /* perms reftbl ... obj ref obj */
- lua_settable(upi->L, 2);
- /* perms reftbl ... obj */
-}
-
-static void unpersistboolean(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int b;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &b, sizeof(int)) == 0);
- lua_pushboolean(upi->L, b);
- /* perms reftbl ... bool */
-}
-
-static void unpersistlightuserdata(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- void *p;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &p, sizeof(void *)) == 0);
- lua_pushlightuserdata(upi->L, p);
- /* perms reftbl ... ludata */
-}
-
-static void unpersistnumber(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_Number n;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &n, sizeof(lua_Number)) == 0);
- lua_pushnumber(upi->L, n);
- /* perms reftbl ... num */
-}
-
-static void unpersiststring(UnpersistInfo *upi)
-{
- /* perms reftbl sptbl ref */
- /*int length;*/
- size_t length;
- char* string;
- lua_checkstack(upi->L, 1);
- /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(int)) == 0);*/
- /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);*/
- read_size(&upi->zio, &length);
- string = pdep_newvector(upi->L, length, char);
- verify(LIF(Z,read)(&upi->zio, string, length) == 0);
- lua_pushlstring(upi->L, string, length);
- /* perms reftbl sptbl ref str */
- pdep_freearray(upi->L, string, length, char);
-}
-
-static void unpersistspecialtable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 1);
- unpersist(upi);
- /* perms reftbl ... spfunc? */
- lua_assert(lua_isfunction(upi->L, -1));
- /* perms reftbl ... spfunc */
- lua_call(upi->L, 0, 1);
- /* perms reftbl ... tbl? */
- lua_assert(lua_istable(upi->L, -1));
- /* perms reftbl ... tbl */
-}
-
-static void unpersistliteraltable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 3);
- /* Preregister table for handling of cycles */
- lua_newtable(upi->L);
- /* perms reftbl ... tbl */
- registerobject(ref, upi);
- /* perms reftbl ... tbl */
- /* Unpersist metatable */
- {
- unpersist(upi);
- /* perms reftbl ... tbl mt/nil? */
- if(lua_istable(upi->L, -1)) {
- /* perms reftbl ... tbl mt */
- lua_setmetatable(upi->L, -2);
- /* perms reftbl ... tbl */
- } else {
- /* perms reftbl ... tbl nil? */
- lua_assert(lua_isnil(upi->L, -1));
- /* perms reftbl ... tbl nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... tbl */
- }
- /* perms reftbl ... tbl */
- }
-
- while(1)
- {
- /* perms reftbl ... tbl */
- unpersist(upi);
- /* perms reftbl ... tbl key/nil */
- if(lua_isnil(upi->L, -1)) {
- /* perms reftbl ... tbl nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... tbl */
- break;
- }
- /* perms reftbl ... tbl key */
- unpersist(upi);
- /* perms reftbl ... tbl key value? */
- lua_assert(!lua_isnil(upi->L, -1));
- /* perms reftbl ... tbl key value */
- lua_rawset(upi->L, -3);
- /* perms reftbl ... tbl */
- }
-}
-
-static void unpersisttable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 1);
- {
- int isspecial;
- verify(LIF(Z,read)(&upi->zio, &isspecial, sizeof(int)) == 0);
- if(isspecial) {
- unpersistspecialtable(ref, upi);
- /* perms reftbl ... tbl */
- } else {
- unpersistliteraltable(ref, upi);
- /* perms reftbl ... tbl */
- }
- /* perms reftbl ... tbl */
- }
-}
-
-static UpVal *makeupval(lua_State *L, int stackpos)
-{
- UpVal *uv = pdep_new(L, UpVal);
- pdep_link(L, (GCObject *)uv, LUA_TUPVAL);
- uv->tt = LUA_TUPVAL;
- uv->v = &uv->u.value;
- uv->u.l.prev = NULL;
- uv->u.l.next = NULL;
- setobj(L, uv->v, getobject(L, stackpos));
- return uv;
-}
-
-static Proto *makefakeproto(lua_State *L, lu_byte nups)
-{
- Proto *p = pdep_newproto(L);
- p->sizelineinfo = 1;
- p->lineinfo = pdep_newvector(L, 1, int);
- p->lineinfo[0] = 1;
- p->sizecode = 1;
- p->code = pdep_newvector(L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->source = pdep_newlstr(L, "", 0);
- p->maxstacksize = 2;
- p->nups = nups;
- p->sizek = 0;
- p->sizep = 0;
-
- return p;
-}
-
-/* The GC is not fond of finding upvalues in tables. We get around this
- * during persistence using a weakly keyed table, so that the GC doesn't
- * bother to mark them. This won't work in unpersisting, however, since
- * if we make the values weak they'll be collected (since nothing else
- * references them). Our solution, during unpersisting, is to represent
- * upvalues as dummy functions, each with one upvalue. */
-static void boxupval_start(lua_State *L)
-{
- LClosure *lcl;
- lcl = (LClosure *)pdep_newLclosure(L, 1, hvalue(&L->l_gt));
- pushclosure(L, (Closure *)lcl);
- /* ... func */
- lcl->p = makefakeproto(L, 1);
-
- /* Temporarily initialize the upvalue to nil */
-
- lua_pushnil(L);
- lcl->upvals[0] = makeupval(L, -1);
- lua_pop(L, 1);
-}
-
-static void boxupval_finish(lua_State *L)
-{
- /* ... func obj */
- LClosure *lcl = (LClosure *) clvalue(getobject(L, -2));
-
- lcl->upvals[0]->u.value = *getobject(L, -1);
- lua_pop(L, 1);
-}
-
-
-static void unboxupval(lua_State *L)
-{
- /* ... func */
- LClosure *lcl;
- UpVal *uv;
-
- lcl = (LClosure *)clvalue(getobject(L, -1));
- uv = lcl->upvals[0];
- lua_pop(L, 1);
- /* ... */
- pushupval(L, uv);
- /* ... upval */
-}
-
-static void unpersistfunction(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- LClosure *lcl;
- int i;
- lu_byte nupvalues;
- lua_checkstack(upi->L, 2);
-
- verify(LIF(Z,read)(&upi->zio, &nupvalues, sizeof(lu_byte)) == 0);
-
- lcl = (LClosure *)pdep_newLclosure(upi->L, nupvalues, hvalue(&upi->L->l_gt));
- pushclosure(upi->L, (Closure *)lcl);
-
- /* perms reftbl ... func */
- /* Put *some* proto in the closure, before the GC can find it */
- lcl->p = makefakeproto(upi->L, nupvalues);
-
- /* Also, we need to temporarily fill the upvalues */
- lua_pushnil(upi->L);
- /* perms reftbl ... func nil */
- for(i=0; iupvals[i] = makeupval(upi->L, -1);
- }
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
-
- /* I can't see offhand how a function would ever get to be self-
- * referential, but just in case let's register it early */
- registerobject(ref, upi);
-
- /* Now that it's safe, we can get the real proto */
- unpersist(upi);
- /* perms reftbl ... func proto? */
- lua_assert(lua_type(upi->L, -1) == LUA_TPROTO);
- /* perms reftbl ... func proto */
- lcl->p = toproto(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
-
- for(i=0; iL);
- /* perms reftbl ... func upval */
- lcl->upvals[i] = toupval(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
-
- /* Finally, the fenv */
- unpersist(upi);
- /* perms reftbl ... func fenv/nil? */
- lua_assert(lua_type(upi->L, -1) == LUA_TNIL ||
- lua_type(upi->L, -1) == LUA_TTABLE);
- /* perms reftbl ... func fenv/nil */
- if(!lua_isnil(upi->L, -1)) {
- /* perms reftbl ... func fenv */
- lua_setfenv(upi->L, -2);
- /* perms reftbl ... func */
- } else {
- /* perms reftbl ... func nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
-}
-
-static void unpersistupval(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 2);
-
- boxupval_start(upi->L);
- /* perms reftbl ... func */
- registerobject(ref, upi);
-
- unpersist(upi);
- /* perms reftbl ... func obj */
- boxupval_finish(upi->L);
- /* perms reftbl ... func */
-}
-
-static void unpersistproto(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- Proto *p;
- int i;
- int sizep, sizek;
-
- /* We have to be careful. The GC expects a lot out of protos. In
- * particular, we need to give the function a valid string for its
- * source, and valid code, even before we actually read in the real
- * code. */
- TString *source = pdep_newlstr(upi->L, "", 0);
- p = pdep_newproto(upi->L);
- p->source = source;
- p->sizecode=1;
- p->code = pdep_newvector(upi->L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->maxstacksize = 2;
- p->sizek = 0;
- p->sizep = 0;
-
- lua_checkstack(upi->L, 2);
-
- pushproto(upi->L, p);
- /* perms reftbl ... proto */
- /* We don't need to register early, since protos can never ever be
- * involved in cyclic references */
-
- /* Read in constant references */
- {
- verify(LIF(Z,read)(&upi->zio, &sizek, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->k, 0, sizek, TValue);
- for(i=0; iL, &p->k[i], getobject(upi->L, -1));
- p->sizek++;
- lua_pop(upi->L, 1);
- /* perms reftbl ... proto */
- }
- /* perms reftbl ... proto */
- }
- /* Read in sub-proto references */
- {
- verify(LIF(Z,read)(&upi->zio, &sizep, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->p, 0, sizep, Proto*);
- for(i=0; ip[i] = toproto(upi->L, -1);
- p->sizep++;
- lua_pop(upi->L, 1);
- /* perms reftbl ... proto */
- }
- /* perms reftbl ... proto */
- }
-
- /* Read in code */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizecode, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->code, 1, p->sizecode, Instruction);
- verify(LIF(Z,read)(&upi->zio, p->code,
- sizeof(Instruction) * p->sizecode) == 0);
- }
-
- /* Read in upvalue names */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizeupvalues, sizeof(int)) == 0);
- if (p->sizeupvalues)
- {
- LIF(M,reallocvector)(upi->L, p->upvalues, 0, p->sizeupvalues, TString *);
- for(i=0; isizeupvalues; i++)
- {
- unpersist(upi);
- p->upvalues[i] = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
- }
- }
- }
-
- /* Read in local variable infos */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizelocvars, sizeof(int)) == 0);
- if (p->sizelocvars)
- {
- LIF(M,reallocvector)(upi->L, p->locvars, 0, p->sizelocvars, LocVar);
- for(i=0; isizelocvars; i++)
- {
- unpersist(upi);
- p->locvars[i].varname = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
-
- verify(LIF(Z,read)(&upi->zio, &p->locvars[i].startpc, sizeof(int)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->locvars[i].endpc, sizeof(int)) == 0);
- }
- }
- }
-
- /* Read in source string*/
- unpersist(upi);
- p->source = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
-
- /* Read in line numbers */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizelineinfo, sizeof(int)) == 0);
- if (p->sizelineinfo)
- {
- LIF(M,reallocvector)(upi->L, p->lineinfo, 0, p->sizelineinfo, int);
- verify(LIF(Z,read)(&upi->zio, p->lineinfo,
- sizeof(int) * p->sizelineinfo) == 0);
- }
- }
-
- /* Read in linedefined and lastlinedefined */
- verify(LIF(Z,read)(&upi->zio, &p->linedefined, sizeof(int)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->lastlinedefined, sizeof(int)) == 0);
-
- /* Read in misc values */
- {
- verify(LIF(Z,read)(&upi->zio, &p->nups, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->numparams, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->is_vararg, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->maxstacksize, sizeof(lu_byte)) == 0);
- }
-}
-
-
-/* Does basically the opposite of luaC_link().
- * Right now this function is rather inefficient; it requires traversing the
- * entire root GC set in order to find one object. If the GC list were doubly
- * linked this would be much easier, but there's no reason for Lua to have
- * that. */
-static void gcunlink(lua_State *L, GCObject *gco)
-{
- GCObject *prevslot;
- if(G(L)->rootgc == gco) {
- G(L)->rootgc = G(L)->rootgc->gch.next;
- return;
- }
-
- prevslot = G(L)->rootgc;
- while(prevslot->gch.next != gco) {
- lua_assert(prevslot->gch.next != NULL);
- prevslot = prevslot->gch.next;
- }
-
- prevslot->gch.next = prevslot->gch.next->gch.next;
-}
-
-/* FIXME __ALL__ field ordering */
-static void unpersistthread(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_State *L2;
- size_t stacklimit = 0;
- L2 = lua_newthread(upi->L);
- lua_checkstack(upi->L, 3);
- /* L1: perms reftbl ... thr */
- /* L2: (empty) */
- registerobject(ref, upi);
-
- /* First, deserialize the object stack. */
- {
- size_t i, stacksize;
- read_size(&upi->zio, &stacksize);
- LIF(D,growstack)(L2, (int)stacksize);
- /* Make sure that the first stack element (a nil, representing
- * the imaginary top-level C function) is written to the very,
- * very bottom of the stack */
- L2->top--;
- for(i=0; iL, L2, stacksize);
- /* L1: perms reftbl ... thr */
- /* L2: obj* */
- }
- /* (hereafter, stacks refer to L1) */
-
- /* Now, deserialize the CallInfo stack. */
- {
- size_t i, numframes;
- read_size(&upi->zio, &numframes);
- LIF(D,reallocCI)(L2,numframes*2);
- for(i=0; ibase_ci + i;
- size_t stackbase, stackfunc, stacktop, savedpc;
- read_size(&upi->zio, &stackbase);
- read_size(&upi->zio, &stackfunc);
- read_size(&upi->zio, &stacktop);
- verify(LIF(Z,read)(&upi->zio, &ci->nresults, sizeof(int)) == 0);
- read_size(&upi->zio, &savedpc);
-
- if(stacklimit < stacktop)
- stacklimit = stacktop;
-
- ci->base = L2->stack+stackbase;
- ci->func = L2->stack+stackfunc;
- ci->top = L2->stack+stacktop;
- ci->savedpc = (ci != L2->base_ci) ?
- ci_func(ci)->l.p->code+savedpc :
- 0;
- ci->tailcalls = 0;
- /* Update the pointer each time, to keep the GC
- * happy*/
- L2->ci = ci;
- }
- }
- /* perms reftbl ... thr */
- /* Deserialize the state's other parameters, with the exception of upval stuff */
- {
- size_t stackbase, stacktop;
- L2->savedpc = L2->ci->savedpc;
- verify(LIF(Z,read)(&upi->zio, &L2->status, sizeof(lu_byte)) == 0);
- read_size(&upi->zio, &stackbase);
- read_size(&upi->zio, &stacktop);
-
-#ifdef SIZES64
- uint64 value;
- verify(LIF(Z,read)(&upi->zio, &value, sizeof(uint64)) == 0);
-
- L2->errfunc = static_cast(value);
-#else
- verify(LIF(Z,read)(&upi->zio, &L2->errfunc, sizeof(ptrdiff_t)) == 0);
-#endif
-
- //read_size(&upi->zio, (size_t *)&L2->errfunc);
- L2->base = L2->stack + stackbase;
- L2->top = L2->stack + stacktop;
- }
- /* Finally, "reopen" upvalues (see persistupval() for why) */
- {
- UpVal* uv;
- GCObject **nextslot = &L2->openupval;
- global_State *g = G(L2);
- while(1) {
- size_t stackpos;
- unpersist(upi);
- /* perms reftbl ... thr uv/nil */
- if(lua_isnil(upi->L, -1)) {
- /* perms reftbl ... thr nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... thr */
- break;
- }
- /* perms reftbl ... thr boxeduv */
- unboxupval(upi->L);
- /* perms reftbl ... thr uv */
- uv = toupval(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... thr */
-
- read_size(&upi->zio, &stackpos);
- uv->v = L2->stack + stackpos;
- gcunlink(upi->L, (GCObject *)uv);
- uv->marked = luaC_white(g);
- *nextslot = (GCObject *)uv;
- nextslot = &uv->next;
- uv->u.l.prev = &G(L2)->uvhead;
- uv->u.l.next = G(L2)->uvhead.u.l.next;
- uv->u.l.next->u.l.prev = uv;
- G(L2)->uvhead.u.l.next = uv;
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- }
- *nextslot = NULL;
- }
-
- /* The stack must be valid at least to the highest value among the CallInfos */
- /* 'top' and the values up to there must be filled with 'nil' */
- {
- StkId o;
- LIF(D,checkstack)(L2, (int)stacklimit);
- for (o = L2->top; o <= L2->top + stacklimit; o++)
- setnilvalue(o);
- }
-}
-
-static void unpersistuserdata(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int isspecial;
- lua_checkstack(upi->L, 2);
- verify(LIF(Z,read)(&upi->zio, &isspecial, sizeof(int)) == 0);
- if(isspecial) {
- unpersist(upi);
- /* perms reftbl ... spfunc? */
- lua_assert(lua_isfunction(upi->L, -1));
- /* perms reftbl ... spfunc */
-#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
- lua_pushlightuserdata(upi->L, &upi->zio);
- lua_call(upi->L, 1, 1);
-#else
- lua_call(upi->L, 0, 1);
-#endif
- /* perms reftbl ... udata? */
-/* This assertion might not be necessary; it's conceivable, for
- * example, that the SP function might decide to return a table
- * with equivalent functionality. For the time being, we'll
- * ignore this possibility in favor of stricter and more testable
- * requirements. */
- lua_assert(lua_isuserdata(upi->L, -1));
- /* perms reftbl ... udata */
- } else {
- size_t length;
- read_size(&upi->zio, &length);
-
- lua_newuserdata(upi->L, length);
- /* perms reftbl ... udata */
- registerobject(ref, upi);
- verify(LIF(Z,read)(&upi->zio, lua_touserdata(upi->L, -1), length) == 0);
-
- unpersist(upi);
- /* perms reftbl ... udata mt/nil? */
- lua_assert(lua_istable(upi->L, -1) || lua_isnil(upi->L, -1));
- /* perms reftbl ... udata mt/nil */
- lua_setmetatable(upi->L, -2);
- /* perms reftbl ... udata */
- }
- /* perms reftbl ... udata */
-}
-
-static void unpersistpermanent(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 2);
- unpersist(upi);
- /* perms reftbl permkey */
- lua_gettable(upi->L, 1);
- /* perms reftbl perm? */
- /* We assume currently that the substituted permanent value
- * shouldn't be nil. This may be a bad assumption. Real-life
- * experience is needed to evaluate this. */
- lua_assert(!lua_isnil(upi->L, -1));
- /* perms reftbl perm */
-}
-
-#if 0
-/* For debugging only; not called when lua_assert is empty */
-static int inreftable(lua_State *L, int ref)
-{
- int res;
- lua_checkstack(L, 1);
- /* perms reftbl ... */
- lua_pushlightuserdata(L, (void *)ref);
- /* perms reftbl ... ref */
- lua_gettable(L, 2);
- /* perms reftbl ... obj? */
- res = !lua_isnil(L, -1);
- lua_pop(L, 1);
- /* perms reftbl ... */
- return res;
-}
-#endif
-
-static void unpersist(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int firstTime;
- int stacksize = lua_gettop(upi->L); stacksize = stacksize; /* DEBUG */
- lua_checkstack(upi->L, 2);
- LIF(Z,read)(&upi->zio, &firstTime, sizeof(int));
- if(firstTime) {
- int ref;
- int type;
- LIF(Z,read)(&upi->zio, &ref, sizeof(int));
- lua_assert(!inreftable(upi->L, ref));
- LIF(Z,read)(&upi->zio, &type, sizeof(int));
-#ifdef PLUTO_DEBUG
- printindent(upi->level);
- printf("1 %d %d\n", ref, type);
- upi->level++;
-#endif
- switch(type) {
- case LUA_TBOOLEAN:
- unpersistboolean(upi);
- break;
- case LUA_TLIGHTUSERDATA:
- unpersistlightuserdata(upi);
- break;
- case LUA_TNUMBER:
- unpersistnumber(upi);
- break;
- case LUA_TSTRING:
- unpersiststring(upi);
- break;
- case LUA_TTABLE:
- unpersisttable(ref, upi);
- break;
- case LUA_TFUNCTION:
- unpersistfunction(ref, upi);
- break;
- case LUA_TTHREAD:
- unpersistthread(ref, upi);
- break;
- case LUA_TPROTO:
- unpersistproto(ref, upi);
- break;
- case LUA_TUPVAL:
- unpersistupval(ref, upi);
- break;
- case LUA_TUSERDATA:
- unpersistuserdata(ref, upi);
- break;
- case PLUTO_TPERMANENT:
- unpersistpermanent(ref, upi);
- break;
- default:
- lua_assert(0);
- }
- /* perms reftbl ... obj */
- lua_assert(lua_type(upi->L, -1) == type ||
- type == PLUTO_TPERMANENT ||
- /* Remember, upvalues get a special dispensation, as
- * described in boxupval */
- (lua_type(upi->L, -1) == LUA_TFUNCTION &&
- type == LUA_TUPVAL));
- registerobject(ref, upi);
- /* perms reftbl ... obj */
-#ifdef PLUTO_DEBUG
- upi->level--;
-#endif
- } else {
- int ref;
- LIF(Z,read)(&upi->zio, &ref, sizeof(int));
-#ifdef PLUTO_DEBUG
- printindent(upi->level);
- printf("0 %d\n", ref);
-#endif
- if(ref == 0) {
- lua_pushnil(upi->L);
- /* perms reftbl ... nil */
- } else {
- lua_pushlightuserdata(upi->L, (void *)ref);
- /* perms reftbl ... ref */
- lua_gettable(upi->L, 2);
- /* perms reftbl ... obj? */
- lua_assert(!lua_isnil(upi->L, -1));
- }
- /* perms reftbl ... obj/nil */
- }
- /* perms reftbl ... obj/nil */
- lua_assert(lua_gettop(upi->L) == stacksize + 1);
-}
-
-void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud)
-{
- /* We use the graciously provided ZIO (what the heck does the Z stand
- * for?) library so that we don't have to deal with the reader directly.
- * Letting the reader function decide how much data to return can be
- * very unpleasant.
- */
- UnpersistInfo upi;
- upi.L = L;
-#ifdef PLUTO_DEBUG
- upi.level = 0;
-#endif
-
- lua_checkstack(L, 3);
- LIF(Z,init)(L, &upi.zio, reader, ud);
-
- /* perms */
- lua_newtable(L);
- /* perms reftbl */
- lua_gc(L, LUA_GCSTOP, 0);
- unpersist(&upi);
- lua_gc(L, LUA_GCRESTART, 0);
- /* perms reftbl rootobj */
- lua_replace(L, 2);
- /* perms rootobj */
-}
-
-typedef struct LoadInfo_t {
- char *buf;
- size_t size;
-} LoadInfo;
-
-
-static const char *bufreader(lua_State *L, void *ud, size_t *sz) {
- LoadInfo *li = (LoadInfo *)ud;
- if(li->size == 0) {
- return NULL;
- }
- *sz = li->size;
- li->size = 0;
- return li->buf;
-}
-
-int unpersist_l(lua_State *L)
-{
- LoadInfo li;
- char const *origbuf;
- char *tempbuf;
- size_t bufsize;
- /* perms? str? ...? */
- lua_settop(L, 2);
- /* perms? str? */
- origbuf = luaL_checklstring(L, 2, &bufsize);
- tempbuf = LIF(M,newvector)(L, bufsize, char);
- memcpy(tempbuf, origbuf, bufsize);
-
- li.buf = tempbuf;
- li.size = bufsize;
-
- /* perms? str */
- lua_pop(L, 1);
- /* perms? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms */
- pluto_unpersist(L, bufreader, &li);
- /* perms rootobj */
- LIF(M,freearray)(L, tempbuf, bufsize, char);
- return 1;
-}
-
-/* Stefan's first C function for Lua! :)
- Returns a string describing the Pluto version you're using. */
-
-int version_l(lua_State *L)
-{
- const char *version = VERSION;
-
- lua_settop(L, 0);
- /* (empty) */
- lua_pushlstring(L, version, strlen(version));
- /* str */
- return 1;
-}
-
-/* Set human-readable output on or off. */
-int human_l(lua_State *L)
-{
- /* flag? ...? */
- lua_settop(L, 1);
- /* flag? */
- /*luaL_checktype(L, 1, LUA_TBOOLEAN);*/
- /* flag */
-
- humanReadable = lua_toboolean(L, 1);
-
- lua_settop(L, 0);
- /* (empty) */
- return 0;
-}
-
-static luaL_reg pluto_reg[] = {
- { "persist", persist_l },
- { "unpersist", unpersist_l },
- { "version", version_l },
- { "human", human_l },
- { NULL, NULL }
-};
-
-LUALIB_API int luaopen_pluto(lua_State *L) {
- luaL_openlib(L, "pluto", pluto_reg, 0);
- return 1;
-}
diff --git a/engines/sword25/util/pluto/pluto.h b/engines/sword25/util/pluto/pluto.h
deleted file mode 100644
index 3674842d44..0000000000
--- a/engines/sword25/util/pluto/pluto.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* $Id$ */
-
-/* Pluto - Heavy-duty persistence for Lua
- * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
- * domain. People making use of this software as part of an application
- * are politely requested to email the author at sneftel@gmail.com
- * with a brief description of the application, primarily to satisfy his
- * curiosity.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* lua.h must be included before this file */
-
-void pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud);
-
-void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud);
-
-LUALIB_API int luaopen_pluto(lua_State *L);
diff --git a/engines/sword25/util/pluto/plzio.cpp b/engines/sword25/util/pluto/plzio.cpp
deleted file mode 100644
index 21f69a9e8d..0000000000
--- a/engines/sword25/util/pluto/plzio.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-** $Id$
-** a generic input stream interface
-** See Copyright Notice in lua.h
-*/
-
-
-#include
-
-#define lzio_c
-#define LUA_CORE
-
-#include "pdep/pdep.h"
-
-int pdep_fill (ZIO *z) {
- size_t size;
- lua_State *L = z->L;
- const char *buff;
- lua_unlock(L);
- buff = z->reader(L, z->data, &size);
- lua_lock(L);
- if (buff == NULL || size == 0) return EOZ;
- z->n = size - 1;
- z->p = buff;
- return char2int(*(z->p++));
-}
-
-
-int pdep_lookahead (ZIO *z) {
- if (z->n == 0) {
- if (pdep_fill(z) == EOZ)
- return EOZ;
- else {
- z->n++; /* pdep_fill removed first byte; put back it */
- z->p--;
- }
- }
- return char2int(*z->p);
-}
-
-
-void pdep_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
- z->L = L;
- z->reader = reader;
- z->data = data;
- z->n = 0;
- z->p = NULL;
-}
-
-
-/* --------------------------------------------------------------- read --- */
-size_t pdep_read (ZIO *z, void *b, size_t n) {
- while (n) {
- size_t m;
- if (pdep_lookahead(z) == EOZ)
- return n; /* return number of missing bytes */
- m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
- memcpy(b, z->p, m);
- z->n -= m;
- z->p += m;
- b = (char *)b + m;
- n -= m;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-char *pdep_openspace (lua_State *L, Mbuffer *buff, size_t n) {
- if (n > buff->buffsize) {
- if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
- pdep_resizebuffer(L, buff, n);
- }
- return buff->buffer;
-}
--
cgit v1.2.3
From eaff6a40f6f9cb8a5817c7b90a7e24c8c12da3fe Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 18:21:43 -0600
Subject: SWORD25: Correct include guards to reflect the changes to the file
names
---
engines/sword25/util/lua_persistence.h | 4 ++--
engines/sword25/util/lua_persistence_util.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/engines/sword25/util/lua_persistence.h b/engines/sword25/util/lua_persistence.h
index cf7d7e03ca..88cbb04ad2 100644
--- a/engines/sword25/util/lua_persistence.h
+++ b/engines/sword25/util/lua_persistence.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef LUA_SERIALIZATION_H
-#define LUA_SERIALIZATION_H
+#ifndef LUA_PERSISTENCE_H
+#define LUA_PERSISTENCE_H
#include "sword25/util/lua/lua.h"
diff --git a/engines/sword25/util/lua_persistence_util.h b/engines/sword25/util/lua_persistence_util.h
index 345996f606..305eea4aaf 100644
--- a/engines/sword25/util/lua_persistence_util.h
+++ b/engines/sword25/util/lua_persistence_util.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef LUA_SERIALIZATION_UTIL_H
-#define LUA_SERIALIZATION_UTIL_H
+#ifndef LUA_PERISTENCE_UTIL_H
+#define LUA_PERISTENCE_UTIL_H
struct lua_State;
--
cgit v1.2.3
From 8ee75e1dc56681337a3ae98c9d207e70e28c5ff5 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 18:22:15 -0600
Subject: SWORD25: Add Pluto copyright message to new persistence code
Since the code is based off the Pluto code
---
engines/sword25/util/lua_persist.cpp | 24 ++++++++++++++
engines/sword25/util/lua_persistence.h | 23 +++++++++++++
engines/sword25/util/lua_persistence_util.cpp | 47 +++++++++++++++++++++++++++
engines/sword25/util/lua_persistence_util.h | 24 ++++++++++++++
engines/sword25/util/lua_unpersist.cpp | 24 ++++++++++++++
5 files changed, 142 insertions(+)
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
index 6d758067ad..aea4e70036 100644
--- a/engines/sword25/util/lua_persist.cpp
+++ b/engines/sword25/util/lua_persist.cpp
@@ -20,6 +20,30 @@
*
*/
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
#include "sword25/util/lua_persistence.h"
#include "sword25/util/double_serialization.h"
diff --git a/engines/sword25/util/lua_persistence.h b/engines/sword25/util/lua_persistence.h
index 88cbb04ad2..53e3dee02e 100644
--- a/engines/sword25/util/lua_persistence.h
+++ b/engines/sword25/util/lua_persistence.h
@@ -20,6 +20,29 @@
*
*/
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
#ifndef LUA_PERSISTENCE_H
#define LUA_PERSISTENCE_H
diff --git a/engines/sword25/util/lua_persistence_util.cpp b/engines/sword25/util/lua_persistence_util.cpp
index 8365f5d483..958fb7ac3c 100644
--- a/engines/sword25/util/lua_persistence_util.cpp
+++ b/engines/sword25/util/lua_persistence_util.cpp
@@ -20,6 +20,53 @@
*
*/
+/**
+ * This code is heavily based on the pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
#include "sword25/util/lua_persistence_util.h"
#include "common/scummsys.h"
diff --git a/engines/sword25/util/lua_persistence_util.h b/engines/sword25/util/lua_persistence_util.h
index 305eea4aaf..4d0085e242 100644
--- a/engines/sword25/util/lua_persistence_util.h
+++ b/engines/sword25/util/lua_persistence_util.h
@@ -20,6 +20,30 @@
*
*/
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
#ifndef LUA_PERISTENCE_UTIL_H
#define LUA_PERISTENCE_UTIL_H
diff --git a/engines/sword25/util/lua_unpersist.cpp b/engines/sword25/util/lua_unpersist.cpp
index 8d644302f9..6f3275741a 100644
--- a/engines/sword25/util/lua_unpersist.cpp
+++ b/engines/sword25/util/lua_unpersist.cpp
@@ -20,6 +20,30 @@
*
*/
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
#include "sword25/util/lua_persistence.h"
#include "sword25/util/double_serialization.h"
--
cgit v1.2.3
From 9a4d62e76a29647ed7f2c0b16f009ff143fdf739 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 18:26:59 -0600
Subject: SWORD25: Change function names to use persist instead of serialize
Same argument as in 97c35714ce3986b99848a780f6b195a63f8910b7.
To match the rest of the SWORD25 code base
---
engines/sword25/util/lua_persist.cpp | 98 +++++++++++++++----------------
engines/sword25/util/lua_unpersist.cpp | 102 ++++++++++++++++-----------------
2 files changed, 100 insertions(+), 100 deletions(-)
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
index aea4e70036..6038111bbc 100644
--- a/engines/sword25/util/lua_persist.cpp
+++ b/engines/sword25/util/lua_persist.cpp
@@ -66,17 +66,17 @@ struct SerializationInfo {
uint counter;
};
-static void serialize(SerializationInfo *info);
+static void persist(SerializationInfo *info);
-static void serializeBoolean(SerializationInfo *info);
-static void serializeNumber(SerializationInfo *info);
-static void serializeString(SerializationInfo *info);
-static void serializeTable(SerializationInfo *info);
-static void serializeFunction(SerializationInfo *info);
-static void serializeThread(SerializationInfo *info);
-static void serializeProto(SerializationInfo *info);
-static void serializeUpValue(SerializationInfo *info);
-static void serializeUserData(SerializationInfo *info);
+static void persistBoolean(SerializationInfo *info);
+static void persistNumber(SerializationInfo *info);
+static void persistString(SerializationInfo *info);
+static void persistTable(SerializationInfo *info);
+static void persistFunction(SerializationInfo *info);
+static void persistThread(SerializationInfo *info);
+static void persistProto(SerializationInfo *info);
+static void persistUpValue(SerializationInfo *info);
+static void persistUserData(SerializationInfo *info);
void persistLua(lua_State *luaState, Common::WriteStream *writeStream) {
@@ -127,14 +127,14 @@ void persistLua(lua_State *luaState, Common::WriteStream *writeStream) {
// >>>>> permTbl indexTbl rootObj
// Serialize the root recursively
- serialize(&info);
+ persist(&info);
// Return the stack back to the original state
lua_remove(luaState, 2);
// >>>>> permTbl rootObj
}
-static void serialize(SerializationInfo *info) {
+static void persist(SerializationInfo *info) {
// The stack can potentially have many things on it
// The object we want to serialize is the item on the top of the stack
// >>>>> permTbl indexTbl rootObj ...... obj
@@ -215,7 +215,7 @@ static void serialize(SerializationInfo *info) {
info->writeStream->writeSint32LE(PERMANENT_TYPE);
// Serialize the key
- serialize(info);
+ persist(info);
// Pop the key off the stack
lua_pop(info->luaState, 1);
@@ -236,7 +236,7 @@ static void serialize(SerializationInfo *info) {
switch (objType) {
case LUA_TBOOLEAN:
- serializeBoolean(info);
+ persistBoolean(info);
break;
case LUA_TLIGHTUSERDATA:
// You can't serialize a pointer
@@ -244,41 +244,41 @@ static void serialize(SerializationInfo *info) {
assert(0);
break;
case LUA_TNUMBER:
- serializeNumber(info);
+ persistNumber(info);
break;
case LUA_TSTRING:
- serializeString(info);
+ persistString(info);
break;
case LUA_TTABLE:
- serializeTable(info);
+ persistTable(info);
break;
case LUA_TFUNCTION:
- serializeFunction(info);
+ persistFunction(info);
break;
case LUA_TTHREAD:
- serializeThread(info);
+ persistThread(info);
break;
case LUA_TPROTO:
- serializeProto(info);
+ persistProto(info);
break;
case LUA_TUPVAL:
- serializeUpValue(info);
+ persistUpValue(info);
break;
case LUA_TUSERDATA:
- serializeUserData(info);
+ persistUserData(info);
break;
default:
assert(0);
}
}
-static void serializeBoolean(SerializationInfo *info) {
+static void persistBoolean(SerializationInfo *info) {
int value = lua_toboolean(info->luaState, -1);
info->writeStream->writeSint32LE(value);
}
-static void serializeNumber(SerializationInfo *info) {
+static void persistNumber(SerializationInfo *info) {
lua_Number value = lua_tonumber(info->luaState, -1);
#if 1
@@ -298,7 +298,7 @@ static void serializeNumber(SerializationInfo *info) {
}
-static void serializeString(SerializationInfo *info) {
+static void persistString(SerializationInfo *info) {
// Hard cast to a uint32 to force size_t to an explicit size
// *Theoretically* this could truncate, but if we have a 4gb string, we have bigger problems
uint32 length = static_cast(lua_strlen(info->luaState, -1));
@@ -395,7 +395,7 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
info->writeStream->writeSint32LE(1);
// Serialize the function
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 2);
// >>>>> permTbl indexTbl ...... obj
@@ -403,7 +403,7 @@ static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
return true;
}
-static void serializeTable(SerializationInfo *info) {
+static void persistTable(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... tbl
// Make sure there is enough room on the stack
@@ -422,7 +422,7 @@ static void serializeTable(SerializationInfo *info) {
}
// >>>>> permTbl indexTbl ...... tbl metaTbl/nil */
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl
@@ -439,13 +439,13 @@ static void serializeTable(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... tbl k v k */
// Serialize the key
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl k v */
// Serialize the value
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl k */
@@ -457,13 +457,13 @@ static void serializeTable(SerializationInfo *info) {
lua_pushnil(info->luaState);
// >>>>> permTbl indexTbl ...... tbl
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... tbl
}
-static void serializeFunction(SerializationInfo *info) {
+static void persistFunction(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... func
Closure *cl = clvalue(getObject(info->luaState, -1));
lua_checkstack(info->luaState, 2);
@@ -484,7 +484,7 @@ static void serializeFunction(SerializationInfo *info) {
pushProto(info->luaState, cl->l.p);
// >>>>> permTbl indexTbl ...... func proto */
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
@@ -495,7 +495,7 @@ static void serializeFunction(SerializationInfo *info) {
pushUpValue(info->luaState, cl->l.upvals[i]);
// >>>>> permTbl indexTbl ...... func upval
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
@@ -519,14 +519,14 @@ static void serializeFunction(SerializationInfo *info) {
}
// >>>>> permTbl indexTbl ...... func fenv/nil
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... func
}
}
-static void serializeThread(SerializationInfo *info) {
+static void persistThread(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... thread
lua_State *threadState = lua_tothread(info->luaState, -1);
@@ -547,7 +547,7 @@ static void serializeThread(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... thread (reversed contents of thread stack) */
for (; stackSize > 0; --stackSize) {
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
}
@@ -609,7 +609,7 @@ static void serializeThread(SerializationInfo *info) {
pushUpValue(info->luaState, upVal);
// >>>>> permTbl indexTbl ...... thread upVal
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... thread
@@ -624,13 +624,13 @@ static void serializeThread(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... thread nil
// Use nil as a terminator
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... thread
}
-static void serializeProto(SerializationInfo *info) {
+static void persistProto(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... proto
Proto *proto = gco2p(getObject(info->luaState, -1)->value.gc);
@@ -644,7 +644,7 @@ static void serializeProto(SerializationInfo *info) {
pushObject(info->luaState, &proto->k[i]);
// >>>>> permTbl indexTbl ...... proto const
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -660,7 +660,7 @@ static void serializeProto(SerializationInfo *info) {
pushProto(info->luaState, proto->p[i]);
// >>>>> permTbl indexTbl ...... proto subProto */
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -683,7 +683,7 @@ static void serializeProto(SerializationInfo *info) {
pushString(info->luaState, proto->upvalues[i]);
// >>>>> permTbl indexTbl ...... proto str
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -697,7 +697,7 @@ static void serializeProto(SerializationInfo *info) {
pushString(info->luaState, proto->locvars[i].varname);
// >>>>> permTbl indexTbl ...... proto str
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -711,7 +711,7 @@ static void serializeProto(SerializationInfo *info) {
pushString(info->luaState, proto->source);
// >>>>> permTbl indexTbl ...... proto sourceStr
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
// >>>>> permTbl indexTbl ...... proto
@@ -757,7 +757,7 @@ static void serializeProto(SerializationInfo *info) {
* (d) When unserializing, "reopen" each of these upvalues as the thread is
* unserialized
*/
-static void serializeUpValue(SerializationInfo *info) {
+static void persistUpValue(SerializationInfo *info) {
// >>>>> permTbl indexTbl ...... upval
assert(ttype(getObject(info->luaState, -1)) == LUA_TUPVAL);
UpVal *upValue = gco2uv(getObject(info->luaState, -1)->value.gc);
@@ -774,11 +774,11 @@ static void serializeUpValue(SerializationInfo *info) {
pushObject(info->luaState, upValue->v);
// >>>>> permTbl indexTbl ...... obj
- serialize(info);
+ persist(info);
// >>>>> permTbl indexTbl ...... obj
}
-static void serializeUserData(SerializationInfo *info) {
+static void persistUserData(SerializationInfo *info) {
// >>>>> permTbl rootObj ...... udata
// Make sure there is enough room on the stack
@@ -804,7 +804,7 @@ static void serializeUserData(SerializationInfo *info) {
}
// >>>>> permTbl rootObj ...... udata metaTbl/nil
- serialize(info);
+ persist(info);
lua_pop(info->luaState, 1);
/* perms reftbl ... udata */
diff --git a/engines/sword25/util/lua_unpersist.cpp b/engines/sword25/util/lua_unpersist.cpp
index 6f3275741a..ef0ef31041 100644
--- a/engines/sword25/util/lua_unpersist.cpp
+++ b/engines/sword25/util/lua_unpersist.cpp
@@ -64,18 +64,18 @@ struct UnSerializationInfo {
Common::ReadStream *readStream;
};
-static void unserialize(UnSerializationInfo *info);
+static void unpersist(UnSerializationInfo *info);
-static void unserializeBoolean(UnSerializationInfo *info);
-static void unserializeNumber(UnSerializationInfo *info);
-static void unserializeString(UnSerializationInfo *info);
-static void unserializeTable(UnSerializationInfo *info, int index);
-static void unserializeFunction(UnSerializationInfo *info, int index);
-static void unserializeThread(UnSerializationInfo *info, int index);
-static void unserializeProto(UnSerializationInfo *info, int index);
-static void unserializeUpValue(UnSerializationInfo *info, int index);
-static void unserializeUserData(UnSerializationInfo *info, int index);
-static void unserializePermanent(UnSerializationInfo *info, int index);
+static void unpersistBoolean(UnSerializationInfo *info);
+static void unpersistNumber(UnSerializationInfo *info);
+static void unpersistString(UnSerializationInfo *info);
+static void unpersistTable(UnSerializationInfo *info, int index);
+static void unpersistFunction(UnSerializationInfo *info, int index);
+static void unpersistThread(UnSerializationInfo *info, int index);
+static void unpersistProto(UnSerializationInfo *info, int index);
+static void unpersistUpValue(UnSerializationInfo *info, int index);
+static void unpersistUserData(UnSerializationInfo *info, int index);
+static void unpersistPermanent(UnSerializationInfo *info, int index);
void unpersistLua(lua_State *luaState, Common::ReadStream *readStream) {
@@ -98,7 +98,7 @@ void unpersistLua(lua_State *luaState, Common::ReadStream *readStream) {
lua_gc(luaState, LUA_GCSTOP, 0);
// Unserialize the root object
- unserialize(&info);
+ unpersist(&info);
// >>>>> permTbl indexTbl rootObj
// Re-start garbage collection
@@ -129,7 +129,7 @@ static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... obj
}
-static void unserialize(UnSerializationInfo *info) {
+static void unpersist(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -142,7 +142,7 @@ static void unserialize(UnSerializationInfo *info) {
switch (type) {
case LUA_TBOOLEAN:
- unserializeBoolean(info);
+ unpersistBoolean(info);
break;
case LUA_TLIGHTUSERDATA:
// You can't serialize a pointer
@@ -150,31 +150,31 @@ static void unserialize(UnSerializationInfo *info) {
assert(0);
break;
case LUA_TNUMBER:
- unserializeNumber(info);
+ unpersistNumber(info);
break;
case LUA_TSTRING:
- unserializeString(info);
+ unpersistString(info);
break;
case LUA_TTABLE:
- unserializeTable(info, index);
+ unpersistTable(info, index);
break;
case LUA_TFUNCTION:
- unserializeFunction(info, index);
+ unpersistFunction(info, index);
break;
case LUA_TTHREAD:
- unserializeThread(info, index);
+ unpersistThread(info, index);
break;
case LUA_TPROTO:
- unserializeProto(info, index);
+ unpersistProto(info, index);
break;
case LUA_TUPVAL:
- unserializeUpValue(info, index);
+ unpersistUpValue(info, index);
break;
case LUA_TUSERDATA:
- unserializeUserData(info, index);
+ unpersistUserData(info, index);
break;
case PERMANENT_TYPE:
- unserializePermanent(info, index);
+ unpersistPermanent(info, index);
break;
default:
assert(0);
@@ -212,7 +212,7 @@ static void unserialize(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ...... obj/nil
}
-static void unserializeBoolean(UnSerializationInfo *info) {
+static void unpersistBoolean(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -224,7 +224,7 @@ static void unserializeBoolean(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ...... bool
}
-static void unserializeNumber(UnSerializationInfo *info) {
+static void unpersistNumber(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -242,7 +242,7 @@ static void unserializeNumber(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ...... num
}
-static void unserializeString(UnSerializationInfo *info) {
+static void unpersistString(UnSerializationInfo *info) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -265,7 +265,7 @@ static void unserializeSpecialTable(UnSerializationInfo *info, int index) {
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 1);
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... spfunc
lua_call(info->luaState, 0, 1);
@@ -286,7 +286,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... tbl
// Unserialize metatable
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
if (lua_istable(info->luaState, -1)) {
@@ -303,7 +303,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
while (1) {
// >>>>> permTbl indexTbl ...... tbl
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... tbl key/nil
// The table serialization is nil terminated
@@ -316,7 +316,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
}
// >>>>> permTbl indexTbl ...... tbl key
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... tbl value
lua_rawset(info->luaState, -3);
@@ -324,7 +324,7 @@ static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
}
}
-void unserializeTable(UnSerializationInfo *info, int index) {
+void unpersistTable(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -341,7 +341,7 @@ void unserializeTable(UnSerializationInfo *info, int index) {
}
}
-void unserializeFunction(UnSerializationInfo *info, int index) {
+void unpersistFunction(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -372,7 +372,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
registerObjectInIndexTable(info, index);
// Now that it's safe, we can get the real proto
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... func proto
lclosure->p = gco2p(getObject(info->luaState, -1)->value.gc);
@@ -382,7 +382,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
for (byte i = 0; i < numUpValues; ++i) {
// >>>>> permTbl indexTbl ...... func
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... func func2
unboxUpValue(info->luaState);
@@ -394,7 +394,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
}
// Finally, the fenv
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... func ?fenv/nil?
if (!lua_isnil(info->luaState, -1)) {
@@ -410,7 +410,7 @@ void unserializeFunction(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... func
}
-void unserializeThread(UnSerializationInfo *info, int index) {
+void unpersistThread(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
lua_State *L2;
@@ -432,7 +432,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
// very bottom of the stack
L2->top--;
for (uint32 i = 0; i < stackSize; ++i) {
- unserialize(info);
+ unpersist(info);
// L1: permTbl indexTbl ...... thread obj*
}
@@ -492,7 +492,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
global_State *g = G(L2);
while (true) {
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... thread upVal/nil
// The list is terminated by a nil
@@ -535,7 +535,7 @@ void unserializeThread(UnSerializationInfo *info, int index) {
}
}
-void unserializeProto(UnSerializationInfo *info, int index) {
+void unpersistProto(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
// We have to be careful. The GC expects a lot out of protos. In particular, we need
@@ -564,7 +564,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
for (int i = 0; i < sizek; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... proto k
setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
@@ -581,7 +581,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
for (int i = 0; i < sizep; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... proto subproto
p->p[i] = (Proto *)getObject(info->luaState, -1)->value.gc;
@@ -605,7 +605,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
for (int i = 0; i < p->sizeupvalues; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... proto str
p->upvalues[i] = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
@@ -621,7 +621,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
for (int i = 0; i < p->sizelocvars; ++i) {
// >>>>> permTbl indexTbl ...... proto
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... proto str
p->locvars[i].varname = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
@@ -635,7 +635,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... proto
// Read in source string
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... proto sourceStr
p->source = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
@@ -661,7 +661,7 @@ void unserializeProto(UnSerializationInfo *info, int index) {
p->maxstacksize = info->readStream->readByte();
}
-void unserializeUpValue(UnSerializationInfo *info, int index) {
+void unpersistUpValue(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
lua_checkstack(info->luaState, 2);
@@ -669,14 +669,14 @@ void unserializeUpValue(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... func
registerObjectInIndexTable(info, index);
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... func obj
boxUpValue_finish(info->luaState);
// >>>>> permTbl indexTbl ...... func
}
-void unserializeUserData(UnSerializationInfo *info, int index) {
+void unpersistUserData(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
@@ -684,7 +684,7 @@ void unserializeUserData(UnSerializationInfo *info, int index) {
int isspecial = info->readStream->readSint32LE();
if (isspecial) {
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... specialFunc
lua_call(info->luaState, 0, 1);
@@ -697,7 +697,7 @@ void unserializeUserData(UnSerializationInfo *info, int index) {
info->readStream->read(lua_touserdata(info->luaState, -1), length);
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... udata metaTable/nil
lua_setmetatable(info->luaState, -2);
@@ -706,13 +706,13 @@ void unserializeUserData(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ...... udata
}
-void unserializePermanent(UnSerializationInfo *info, int index) {
+void unpersistPermanent(UnSerializationInfo *info, int index) {
// >>>>> permTbl indexTbl ......
// Make sure there is enough room on the stack
lua_checkstack(info->luaState, 2);
- unserialize(info);
+ unpersist(info);
// >>>>> permTbl indexTbl ...... permKey
lua_gettable(info->luaState, 1);
--
cgit v1.2.3
From e4f74b6c346023608841d9f871b16069e5b54194 Mon Sep 17 00:00:00 2001
From: RichieSams
Date: Tue, 30 Dec 2014 18:28:14 -0600
Subject: SWORD25: Remove the option to persist a double as a string
Since the current method *should* be more accurate
---
engines/sword25/util/lua_persist.cpp | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
index 6038111bbc..6fe88fe9a3 100644
--- a/engines/sword25/util/lua_persist.cpp
+++ b/engines/sword25/util/lua_persist.cpp
@@ -281,21 +281,11 @@ static void persistBoolean(SerializationInfo *info) {
static void persistNumber(SerializationInfo *info) {
lua_Number value = lua_tonumber(info->luaState, -1);
- #if 1
- Util::SerializedDouble serializedValue(Util::encodeDouble(value));
-
- info->writeStream->writeUint32LE(serializedValue.significandOne);
- info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
- info->writeStream->writeSint16LE(serializedValue.exponent);
- #else
- // NOTE: We need to store a double. Unfortunately, we have to accommodate endianness.
- // Also, I don't know if we can assume all compilers use IEEE double
- // Therefore, I have chosen to store the double as a string.
- Common::String buffer = Common::String::format("%f", value);
-
- info->writeStream->write(buffer.c_str(), buffer.size());
- #endif
+ Util::SerializedDouble serializedValue(Util::encodeDouble(value));
+ info->writeStream->writeUint32LE(serializedValue.significandOne);
+ info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
+ info->writeStream->writeSint16LE(serializedValue.exponent);
}
static void persistString(SerializationInfo *info) {
--
cgit v1.2.3
From f96dbd52c793a6b96bee8ecde0148ae85dd9fd9e Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Wed, 31 Dec 2014 10:10:32 +0100
Subject: ACCESS: MM - Implement some more tex palette handling
---
engines/access/martian/martian_room.cpp | 5 +++++
engines/access/player.cpp | 4 +++-
engines/access/player.h | 2 +-
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp
index dfc0dbcd5e..c4f38d8f99 100644
--- a/engines/access/martian/martian_room.cpp
+++ b/engines/access/martian/martian_room.cpp
@@ -82,7 +82,12 @@ void MartianRoom::reloadRoom1() {
setWallCodes();
buildScreen();
_vm->copyBF2Vid();
+
+ //
warning("TODO: setManPalette");
+ Common::copy(_vm->_player->_manPal1 + 0x2A0, _vm->_player->_manPal1 + 0x2A0 + 0x42, _vm->_screen->_manPal);
+ //
+
_vm->_events->showCursor();
_vm->_player->_frame = 0;
_vm->_oldRects.clear();
diff --git a/engines/access/player.cpp b/engines/access/player.cpp
index 41c5b47daf..fe555ec49a 100644
--- a/engines/access/player.cpp
+++ b/engines/access/player.cpp
@@ -140,7 +140,8 @@ void Player::load() {
_playerSprites = _playerSprites1;
if (_manPal1) {
- Common::copy(_manPal1 + 0x270, _manPal1 + 0x270 + 0x60, _vm->_screen->_manPal);
+ // Those values are from MM as Amazon doesn't use it
+ Common::copy(_manPal1 + 0x2A0, _manPal1 + 0x2A0 + 0x42, _vm->_screen->_manPal);
} else {
Common::fill(_vm->_screen->_manPal, _vm->_screen->_manPal + 0x60, 0);
}
@@ -149,6 +150,7 @@ void Player::load() {
void Player::loadTexPalette() {
Resource *_texPal = _vm->_files->loadFile("TEXPAL.COL");
int size = _texPal->_size;
+ assert(size == 768);
_manPal1 = new byte[size];
memcpy(_manPal1, _texPal->data(), size);
}
diff --git a/engines/access/player.h b/engines/access/player.h
index 1e66a72a95..db88892d7c 100644
--- a/engines/access/player.h
+++ b/engines/access/player.h
@@ -56,7 +56,6 @@ protected:
int _diagUpWalkMin, _diagUpWalkMax;
int _diagDownWalkMin, _diagDownWalkMax;
SpriteResource *_playerSprites1;
- byte *_manPal1;
int _scrollEnd;
int _inactiveYOff;
@@ -82,6 +81,7 @@ public:
Direction _playerDirection;
SpriteResource *_playerSprites;
// Fields in original Player structure
+ byte *_manPal1;
byte *_monData;
int *_walkOffRight;
int *_walkOffLeft;
--
cgit v1.2.3
From 3ac8a26cb950f63c2f3b25995d268a30b470d1fd Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Wed, 31 Dec 2014 10:11:15 +0100
Subject: ACCESS: MM - Start implementing intro
---
engines/access/martian/martian_game.cpp | 85 +++++++++++++++++++++-------
engines/access/martian/martian_game.h | 6 +-
engines/access/martian/martian_resources.cpp | 21 +++++++
engines/access/martian/martian_resources.h | 1 +
4 files changed, 91 insertions(+), 22 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index 6722120211..3371610418 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -110,33 +110,78 @@ void MartianEngine::playGame() {
} while (_restartFl);
}
+bool MartianEngine::showCredits() {
+ _events->hideCursor();
+ _screen->clearBuffer();
+ _destIn = _screen;
+
+ int val1 = _demoStream->readSint16LE();
+ int val2 = 0;
+ int val3 = 0;
+
+ while(val1 != -1) {
+ val2 = _demoStream->readSint16LE();
+ val3 = _demoStream->readSint16LE();
+ _screen->plotImage(_introObjects, val3, Common::Point(val1, val2));
+
+ val1 = _demoStream->readSint16LE();
+ }
+
+ val2 = _demoStream->readSint16LE();
+ if (val2 == -1) {
+ _events->showCursor();
+ _screen->forceFadeOut();
+ return true;
+ }
+
+ _screen->forceFadeIn();
+ _timers[6]._timer = val2;
+ _timers[6]._initTm = val2;
+
+ while (!shouldQuit() && !_events->isKeyMousePressed() && _timers[6]._timer) {
+ _events->pollEventsAndWait();
+ }
+
+ _events->showCursor();
+ _screen->forceFadeOut();
+
+ if (_events->_rightButton)
+ return true;
+ else
+ return false;
+}
+
void MartianEngine::doIntroduction() {
- _screen->setInitialPalettte();
- _events->setCursor(CURSOR_ARROW);
+ _midi->loadMusic(47, 3);
+ _midi->midiPlay();
+ _screen->setDisplayScan();
+ _events->hideCursor();
+ _screen->forceFadeOut();
+ Resource *data = _files->loadFile(41, 1);
+ _introObjects = new SpriteResource(this, data);
+ delete data;
+
+ _files->loadScreen(41, 0);
+ _buffer2.copyFrom(*_screen);
+ _buffer1.copyFrom(*_screen);
_events->showCursor();
- _screen->setPanel(0);
+ _demoStream = new Common::MemoryReadStream(DEMO_DATA, 180);
- // TODO: Worry about implementing full intro sequence later
- return;
+ if (!showCredits()) {
+ _screen->copyFrom(_buffer2);
+ _screen->forceFadeIn();
- doTitle();
- if (shouldQuit())
- return;
+ _events->_vbCount = 550;
+ while (!shouldQuit() && !_events->isKeyMousePressed() && _events->_vbCount > 0)
+ _events->pollEventsAndWait();
- if (!_skipStart) {
- _screen->setPanel(3);
- doOpening();
- if (shouldQuit())
- return;
+ _screen->forceFadeOut();
+ while (!shouldQuit() && !_events->isKeyMousePressed()&& !showCredits())
+ _events->pollEventsAndWait();
- if (!_skipStart) {
- //doTent();
- if (shouldQuit())
- return;
- }
+ warning("TODO: Free word_21E2B");
+ _midi->freeMusic();
}
-
- doTitle();
}
void MartianEngine::doTitle() {
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
index 812aa37ed1..e1606d7558 100644
--- a/engines/access/martian/martian_game.h
+++ b/engines/access/martian/martian_game.h
@@ -32,12 +32,15 @@ namespace Martian {
class MartianEngine : public AccessEngine {
private:
bool _skipStart;
-
+ SpriteResource *_introObjects;
+ Common::MemoryReadStream *_demoStream;
/**
* Do the game introduction
*/
void doIntroduction();
+ bool showCredits();
+
/**
* Do title sequence
*/
@@ -56,7 +59,6 @@ private:
void initObjects();
void configSelect();
void initVariables();
-
protected:
/**
* Play the game
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index 78d14b7c86..22a0cf1135 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -724,6 +724,27 @@ const int SIDEOFFL[] = { 11, 6, 1, 4, 10, 6, 1, 4, 0, 0, 0, 0 };
const int SIDEOFFU[] = { 1, 2, 0, 2, 2, 1, 1, 0, 0, 0, 0, 0 };
const int SIDEOFFD[] = { 2, 0, 1, 1, 0, 1, 1, 1, 2, 0, 0, 0 };
+const byte DEMO_DATA[] = {
+ 0x1F, 0x00, 0x49, 0x00, 0x00, 0x00, 0xB7, 0x00, 0x49, 0x00,
+ 0x01, 0x00, 0x79, 0x00, 0x6F, 0x00, 0x02, 0x00, 0xFF, 0xFF,
+ 0xEA, 0x01, 0x75, 0x00, 0x46, 0x00, 0x03, 0x00, 0x46, 0x00,
+ 0x5E, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xEA, 0x01, 0x72, 0x00,
+ 0x3E, 0x00, 0x05, 0x00, 0x46, 0x00, 0x57, 0x00, 0x04, 0x00,
+ 0x5C, 0x00, 0x6E, 0x00, 0x06, 0x00, 0xFF, 0xFF, 0xEA, 0x01,
+ 0x63, 0x00, 0x48, 0x00, 0x07, 0x00, 0x2A, 0x00, 0x65, 0x00,
+ 0x08, 0x00, 0xFF, 0xFF, 0xEA, 0x01, 0x7E, 0x00, 0x39, 0x00,
+ 0x09, 0x00, 0x5C, 0x00, 0x57, 0x00, 0x06, 0x00, 0x45, 0x00,
+ 0x6B, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xEA, 0x01, 0x5F, 0x00,
+ 0x46, 0x00, 0x0A, 0x00, 0x67, 0x00, 0x62, 0x00, 0x0B, 0x00,
+ 0x47, 0x00, 0x76, 0x00, 0x0C, 0x00, 0xFF, 0xFF, 0xEA, 0x01,
+ 0x62, 0x00, 0x38, 0x00, 0x0D, 0x00, 0x47, 0x00, 0x55, 0x00,
+ 0x0E, 0x00, 0x49, 0x00, 0x6A, 0x00, 0x0F, 0x00, 0xFF, 0xFF,
+ 0xEA, 0x01, 0x18, 0x00, 0x22, 0x00, 0x10, 0x00, 0x17, 0x00,
+ 0x3E, 0x00, 0x11, 0x00, 0x16, 0x00, 0x52, 0x00, 0x12, 0x00,
+ 0xEE, 0x00, 0x7B, 0x00, 0x13, 0x00, 0xB5, 0x00, 0x93, 0x00,
+ 0x0B, 0x00, 0xFF, 0xFF, 0xF4, 0x01, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
} // End of namespace Martian
} // End of namespace Access
diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h
index 36b4ce3d37..67f8cb44a3 100644
--- a/engines/access/martian/martian_resources.h
+++ b/engines/access/martian/martian_resources.h
@@ -50,6 +50,7 @@ extern const int SIDEOFFL[];
extern const int SIDEOFFU[];
extern const int SIDEOFFD[];
+extern const byte DEMO_DATA[];
} // End of namespace Martian
} // End of namespace Access
--
cgit v1.2.3
From f6fb26ea664184669f6b2a576831325d852ea71f Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Wed, 31 Dec 2014 13:13:47 +0100
Subject: ACCESS: MM - Remove unused intro functions, fix display in
showCredits
---
engines/access/martian/martian_game.cpp | 51 +--------------------------------
engines/access/martian/martian_game.h | 10 -------
2 files changed, 1 insertion(+), 60 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index 3371610418..6a96160960 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -112,7 +112,7 @@ void MartianEngine::playGame() {
bool MartianEngine::showCredits() {
_events->hideCursor();
- _screen->clearBuffer();
+ _screen->clearScreen();
_destIn = _screen;
int val1 = _demoStream->readSint16LE();
@@ -184,55 +184,6 @@ void MartianEngine::doIntroduction() {
}
}
-void MartianEngine::doTitle() {
- /*
- _screen->setDisplayScan();
- _destIn = &_buffer2;
-
- _screen->forceFadeOut();
- _events->hideCursor();
-
- _sound->queueSound(0, 98, 30);
-
- _files->_setPaletteFlag = false;
- _files->loadScreen(0, 3);
-
- _buffer2.copyFrom(*_screen);
- _buffer1.copyFrom(*_screen);
- _screen->forceFadeIn();
- _sound->playSound(1);
-
- Resource *spriteData = _files->loadFile(0, 2);
- _objectsTable[0] = new SpriteResource(this, spriteData);
- delete spriteData;
-
- _sound->playSound(1);
-
- _files->_setPaletteFlag = false;
- _files->loadScreen(0, 4);
- _sound->playSound(1);
-
- _buffer2.copyFrom(*_screen);
- _buffer1.copyFrom(*_screen);
- _sound->playSound(1);
-
- const int COUNTDOWN[6] = { 2, 0x80, 1, 0x7d, 0, 0x87 };
- for (_pCount = 0; _pCount < 3; ++_pCount) {
- _buffer2.copyFrom(_buffer1);
- int id = READ_LE_UINT16(COUNTDOWN + _pCount * 4);
- int xp = READ_LE_UINT16(COUNTDOWN + _pCount * 4 + 2);
- _screen->plotImage(_objectsTable[0], id, Common::Point(xp, 71));
- }
- // TODO: More to do
-
- delete _objectsTable[0];
- */
-}
-
-void MartianEngine::doOpening() {
- warning("TODO doOpening");
-}
-
void MartianEngine::setupGame() {
// Setup timers
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
index e1606d7558..99d4926964 100644
--- a/engines/access/martian/martian_game.h
+++ b/engines/access/martian/martian_game.h
@@ -41,16 +41,6 @@ private:
bool showCredits();
- /**
- * Do title sequence
- */
- void doTitle();
-
- /**
- * Do opening sequence
- */
- void doOpening();
-
/**
* Setup variables for the game
*/
--
cgit v1.2.3
From e83e55e7be274ea884f144ce69849e8bc65b479b Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Thu, 1 Jan 2015 15:35:20 +0100
Subject: ACCESS: MM - Implement the display of notes at the beginning of
chapters (WIP)
---
engines/access/martian/martian_game.cpp | 97 ++++++++++++++++++++++++++++--
engines/access/martian/martian_game.h | 6 +-
engines/access/martian/martian_scripts.cpp | 29 +++++++++
engines/access/martian/martian_scripts.h | 4 ++
engines/access/sound.cpp | 7 +++
engines/access/sound.h | 1 +
6 files changed, 138 insertions(+), 6 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index 6a96160960..a14d7830b3 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -75,6 +75,88 @@ void MartianEngine::initVariables() {
_numAnimTimers = 0;
}
+void MartianEngine::sub13E1F() {
+ _events->hideCursor();
+
+ _screen->_orgX1 = 58;
+ _screen->_orgY1 = 124;
+ _screen->_orgX2 = 297;
+ _screen->_orgY2 = 199;
+ _screen->drawRect();
+
+ _events->showCursor();
+}
+
+void MartianEngine::sub13E4C(const Common::String &msg) {
+ _fonts._charSet._lo = 1;
+ _fonts._charSet._hi = 8;
+ _fonts._charFor._lo = 0;
+ _fonts._charFor._hi = 255;
+
+ _screen->_maxChars = 40;
+ _screen->_printOrg = _screen->_printStart = Common::Point(59, 124);
+
+ sub13E1F();
+
+ Common::String lines = msg;
+ Common::String line;
+ int width = 0;
+ bool lastLine = false;
+ do {
+ lastLine = _fonts._font2.getLine(lines, _screen->_maxChars * 6, line, width);
+
+ // Set font colors
+ _fonts._font2._fontColors[0] = 0;
+ _fonts._font2._fontColors[1] = 27;
+ _fonts._font2._fontColors[2] = 28;
+ _fonts._font2._fontColors[3] = 29;
+
+ _fonts._font2.drawString(_screen, line, _screen->_printOrg);
+ _screen->_printOrg = Common::Point(_screen->_printStart.x, _screen->_printOrg.y + 6);
+
+ if (_screen->_printOrg.y == 196) {
+ _events->waitKeyMouse();
+ sub13E1F();
+ _screen->_printOrg = _screen->_printStart;
+ }
+ } while (!lastLine);
+ _events->waitKeyMouse();
+}
+
+void MartianEngine::doSpecial5(int param1) {
+ warning("TODO: Push midi song");
+ _midi->stopSong();
+ _midi->_byte1F781 = false;
+ _midi->loadMusic(47, 4);
+ _midi->midiPlay();
+ _screen->setDisplayScan();
+ _events->clearEvents();
+ _screen->forceFadeOut();
+ _events->hideCursor();
+ _files->loadScreen("DATA.SC");
+ _events->showCursor();
+ _screen->setIconPalette();
+ _screen->forceFadeIn();
+ warning("TODO: LoadCells");
+ _timers[20]._timer = _timers[20]._initTm = 30;
+ Resource *_word20060 = _files->loadFile("NOTES.DAT");
+ _word20060->_stream->skip(param1 * 2);
+ int pos = _word20060->_stream->readUint16LE();
+ _word20060->_stream->seek(pos);
+ Common::String msg = "";
+ byte c;
+ while ((c = (char)_word20060->_stream->readByte()) != '\0')
+ msg += c;
+
+ sub13E4C(msg);
+
+ _midi->stopSong();
+ _midi->freeMusic();
+
+ warning("TODO: Pop Midi");
+ // _midi->_byte1F781 = true;
+}
+
void MartianEngine::playGame() {
// Initialize Amazon game-specific objects
initObjects();
@@ -85,9 +167,14 @@ void MartianEngine::playGame() {
if (_loadSaveSlot == -1) {
// Do introduction
- doIntroduction();
+// doCredits();
if (shouldQuit())
return;
+
+ doSpecial5(4);
+ if (shouldQuit())
+ return;
+ _screen->forceFadeOut();
}
do {
@@ -135,10 +222,9 @@ bool MartianEngine::showCredits() {
}
_screen->forceFadeIn();
- _timers[6]._timer = val2;
- _timers[6]._initTm = val2;
+ _timers[3]._timer = _timers[3]._initTm = val2;
- while (!shouldQuit() && !_events->isKeyMousePressed() && _timers[6]._timer) {
+ while (!shouldQuit() && !_events->isKeyMousePressed() && _timers[3]._timer) {
_events->pollEventsAndWait();
}
@@ -151,7 +237,8 @@ bool MartianEngine::showCredits() {
return false;
}
-void MartianEngine::doIntroduction() {
+void MartianEngine::doCredits() {
+ _midi->_byte1F781 = false;
_midi->loadMusic(47, 3);
_midi->midiPlay();
_screen->setDisplayScan();
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
index 99d4926964..bd32527ffd 100644
--- a/engines/access/martian/martian_game.h
+++ b/engines/access/martian/martian_game.h
@@ -37,7 +37,7 @@ private:
/**
* Do the game introduction
*/
- void doIntroduction();
+ void doCredits();
bool showCredits();
@@ -56,11 +56,15 @@ protected:
virtual void playGame();
virtual void dead(int deathId) {}
+
+ void sub13E1F();
+ void sub13E4C(const Common::String &msg);
public:
MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc);
virtual ~MartianEngine();
+ void doSpecial5(int param1);
void drawHelp();
virtual void establish(int esatabIndex, int sub) {};
};
diff --git a/engines/access/martian/martian_scripts.cpp b/engines/access/martian/martian_scripts.cpp
index 0578872092..8d936ba728 100644
--- a/engines/access/martian/martian_scripts.cpp
+++ b/engines/access/martian/martian_scripts.cpp
@@ -34,7 +34,36 @@ MartianScripts::MartianScripts(AccessEngine *vm) : Scripts(vm) {
_game = (MartianEngine *)_vm;
}
+void MartianScripts::cmdSpecial5(int param1) {
+ _game->doSpecial5(param1);
+}
+
void MartianScripts::executeSpecial(int commandIndex, int param1, int param2) {
+ switch (commandIndex) {
+ case 0:
+ warning("TODO: cmdSpecial0");
+ break;
+ case 1:
+ warning("TODO: cmdSpecial1");
+ break;
+ case 2:
+ warning("TODO: cmdSpecial2");
+ break;
+ case 3:
+ warning("TODO: cmdSpecial3");
+ break;
+ case 4:
+ warning("TODO: cmdSpecial4");
+ break;
+ case 5:
+ cmdSpecial5(param1);
+ break;
+ case 6:
+ warning("TODO: cmdSpecial6");
+ break;
+ default:
+ warning("Unexpected Special code %d - Skipped", commandIndex);
+ }
}
typedef void(MartianScripts::*MartianScriptMethodPtr)();
diff --git a/engines/access/martian/martian_scripts.h b/engines/access/martian/martian_scripts.h
index fc7495fc47..125f1e422d 100644
--- a/engines/access/martian/martian_scripts.h
+++ b/engines/access/martian/martian_scripts.h
@@ -35,9 +35,13 @@ class MartianEngine;
class MartianScripts : public Scripts {
private:
MartianEngine *_game;
+
+ void cmdSpecial5(int param1);
+
protected:
virtual void executeSpecial(int commandIndex, int param1, int param2);
virtual void executeCommand(int commandIndex);
+
public:
MartianScripts(AccessEngine *vm);
};
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index a7d96dac9a..9ade99cb72 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -178,6 +178,7 @@ MusicManager::MusicManager(AccessEngine *vm) : _vm(vm) {
_music = nullptr;
_tempMusic = nullptr;
_isLooping = false;
+ _byte1F781 = false;
MidiPlayer::createDriver();
MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
@@ -217,6 +218,12 @@ void MusicManager::midiPlay() {
if (READ_BE_UINT32(_music->data()) != MKTAG('F', 'O', 'R', 'M')) {
warning("midiPlay() Unexpected signature");
+ Common::DumpFile *outFile = new Common::DumpFile();
+ Common::String outName = "music.dump";
+ outFile->open(outName);
+ outFile->write(_music->data(), _music->_size);
+ outFile->finalize();
+ outFile->close();
_isPlaying = false;
} else {
_parser = MidiParser::createParser_XMIDI();
diff --git a/engines/access/sound.h b/engines/access/sound.h
index d0f4584fac..6bfdbcda7d 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -82,6 +82,7 @@ private:
public:
Resource *_music;
+ bool _byte1F781;
public:
MusicManager(AccessEngine *vm);
--
cgit v1.2.3
From 0c54278f6c2ea6d2a2ba10ed1e833695620625ca Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 2 Jan 2015 00:28:20 +0200
Subject: ZVISION: Fix newline in truetype_font.cpp
---
engines/zvision/text/truetype_font.cpp | 454 ++++++++++++++++-----------------
1 file changed, 227 insertions(+), 227 deletions(-)
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
index 85d9fa5a29..e378ccd127 100644
--- a/engines/zvision/text/truetype_font.cpp
+++ b/engines/zvision/text/truetype_font.cpp
@@ -1,228 +1,228 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-#include "common/config-manager.h"
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/system.h"
-#include "common/unzip.h"
-#include "graphics/font.h"
-#include "graphics/fonts/ttf.h"
-#include "graphics/surface.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/text/truetype_font.h"
-
-namespace ZVision {
-
-StyledTTFont::StyledTTFont(ZVision *engine) {
- _engine = engine;
- _style = 0;
- _font = NULL;
- _lineHeight = 0;
-}
-
-StyledTTFont::~StyledTTFont() {
- if (_font)
- delete _font;
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
- _style = style;
- return loadFont(fontName, point);
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
- struct FontStyle {
- const char *zorkFont;
- const char *fontBase;
- const char *freeFontBase;
- const char *freeFontItalicName;
- };
-
- const FontStyle systemFonts[] = {
- { "*times new roman*", "times", "FreeSerif", "Italic" },
- { "*times*", "times", "FreeSerif", "Italic" },
- { "*century schoolbook*", "censcbk", "FreeSerif", "Italic" },
- { "*garamond*", "gara", "FreeSerif", "Italic" },
- { "*courier new*", "cour", "FreeMono", "Oblique" },
- { "*courier*", "cour", "FreeMono", "Oblique" },
- { "*ZorkDeath*", "cour", "FreeMono", "Oblique" },
- { "*arial*", "arial", "FreeSans", "Oblique" },
- { "*ZorkNormal*", "arial", "FreeSans", "Oblique" },
- };
-
- Common::String newFontName;
- Common::String freeFontName;
-
- for (int i = 0; i < ARRAYSIZE(systemFonts); i++) {
- if (fontName.matchString(systemFonts[i].zorkFont, true)) {
- newFontName = systemFonts[i].fontBase;
- freeFontName = systemFonts[i].freeFontBase;
-
- if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
- newFontName += "bi";
- freeFontName += "Bold";
- freeFontName += systemFonts[i].freeFontItalicName;
- } else if (_style & STTF_BOLD) {
- newFontName += "bd";
- freeFontName += "Bold";
- } else if (_style & STTF_ITALIC) {
- newFontName += "i";
- freeFontName += systemFonts[i].freeFontItalicName;
- }
-
- newFontName += ".ttf";
- freeFontName += ".ttf";
- break;
- }
- }
-
- if (newFontName.empty()) {
- debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
- newFontName = "arial.ttf";
- freeFontName = "FreeSans.ttf";
- }
-
- bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
-
- Common::File file;
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "common/unzip.h"
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
+#include "graphics/surface.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/truetype_font.h"
+
+namespace ZVision {
+
+StyledTTFont::StyledTTFont(ZVision *engine) {
+ _engine = engine;
+ _style = 0;
+ _font = NULL;
+ _lineHeight = 0;
+}
+
+StyledTTFont::~StyledTTFont() {
+ if (_font)
+ delete _font;
+}
+
+bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
+ _style = style;
+ return loadFont(fontName, point);
+}
+
+bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
+ struct FontStyle {
+ const char *zorkFont;
+ const char *fontBase;
+ const char *freeFontBase;
+ const char *freeFontItalicName;
+ };
+
+ const FontStyle systemFonts[] = {
+ { "*times new roman*", "times", "FreeSerif", "Italic" },
+ { "*times*", "times", "FreeSerif", "Italic" },
+ { "*century schoolbook*", "censcbk", "FreeSerif", "Italic" },
+ { "*garamond*", "gara", "FreeSerif", "Italic" },
+ { "*courier new*", "cour", "FreeMono", "Oblique" },
+ { "*courier*", "cour", "FreeMono", "Oblique" },
+ { "*ZorkDeath*", "cour", "FreeMono", "Oblique" },
+ { "*arial*", "arial", "FreeSans", "Oblique" },
+ { "*ZorkNormal*", "arial", "FreeSans", "Oblique" },
+ };
+
+ Common::String newFontName;
+ Common::String freeFontName;
+
+ for (int i = 0; i < ARRAYSIZE(systemFonts); i++) {
+ if (fontName.matchString(systemFonts[i].zorkFont, true)) {
+ newFontName = systemFonts[i].fontBase;
+ freeFontName = systemFonts[i].freeFontBase;
+
+ if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
+ newFontName += "bi";
+ freeFontName += "Bold";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ } else if (_style & STTF_BOLD) {
+ newFontName += "bd";
+ freeFontName += "Bold";
+ } else if (_style & STTF_ITALIC) {
+ newFontName += "i";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ }
+
+ newFontName += ".ttf";
+ freeFontName += ".ttf";
+ break;
+ }
+ }
+
+ if (newFontName.empty()) {
+ debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
+ newFontName = "arial.ttf";
+ freeFontName = "FreeSans.ttf";
+ }
+
+ bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
+
+ Common::File file;
if (!file.open(newFontName) && !file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, newFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
- error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
-
- Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
- if (_newFont) {
- if (!_font)
- delete _font;
- _font = _newFont;
- }
-
- _fntName = fontName;
- _lineHeight = point;
-
- if (_font)
- return true;
- return false;
-}
-
-void StyledTTFont::setStyle(uint newStyle) {
- if ((_style & (STTF_BOLD | STTF_ITALIC | STTF_SHARP)) != (newStyle & (STTF_BOLD | STTF_ITALIC | STTF_SHARP))) {
- _style = newStyle;
- loadFont(_fntName, _lineHeight);
- } else {
- _style = newStyle;
- }
-}
-
-int StyledTTFont::getFontHeight() {
- if (_font)
- return _font->getFontHeight();
- return 0;
-}
-
-int StyledTTFont::getMaxCharWidth() {
- if (_font)
- return _font->getMaxCharWidth();
- return 0;
-}
-
-int StyledTTFont::getCharWidth(byte chr) {
- if (_font)
- return _font->getCharWidth(chr);
- return 0;
-}
-
-int StyledTTFont::getKerningOffset(byte left, byte right) {
- if (_font)
- return _font->getKerningOffset(left, right);
- return 0;
-}
-
-void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
- if (_font) {
- _font->drawChar(dst, chr, x, y, color);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- }
-}
-
-void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
- if (_font) {
- _font->drawString(dst, str, x, y, w, color, align);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- }
-}
-
-int StyledTTFont::getStringWidth(const Common::String &str) {
- if (_font)
- return _font->getStringWidth(str);
- return 0;
-}
-
-Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
- Graphics::Surface *tmp = new Graphics::Surface;
- if (_font) {
- int16 w = _font->getStringWidth(str);
- if (w && w < 1024) {
- tmp->create(w, _font->getFontHeight(), _engine->_resourcePixelFormat);
- drawString(tmp, str, 0, 0, w, color);
- }
- }
- return tmp;
-}
-
-} // End of namespace ZVision
+ error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
+
+ Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
+ if (_newFont) {
+ if (!_font)
+ delete _font;
+ _font = _newFont;
+ }
+
+ _fntName = fontName;
+ _lineHeight = point;
+
+ if (_font)
+ return true;
+ return false;
+}
+
+void StyledTTFont::setStyle(uint newStyle) {
+ if ((_style & (STTF_BOLD | STTF_ITALIC | STTF_SHARP)) != (newStyle & (STTF_BOLD | STTF_ITALIC | STTF_SHARP))) {
+ _style = newStyle;
+ loadFont(_fntName, _lineHeight);
+ } else {
+ _style = newStyle;
+ }
+}
+
+int StyledTTFont::getFontHeight() {
+ if (_font)
+ return _font->getFontHeight();
+ return 0;
+}
+
+int StyledTTFont::getMaxCharWidth() {
+ if (_font)
+ return _font->getMaxCharWidth();
+ return 0;
+}
+
+int StyledTTFont::getCharWidth(byte chr) {
+ if (_font)
+ return _font->getCharWidth(chr);
+ return 0;
+}
+
+int StyledTTFont::getKerningOffset(byte left, byte right) {
+ if (_font)
+ return _font->getKerningOffset(left, right);
+ return 0;
+}
+
+void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
+ if (_font) {
+ _font->drawChar(dst, chr, x, y, color);
+ if (_style & STTF_UNDERLINE) {
+ int16 pos = floor(_font->getFontHeight() * 0.87);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ if (_style & STTF_STRIKEOUT) {
+ int16 pos = floor(_font->getFontHeight() * 0.60);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ }
+}
+
+void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
+ if (_font) {
+ _font->drawString(dst, str, x, y, w, color, align);
+ if (_style & STTF_UNDERLINE) {
+ int16 pos = floor(_font->getFontHeight() * 0.87);
+ int16 wd = MIN(_font->getStringWidth(str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ if (_style & STTF_STRIKEOUT) {
+ int16 pos = floor(_font->getFontHeight() * 0.60);
+ int16 wd = MIN(_font->getStringWidth(str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ }
+}
+
+int StyledTTFont::getStringWidth(const Common::String &str) {
+ if (_font)
+ return _font->getStringWidth(str);
+ return 0;
+}
+
+Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
+ Graphics::Surface *tmp = new Graphics::Surface;
+ if (_font) {
+ int16 w = _font->getStringWidth(str);
+ if (w && w < 1024) {
+ tmp->create(w, _font->getFontHeight(), _engine->_resourcePixelFormat);
+ drawString(tmp, str, 0, 0, w, color);
+ }
+ }
+ return tmp;
+}
+
+} // End of namespace ZVision
--
cgit v1.2.3
From 976b4adb4e114c19e47efb3b18a52b1c1c1f44c4 Mon Sep 17 00:00:00 2001
From: Filippos Karapetis
Date: Fri, 2 Jan 2015 00:31:19 +0200
Subject: ZVISION: Add support for unmodified INQUIS.ZIX files
This will greatly help users copy the unmodified file from the game
CDs of ZGI and get the game working straight away
---
engines/zvision/file/search_manager.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/engines/zvision/file/search_manager.cpp b/engines/zvision/file/search_manager.cpp
index 7a907df39c..ec250ff648 100644
--- a/engines/zvision/file/search_manager.cpp
+++ b/engines/zvision/file/search_manager.cpp
@@ -169,8 +169,13 @@ void SearchManager::loadZix(const Common::String &name) {
line.trim();
if (line.matchString("----------*", true))
break;
- else if (line.matchString("DIR:*", true)) {
+ else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true)) {
Common::String path(line.c_str() + 5);
+ // Check if INQUIS.ZIX refers to the ZGI folder, and check the game
+ // root folder instead
+ if (path.hasPrefix("zgi\\"))
+ path = Common::String(path.c_str() + 4);
+
Common::Archive *arc;
char tempPath[128];
strcpy(tempPath, path.c_str());
--
cgit v1.2.3
From 34ec4ed6b51b81afa012543040951091ee1208ee Mon Sep 17 00:00:00 2001
From: Matthew Hoops
Date: Thu, 1 Jan 2015 17:36:12 -0500
Subject: ZVISION: Really fix truetype_font.cpp newlines
They are now all LF.
---
engines/zvision/text/truetype_font.cpp | 456 ++++++++++++++++-----------------
1 file changed, 228 insertions(+), 228 deletions(-)
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
index e378ccd127..622a02a6a8 100644
--- a/engines/zvision/text/truetype_font.cpp
+++ b/engines/zvision/text/truetype_font.cpp
@@ -1,228 +1,228 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-#include "common/config-manager.h"
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/system.h"
-#include "common/unzip.h"
-#include "graphics/font.h"
-#include "graphics/fonts/ttf.h"
-#include "graphics/surface.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/text/truetype_font.h"
-
-namespace ZVision {
-
-StyledTTFont::StyledTTFont(ZVision *engine) {
- _engine = engine;
- _style = 0;
- _font = NULL;
- _lineHeight = 0;
-}
-
-StyledTTFont::~StyledTTFont() {
- if (_font)
- delete _font;
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
- _style = style;
- return loadFont(fontName, point);
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
- struct FontStyle {
- const char *zorkFont;
- const char *fontBase;
- const char *freeFontBase;
- const char *freeFontItalicName;
- };
-
- const FontStyle systemFonts[] = {
- { "*times new roman*", "times", "FreeSerif", "Italic" },
- { "*times*", "times", "FreeSerif", "Italic" },
- { "*century schoolbook*", "censcbk", "FreeSerif", "Italic" },
- { "*garamond*", "gara", "FreeSerif", "Italic" },
- { "*courier new*", "cour", "FreeMono", "Oblique" },
- { "*courier*", "cour", "FreeMono", "Oblique" },
- { "*ZorkDeath*", "cour", "FreeMono", "Oblique" },
- { "*arial*", "arial", "FreeSans", "Oblique" },
- { "*ZorkNormal*", "arial", "FreeSans", "Oblique" },
- };
-
- Common::String newFontName;
- Common::String freeFontName;
-
- for (int i = 0; i < ARRAYSIZE(systemFonts); i++) {
- if (fontName.matchString(systemFonts[i].zorkFont, true)) {
- newFontName = systemFonts[i].fontBase;
- freeFontName = systemFonts[i].freeFontBase;
-
- if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
- newFontName += "bi";
- freeFontName += "Bold";
- freeFontName += systemFonts[i].freeFontItalicName;
- } else if (_style & STTF_BOLD) {
- newFontName += "bd";
- freeFontName += "Bold";
- } else if (_style & STTF_ITALIC) {
- newFontName += "i";
- freeFontName += systemFonts[i].freeFontItalicName;
- }
-
- newFontName += ".ttf";
- freeFontName += ".ttf";
- break;
- }
- }
-
- if (newFontName.empty()) {
- debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
- newFontName = "arial.ttf";
- freeFontName = "FreeSans.ttf";
- }
-
- bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
-
- Common::File file;
- if (!file.open(newFontName) && !file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, newFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
- error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
-
- Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
- if (_newFont) {
- if (!_font)
- delete _font;
- _font = _newFont;
- }
-
- _fntName = fontName;
- _lineHeight = point;
-
- if (_font)
- return true;
- return false;
-}
-
-void StyledTTFont::setStyle(uint newStyle) {
- if ((_style & (STTF_BOLD | STTF_ITALIC | STTF_SHARP)) != (newStyle & (STTF_BOLD | STTF_ITALIC | STTF_SHARP))) {
- _style = newStyle;
- loadFont(_fntName, _lineHeight);
- } else {
- _style = newStyle;
- }
-}
-
-int StyledTTFont::getFontHeight() {
- if (_font)
- return _font->getFontHeight();
- return 0;
-}
-
-int StyledTTFont::getMaxCharWidth() {
- if (_font)
- return _font->getMaxCharWidth();
- return 0;
-}
-
-int StyledTTFont::getCharWidth(byte chr) {
- if (_font)
- return _font->getCharWidth(chr);
- return 0;
-}
-
-int StyledTTFont::getKerningOffset(byte left, byte right) {
- if (_font)
- return _font->getKerningOffset(left, right);
- return 0;
-}
-
-void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
- if (_font) {
- _font->drawChar(dst, chr, x, y, color);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- }
-}
-
-void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
- if (_font) {
- _font->drawString(dst, str, x, y, w, color, align);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- }
-}
-
-int StyledTTFont::getStringWidth(const Common::String &str) {
- if (_font)
- return _font->getStringWidth(str);
- return 0;
-}
-
-Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
- Graphics::Surface *tmp = new Graphics::Surface;
- if (_font) {
- int16 w = _font->getStringWidth(str);
- if (w && w < 1024) {
- tmp->create(w, _font->getFontHeight(), _engine->_resourcePixelFormat);
- drawString(tmp, str, 0, 0, w, color);
- }
- }
- return tmp;
-}
-
-} // End of namespace ZVision
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "common/unzip.h"
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
+#include "graphics/surface.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/truetype_font.h"
+
+namespace ZVision {
+
+StyledTTFont::StyledTTFont(ZVision *engine) {
+ _engine = engine;
+ _style = 0;
+ _font = NULL;
+ _lineHeight = 0;
+}
+
+StyledTTFont::~StyledTTFont() {
+ if (_font)
+ delete _font;
+}
+
+bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
+ _style = style;
+ return loadFont(fontName, point);
+}
+
+bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
+ struct FontStyle {
+ const char *zorkFont;
+ const char *fontBase;
+ const char *freeFontBase;
+ const char *freeFontItalicName;
+ };
+
+ const FontStyle systemFonts[] = {
+ { "*times new roman*", "times", "FreeSerif", "Italic" },
+ { "*times*", "times", "FreeSerif", "Italic" },
+ { "*century schoolbook*", "censcbk", "FreeSerif", "Italic" },
+ { "*garamond*", "gara", "FreeSerif", "Italic" },
+ { "*courier new*", "cour", "FreeMono", "Oblique" },
+ { "*courier*", "cour", "FreeMono", "Oblique" },
+ { "*ZorkDeath*", "cour", "FreeMono", "Oblique" },
+ { "*arial*", "arial", "FreeSans", "Oblique" },
+ { "*ZorkNormal*", "arial", "FreeSans", "Oblique" },
+ };
+
+ Common::String newFontName;
+ Common::String freeFontName;
+
+ for (int i = 0; i < ARRAYSIZE(systemFonts); i++) {
+ if (fontName.matchString(systemFonts[i].zorkFont, true)) {
+ newFontName = systemFonts[i].fontBase;
+ freeFontName = systemFonts[i].freeFontBase;
+
+ if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
+ newFontName += "bi";
+ freeFontName += "Bold";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ } else if (_style & STTF_BOLD) {
+ newFontName += "bd";
+ freeFontName += "Bold";
+ } else if (_style & STTF_ITALIC) {
+ newFontName += "i";
+ freeFontName += systemFonts[i].freeFontItalicName;
+ }
+
+ newFontName += ".ttf";
+ freeFontName += ".ttf";
+ break;
+ }
+ }
+
+ if (newFontName.empty()) {
+ debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
+ newFontName = "arial.ttf";
+ freeFontName = "FreeSans.ttf";
+ }
+
+ bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
+
+ Common::File file;
+ if (!file.open(newFontName) && !file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, newFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
+ error("Unable to open font file %s (free alternative: %s)", newFontName.c_str(), freeFontName.c_str());
+
+ Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
+ if (_newFont) {
+ if (!_font)
+ delete _font;
+ _font = _newFont;
+ }
+
+ _fntName = fontName;
+ _lineHeight = point;
+
+ if (_font)
+ return true;
+ return false;
+}
+
+void StyledTTFont::setStyle(uint newStyle) {
+ if ((_style & (STTF_BOLD | STTF_ITALIC | STTF_SHARP)) != (newStyle & (STTF_BOLD | STTF_ITALIC | STTF_SHARP))) {
+ _style = newStyle;
+ loadFont(_fntName, _lineHeight);
+ } else {
+ _style = newStyle;
+ }
+}
+
+int StyledTTFont::getFontHeight() {
+ if (_font)
+ return _font->getFontHeight();
+ return 0;
+}
+
+int StyledTTFont::getMaxCharWidth() {
+ if (_font)
+ return _font->getMaxCharWidth();
+ return 0;
+}
+
+int StyledTTFont::getCharWidth(byte chr) {
+ if (_font)
+ return _font->getCharWidth(chr);
+ return 0;
+}
+
+int StyledTTFont::getKerningOffset(byte left, byte right) {
+ if (_font)
+ return _font->getKerningOffset(left, right);
+ return 0;
+}
+
+void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
+ if (_font) {
+ _font->drawChar(dst, chr, x, y, color);
+ if (_style & STTF_UNDERLINE) {
+ int16 pos = floor(_font->getFontHeight() * 0.87);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ if (_style & STTF_STRIKEOUT) {
+ int16 pos = floor(_font->getFontHeight() * 0.60);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ }
+}
+
+void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
+ if (_font) {
+ _font->drawString(dst, str, x, y, w, color, align);
+ if (_style & STTF_UNDERLINE) {
+ int16 pos = floor(_font->getFontHeight() * 0.87);
+ int16 wd = MIN(_font->getStringWidth(str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ if (_style & STTF_STRIKEOUT) {
+ int16 pos = floor(_font->getFontHeight() * 0.60);
+ int16 wd = MIN(_font->getStringWidth(str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ }
+}
+
+int StyledTTFont::getStringWidth(const Common::String &str) {
+ if (_font)
+ return _font->getStringWidth(str);
+ return 0;
+}
+
+Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
+ Graphics::Surface *tmp = new Graphics::Surface;
+ if (_font) {
+ int16 w = _font->getStringWidth(str);
+ if (w && w < 1024) {
+ tmp->create(w, _font->getFontHeight(), _engine->_resourcePixelFormat);
+ drawString(tmp, str, 0, 0, w, color);
+ }
+ }
+ return tmp;
+}
+
+} // End of namespace ZVision
--
cgit v1.2.3
From 0f11287b74664a509b85b30e722a1b706c0da0a7 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 00:16:46 +0100
Subject: ACCESS: MM - Fix the color of notes
---
engines/access/martian/martian_game.cpp | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index a14d7830b3..22a3c47928 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -82,6 +82,7 @@ void MartianEngine::sub13E1F() {
_screen->_orgY1 = 124;
_screen->_orgX2 = 297;
_screen->_orgY2 = 199;
+ _screen->_lColor = 51;
_screen->drawRect();
_events->showCursor();
@@ -103,15 +104,8 @@ void MartianEngine::sub13E4C(const Common::String &msg) {
int width = 0;
bool lastLine = false;
do {
- lastLine = _fonts._font2.getLine(lines, _screen->_maxChars * 6, line, width);
-
- // Set font colors
- _fonts._font2._fontColors[0] = 0;
- _fonts._font2._fontColors[1] = 27;
- _fonts._font2._fontColors[2] = 28;
- _fonts._font2._fontColors[3] = 29;
-
- _fonts._font2.drawString(_screen, line, _screen->_printOrg);
+ lastLine = _fonts._font1.getLine(lines, _screen->_maxChars * 6, line, width);
+ _fonts._font1.drawString(_screen, line, _screen->_printOrg);
_screen->_printOrg = Common::Point(_screen->_printStart.x, _screen->_printOrg.y + 6);
if (_screen->_printOrg.y == 196) {
--
cgit v1.2.3
From c3e20acdf2fe3e98fbd024cdedbc6c8bf00d9783 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 00:22:54 +0100
Subject: ACCESS: MM - Some renaming
---
engines/access/martian/martian_game.cpp | 10 +++++-----
engines/access/martian/martian_game.h | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index 22a3c47928..a4cc752c45 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -75,7 +75,7 @@ void MartianEngine::initVariables() {
_numAnimTimers = 0;
}
-void MartianEngine::sub13E1F() {
+void MartianEngine::setNoteParams() {
_events->hideCursor();
_screen->_orgX1 = 58;
@@ -88,7 +88,7 @@ void MartianEngine::sub13E1F() {
_events->showCursor();
}
-void MartianEngine::sub13E4C(const Common::String &msg) {
+void MartianEngine::displayNote(const Common::String &msg) {
_fonts._charSet._lo = 1;
_fonts._charSet._hi = 8;
_fonts._charFor._lo = 0;
@@ -97,7 +97,7 @@ void MartianEngine::sub13E4C(const Common::String &msg) {
_screen->_maxChars = 40;
_screen->_printOrg = _screen->_printStart = Common::Point(59, 124);
- sub13E1F();
+ setNoteParams();
Common::String lines = msg;
Common::String line;
@@ -110,7 +110,7 @@ void MartianEngine::sub13E4C(const Common::String &msg) {
if (_screen->_printOrg.y == 196) {
_events->waitKeyMouse();
- sub13E1F();
+ setNoteParams();
_screen->_printOrg = _screen->_printStart;
}
} while (!lastLine);
@@ -142,7 +142,7 @@ void MartianEngine::doSpecial5(int param1) {
while ((c = (char)_word20060->_stream->readByte()) != '\0')
msg += c;
- sub13E4C(msg);
+ displayNote(msg);
_midi->stopSong();
_midi->freeMusic();
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
index bd32527ffd..059644ce59 100644
--- a/engines/access/martian/martian_game.h
+++ b/engines/access/martian/martian_game.h
@@ -57,8 +57,8 @@ protected:
virtual void dead(int deathId) {}
- void sub13E1F();
- void sub13E4C(const Common::String &msg);
+ void setNoteParams();
+ void displayNote(const Common::String &msg);
public:
MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc);
--
cgit v1.2.3
From ef1165e8b5a9ec26b5bcaf365769d45b87d80c65 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 00:44:34 +0100
Subject: ACCESS: MM - More renaming
---
engines/access/martian/martian_game.cpp | 27 ++++++++++++++-------------
engines/access/martian/martian_game.h | 2 +-
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index a4cc752c45..8eea5d1a1c 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -133,13 +133,13 @@ void MartianEngine::doSpecial5(int param1) {
_screen->forceFadeIn();
warning("TODO: LoadCells");
_timers[20]._timer = _timers[20]._initTm = 30;
- Resource *_word20060 = _files->loadFile("NOTES.DAT");
- _word20060->_stream->skip(param1 * 2);
- int pos = _word20060->_stream->readUint16LE();
- _word20060->_stream->seek(pos);
+ Resource *_notesRes = _files->loadFile("NOTES.DAT");
+ _notesRes->_stream->skip(param1 * 2);
+ int pos = _notesRes->_stream->readUint16LE();
+ _notesRes->_stream->seek(pos);
Common::String msg = "";
byte c;
- while ((c = (char)_word20060->_stream->readByte()) != '\0')
+ while ((c = (char)_notesRes->_stream->readByte()) != '\0')
msg += c;
displayNote(msg);
@@ -161,10 +161,11 @@ void MartianEngine::playGame() {
if (_loadSaveSlot == -1) {
// Do introduction
-// doCredits();
+ doCredits();
if (shouldQuit())
return;
-
+
+ // Display Notes screen
doSpecial5(4);
if (shouldQuit())
return;
@@ -196,19 +197,19 @@ bool MartianEngine::showCredits() {
_screen->clearScreen();
_destIn = _screen;
- int val1 = _demoStream->readSint16LE();
+ int val1 = _creditsStream->readSint16LE();
int val2 = 0;
int val3 = 0;
while(val1 != -1) {
- val2 = _demoStream->readSint16LE();
- val3 = _demoStream->readSint16LE();
+ val2 = _creditsStream->readSint16LE();
+ val3 = _creditsStream->readSint16LE();
_screen->plotImage(_introObjects, val3, Common::Point(val1, val2));
- val1 = _demoStream->readSint16LE();
+ val1 = _creditsStream->readSint16LE();
}
- val2 = _demoStream->readSint16LE();
+ val2 = _creditsStream->readSint16LE();
if (val2 == -1) {
_events->showCursor();
_screen->forceFadeOut();
@@ -246,7 +247,7 @@ void MartianEngine::doCredits() {
_buffer2.copyFrom(*_screen);
_buffer1.copyFrom(*_screen);
_events->showCursor();
- _demoStream = new Common::MemoryReadStream(DEMO_DATA, 180);
+ _creditsStream = new Common::MemoryReadStream(DEMO_DATA, 180);
if (!showCredits()) {
_screen->copyFrom(_buffer2);
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
index 059644ce59..03f3e0f5fa 100644
--- a/engines/access/martian/martian_game.h
+++ b/engines/access/martian/martian_game.h
@@ -33,7 +33,7 @@ class MartianEngine : public AccessEngine {
private:
bool _skipStart;
SpriteResource *_introObjects;
- Common::MemoryReadStream *_demoStream;
+ Common::MemoryReadStream *_creditsStream;
/**
* Do the game introduction
*/
--
cgit v1.2.3
From 539497f009e5c1137017023212055bde6975ae6b Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 01:21:34 +0100
Subject: ACCESS: MM - Implement setManPalette
---
engines/access/martian/martian_room.cpp | 13 ++-----------
engines/access/screen.cpp | 4 ++++
engines/access/screen.h | 5 +++++
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp
index c4f38d8f99..10e9d60cca 100644
--- a/engines/access/martian/martian_room.cpp
+++ b/engines/access/martian/martian_room.cpp
@@ -57,12 +57,7 @@ void MartianRoom::reloadRoom() {
void MartianRoom::reloadRoom1() {
_selectCommand = -1;
-
-// CHECKME: Useful?
-// _vm->_events->setNormalCursor(CURSOR_CROSSHAIRS);
-// _vm->_mouseMode = 0;
-// _vm->_boxSelect = true;
-
+ warning("TODO: _word1F968 = -1;");
_vm->_player->_playerOff = false;
_vm->_screen->forceFadeOut();
@@ -83,11 +78,7 @@ void MartianRoom::reloadRoom1() {
buildScreen();
_vm->copyBF2Vid();
- //
- warning("TODO: setManPalette");
- Common::copy(_vm->_player->_manPal1 + 0x2A0, _vm->_player->_manPal1 + 0x2A0 + 0x42, _vm->_screen->_manPal);
- //
-
+ _vm->_screen->setManPalette();
_vm->_events->showCursor();
_vm->_player->_frame = 0;
_vm->_oldRects.clear();
diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp
index 35069ba683..ec2a825ba8 100644
--- a/engines/access/screen.cpp
+++ b/engines/access/screen.cpp
@@ -112,6 +112,10 @@ void Screen::setInitialPalettte() {
g_system->getPaletteManager()->setPalette(INITIAL_PALETTE, 0, 18);
}
+void Screen::setManPalette() {
+ Common::copy(_vm->_player->_manPal1 + 0x2A0, _vm->_player->_manPal1 + 0x2A0 + 0x42, _rawPalette + 672);
+}
+
void Screen::loadPalette(int fileNum, int subfile) {
Resource *res = _vm->_files->loadFile(fileNum, subfile);
byte *palette = res->data();
diff --git a/engines/access/screen.h b/engines/access/screen.h
index 0fa111c21c..dcf339a1d3 100644
--- a/engines/access/screen.h
+++ b/engines/access/screen.h
@@ -139,6 +139,11 @@ public:
*/
void setIconPalette() {}
+ /**
+ * Set Tex palette (Martian Memorandum)
+ */
+ void setManPalette();
+
void loadPalette(int fileNum, int subfile);
void setPalette();
--
cgit v1.2.3
From 900dc7ffc004d36ff02d38f0cc615098571c7b41 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 01:46:58 +0100
Subject: ACCESS: MM - Implement setIconPalette for MM
---
engines/access/martian/martian_game.cpp | 2 +-
engines/access/martian/martian_resources.cpp | 10 +++++++++-
engines/access/martian/martian_resources.h | 3 ++-
engines/access/screen.cpp | 8 +++++++-
engines/access/screen.h | 2 +-
5 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index 8eea5d1a1c..5fe035962c 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -247,7 +247,7 @@ void MartianEngine::doCredits() {
_buffer2.copyFrom(*_screen);
_buffer1.copyFrom(*_screen);
_events->showCursor();
- _creditsStream = new Common::MemoryReadStream(DEMO_DATA, 180);
+ _creditsStream = new Common::MemoryReadStream(CREDIT_DATA, 180);
if (!showCredits()) {
_screen->copyFrom(_buffer2);
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index 22a0cf1135..f46232977a 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -724,7 +724,7 @@ const int SIDEOFFL[] = { 11, 6, 1, 4, 10, 6, 1, 4, 0, 0, 0, 0 };
const int SIDEOFFU[] = { 1, 2, 0, 2, 2, 1, 1, 0, 0, 0, 0, 0 };
const int SIDEOFFD[] = { 2, 0, 1, 1, 0, 1, 1, 1, 2, 0, 0, 0 };
-const byte DEMO_DATA[] = {
+const byte CREDIT_DATA[] = {
0x1F, 0x00, 0x49, 0x00, 0x00, 0x00, 0xB7, 0x00, 0x49, 0x00,
0x01, 0x00, 0x79, 0x00, 0x6F, 0x00, 0x02, 0x00, 0xFF, 0xFF,
0xEA, 0x01, 0x75, 0x00, 0x46, 0x00, 0x03, 0x00, 0x46, 0x00,
@@ -745,6 +745,14 @@ const byte DEMO_DATA[] = {
0x0B, 0x00, 0xFF, 0xFF, 0xF4, 0x01, 0xFF, 0xFF, 0xFF, 0xFF
};
+const byte ICON_DATA[] = {
+ 0x3F, 0x3F, 0x00, 0x00, 0x07, 0x16,
+ 0x00, 0x0A, 0x1A, 0x00, 0x0D, 0x1F,
+ 0x00, 0x11, 0x28, 0x00, 0x15, 0x30,
+ 0x00, 0x19, 0x39, 0x00, 0x1B, 0x3F,
+ 0x00, 0x2D, 0x3A
+};
+
} // End of namespace Martian
} // End of namespace Access
diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h
index 67f8cb44a3..4a3f227455 100644
--- a/engines/access/martian/martian_resources.h
+++ b/engines/access/martian/martian_resources.h
@@ -50,7 +50,8 @@ extern const int SIDEOFFL[];
extern const int SIDEOFFU[];
extern const int SIDEOFFD[];
-extern const byte DEMO_DATA[];
+extern const byte CREDIT_DATA[];
+extern const byte ICON_DATA[];
} // End of namespace Martian
} // End of namespace Access
diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp
index ec2a825ba8..b7a2d3d1db 100644
--- a/engines/access/screen.cpp
+++ b/engines/access/screen.cpp
@@ -113,7 +113,13 @@ void Screen::setInitialPalettte() {
}
void Screen::setManPalette() {
- Common::copy(_vm->_player->_manPal1 + 0x2A0, _vm->_player->_manPal1 + 0x2A0 + 0x42, _rawPalette + 672);
+ Common::copy(_vm->_screen->_manPal, _vm->_screen->_manPal + 0x42, _rawPalette + 672);
+}
+
+void Screen::setIconPalette() {
+ if (_vm->getGameID() == GType_MartianMemorandum) {
+ Common::copy(Martian::ICON_DATA, Martian::ICON_DATA + 0x1B, _rawPalette + 741);
+ }
}
void Screen::loadPalette(int fileNum, int subfile) {
diff --git a/engines/access/screen.h b/engines/access/screen.h
index dcf339a1d3..a3b55855e7 100644
--- a/engines/access/screen.h
+++ b/engines/access/screen.h
@@ -137,7 +137,7 @@ public:
/**
* Set icon palette
*/
- void setIconPalette() {}
+ void setIconPalette();
/**
* Set Tex palette (Martian Memorandum)
--
cgit v1.2.3
From b2a4999f3cbf8808a10ffe5a4cbb1b536e0011d5 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 11:05:21 +0100
Subject: ACCESS: MM - Fix mouse cursor when y between 177 and 184, add a call
to takePicture (not yet implemented)
---
engines/access/martian/martian_room.cpp | 6 ++++++
engines/access/martian/martian_room.h | 3 +++
engines/access/room.cpp | 17 +++++++++++++----
engines/access/room.h | 2 ++
4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp
index 10e9d60cca..118679b2d8 100644
--- a/engines/access/martian/martian_room.cpp
+++ b/engines/access/martian/martian_room.cpp
@@ -91,6 +91,12 @@ void MartianRoom::roomSet() {
_vm->_scripts->_sequence = 1000;
_vm->_scripts->searchForSequence();
_vm->_scripts->executeScript();
+
+ for (int i = 0; i < 30; i++)
+ _byte26CD2[i] = 0;
+
+ for (int i = 0; i < 10; i++)
+ _byte26CBC[i] = 0;
}
void MartianRoom::roomMenu() {
diff --git a/engines/access/martian/martian_room.h b/engines/access/martian/martian_room.h
index cb2a8c2229..11501b6e57 100644
--- a/engines/access/martian/martian_room.h
+++ b/engines/access/martian/martian_room.h
@@ -39,6 +39,9 @@ private:
MartianEngine *_game;
void roomSet();
+
+ int _byte26CD2[30];
+ int _byte26CBC[10];
protected:
virtual void loadRoom(int roomNumber);
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index f7c2eabd0f..79e5200963 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -55,6 +55,10 @@ void Room::freeTileData() {
_tile = nullptr;
}
+void Room::takePicture() {
+ warning("TODO: takePicture");
+}
+
void Room::doRoom() {
bool reloadFlag = false;
@@ -84,9 +88,13 @@ void Room::doRoom() {
_vm->_events->pollEventsAndWait();
_vm->_canSaveLoad = false;
- _vm->_player->walk();
- _vm->_midi->midiRepeat();
- _vm->_player->checkScroll();
+ if ((_vm->getGameID() == GType_MartianMemorandum) && (_vm->_player->_roomNumber == 47)) {
+ takePicture();
+ } else {
+ _vm->_player->walk();
+ _vm->_midi->midiRepeat();
+ _vm->_player->checkScroll();
+ }
doCommands();
if (_vm->shouldQuitOrRestart())
@@ -136,7 +144,8 @@ void Room::doRoom() {
} else {
_vm->plotList();
- if (_vm->_events->_mousePos.y < 177)
+ if (((_vm->getGameID() == GType_MartianMemorandum) && (_vm->_events->_mousePos.y < 184)) ||
+ ((_vm->getGameID() == GType_Amazon) && (_vm->_events->_mousePos.y < 177)))
_vm->_events->setCursor(_vm->_events->_normalMouse);
else
_vm->_events->setCursor(CURSOR_ARROW);
diff --git a/engines/access/room.h b/engines/access/room.h
index 44279fa6b1..dd8a359665 100644
--- a/engines/access/room.h
+++ b/engines/access/room.h
@@ -72,6 +72,8 @@ private:
int calcLR(int yp);
int calcUD(int xp);
+ void takePicture();
+
/**
* Cycles forwards or backwards through the list of commands
*/
--
cgit v1.2.3
From f4a99656ceab94cfc1c75d34180a5a49dfd43c0f Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Fri, 2 Jan 2015 01:38:49 +0100
Subject: FULLPIPE: Fix bug with spring in scene04
---
engines/fullpipe/scenes/scene04.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index fd1ececdf2..6b3ddf9640 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -949,7 +949,7 @@ void sceneHandler04_springWobble() {
if (g_vars->scene04_bottleWeight < newdelta)
g_vars->scene04_springOffset--;
- if ((oldDynIndex > g_vars->scene04_bottleWeight && newdelta > g_vars->scene04_bottleWeight) || newdelta <= g_vars->scene04_bottleWeight) {
+ if ((oldDynIndex <= g_vars->scene04_bottleWeight && newdelta > g_vars->scene04_bottleWeight) || newdelta <= g_vars->scene04_bottleWeight) {
g_vars->scene04_springDelay++;
if (g_vars->scene04_springOffset && g_vars->scene04_springDelay > 1) {
--
cgit v1.2.3
From 76b71cabb9946b443afc803d04b1ca9e71cf5143 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Fri, 2 Jan 2015 13:10:04 +0100
Subject: FULLPIPE: Fix bug with unmovable jar in scene04
---
engines/fullpipe/scenes/scene04.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index 6b3ddf9640..4a87ae5b87 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -960,6 +960,8 @@ void sceneHandler04_springWobble() {
Common::Point point;
+ int oldpos = g_vars->scene04_spring->getCurrDimensions(point)->y - oldDynIndex;
+
if (g_vars->scene04_dynamicPhaseIndex) {
if (!g_vars->scene04_spring->_movement)
g_vars->scene04_spring->startAnim(MV_SPR_LOWER, 0, -1);
@@ -969,8 +971,9 @@ void sceneHandler04_springWobble() {
g_vars->scene04_spring->changeStatics2(ST_SPR_UP);
}
- if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex)
- sceneHandler04_bottleUpdateObjects(oldDynIndex - g_vars->scene04_dynamicPhaseIndex);
+ if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex) {
+ sceneHandler04_bottleUpdateObjects(oldpos - (g_vars->scene04_spring->getCurrDimensions(point)->y - g_vars->scene04_dynamicPhaseIndex));
+ }
}
void sceneHandler04_leaveScene() {
--
cgit v1.2.3
From f11032eb4e5591536b6565dcf7d7190777c868d8 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 21:34:48 +0100
Subject: ACCESS: MM - Fix menu position
---
engines/access/martian/martian_room.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp
index 118679b2d8..38361e519a 100644
--- a/engines/access/martian/martian_room.cpp
+++ b/engines/access/martian/martian_room.cpp
@@ -107,8 +107,8 @@ void MartianRoom::roomMenu() {
_vm->_screen->saveScreen();
_vm->_screen->setDisplayScan();
_vm->_destIn = _vm->_screen; // TODO: Redundant
- _vm->_screen->plotImage(spr, 0, Common::Point(0, 177));
- _vm->_screen->plotImage(spr, 1, Common::Point(143, 177));
+ _vm->_screen->plotImage(spr, 0, Common::Point(5, 184));
+ _vm->_screen->plotImage(spr, 1, Common::Point(155, 184));
_vm->_screen->restoreScreen();
delete spr;
--
cgit v1.2.3
From 56754c2a9d98ba41f97e0596fd0015f3edb07366 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 22:34:45 +0100
Subject: ACCESS: MM - Make RMOUSE game-specific
---
engines/access/amazon/amazon_logic.cpp | 2 +-
engines/access/amazon/amazon_resources.cpp | 7 ++++++-
engines/access/amazon/amazon_resources.h | 4 ++--
engines/access/martian/martian_resources.cpp | 6 +++++-
engines/access/martian/martian_resources.h | 5 ++++-
engines/access/resources.cpp | 5 -----
engines/access/resources.h | 2 --
engines/access/room.cpp | 23 ++++++++++++++++++++---
engines/access/room.h | 1 +
9 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index 436a875688..d24629a467 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -1591,7 +1591,7 @@ void River::moveCanoe() {
moveCanoe2();
} else {
if (events._leftButton && pt.y >= 140) {
- if (pt.x < RMOUSE[8][0]) {
+ if (pt.x < _vm->_room->_rMouse[8][0]) {
// Disk icon wasn't clicked
_vm->_scripts->printString(BAR_MESSAGE);
} else {
diff --git a/engines/access/amazon/amazon_resources.cpp b/engines/access/amazon/amazon_resources.cpp
index 2010c7d842..2b36ca943a 100644
--- a/engines/access/amazon/amazon_resources.cpp
+++ b/engines/access/amazon/amazon_resources.cpp
@@ -2406,6 +2406,11 @@ const int CAST_END_OBJ1[4][4] = {
{ 3, 103, 1300, 10 }
};
-} // End of namespace Amazon
+const int RMOUSE[10][2] = {
+ { 0, 35 }, { 0, 0 }, { 36, 70 }, { 71, 106 }, { 107, 141 },
+ { 142, 177 }, { 178, 212 }, { 213, 248 }, { 249, 283 }, { 284, 318 }
+};
+
+} // End of namespace Amazon
} // End of namespace Access
diff --git a/engines/access/amazon/amazon_resources.h b/engines/access/amazon/amazon_resources.h
index a952860bc2..190424b841 100644
--- a/engines/access/amazon/amazon_resources.h
+++ b/engines/access/amazon/amazon_resources.h
@@ -138,11 +138,11 @@ extern const int HELP1COORDS[2][4];
extern const int RIVER1OBJ[23][4];
extern const int CAST_END_OBJ[26][4];
-
extern const int CAST_END_OBJ1[4][4];
-} // End of namespace Amazon
+extern const int RMOUSE[10][2];
+} // End of namespace Amazon
} // End of namespace Access
#endif /* ACCESS_AMAZON_RESOURCES_H */
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index f46232977a..f460800a97 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -753,6 +753,10 @@ const byte ICON_DATA[] = {
0x00, 0x2D, 0x3A
};
-} // End of namespace Martian
+const int RMOUSE[10][2] = {
+ { 7, 36 }, { 38, 68 }, { 70, 99 }, { 102, 125 }, { 128, 152 },
+ { 155, 185 }, { 188, 216 }, { 219, 260 }, { 263, 293 }, { 295, 214 }
+};
+} // End of namespace Martian
} // End of namespace Access
diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h
index 4a3f227455..593681a48d 100644
--- a/engines/access/martian/martian_resources.h
+++ b/engines/access/martian/martian_resources.h
@@ -52,8 +52,11 @@ extern const int SIDEOFFD[];
extern const byte CREDIT_DATA[];
extern const byte ICON_DATA[];
-} // End of namespace Martian
+
+extern const int RMOUSE[10][2];
+
+} // End of namespace Martian
} // End of namespace Access
#endif /* ACCESS_MARTIAN_RESOURCES_H */
diff --git a/engines/access/resources.cpp b/engines/access/resources.cpp
index 4157cdfc0d..118e887721 100644
--- a/engines/access/resources.cpp
+++ b/engines/access/resources.cpp
@@ -59,11 +59,6 @@ const int DIAGOFFULY[] = { 3, 3, 1, 2, 2, 1, 1, 1, 0 };
const int DIAGOFFDLX[] = { 4, 5, 3, 3, 5, 4, 6, 1, 0 };
const int DIAGOFFDLY[] = { 2, 2, 1, 2, 3, 1, 2, 1, 0 };
-const int RMOUSE[10][2] = {
- { 0, 35 }, { 0, 0 }, { 36, 70 }, { 71, 106 }, { 107, 141 },
- { 142, 177 }, { 178, 212 }, { 213, 248 }, { 249, 283 }, { 284, 318 }
-};
-
const char *const LOOK_MESSAGE = "LOOKING THERE REVEALS NOTHING OF INTEREST.";
const char *const GET_MESSAGE = "YOU CAN'T TAKE THAT.";
const char *const OPEN_MESSAGE = "THAT DOESN'T OPEN.";
diff --git a/engines/access/resources.h b/engines/access/resources.h
index 8d59b1b1f1..2ef931b11a 100644
--- a/engines/access/resources.h
+++ b/engines/access/resources.h
@@ -42,8 +42,6 @@ extern const int DIAGOFFULY[];
extern const int DIAGOFFDLX[];
extern const int DIAGOFFDLY[];
-extern const int RMOUSE[10][2];
-
extern const char *const GENERAL_MESSAGES[];
extern const int INVCOORDS[][4];
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index 79e5200963..f10ba86a40 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -38,6 +38,23 @@ Room::Room(AccessEngine *vm) : Manager(vm) {
_selectCommand = 0;
_conFlag = false;
_selectCommand = -1;
+
+ switch (vm->getGameID()) {
+ case GType_Amazon:
+ for (int i = 0; i < 10; i++) {
+ _rMouse[i][0] = Amazon::RMOUSE[i][0];
+ _rMouse[i][1] = Amazon::RMOUSE[i][1];
+ }
+ break;
+ case GType_MartianMemorandum:
+ for (int i = 0; i < 10; i++) {
+ _rMouse[i][0] = Martian::RMOUSE[i][0];
+ _rMouse[i][1] = Martian::RMOUSE[i][1];
+ }
+ break;
+ default:
+ error("Game not supported");
+ }
}
Room::~Room() {
@@ -464,8 +481,8 @@ void Room::doCommands() {
if (_vm->_events->_mouseRow >= 22) {
// Mouse in user interface area
for (commandId = 0; commandId < 10; ++commandId) {
- if (_vm->_events->_mousePos.x >= RMOUSE[commandId][0] &&
- _vm->_events->_mousePos.x < RMOUSE[commandId][1])
+ if (_vm->_events->_mousePos.x >= _rMouse[commandId][0] &&
+ _vm->_events->_mousePos.x < _rMouse[commandId][1])
break;
}
if (commandId < 10)
@@ -564,7 +581,7 @@ void Room::executeCommand(int commandId) {
// Draw the button as selected
_vm->_screen->plotImage(spr, _selectCommand + 2,
- Common::Point(RMOUSE[_selectCommand][0], 176));
+ Common::Point(_rMouse[_selectCommand][0], (_vm->getGameID() == GType_MartianMemorandum) ? 184 : 176));
_vm->_screen->restoreScreen();
_vm->_boxSelect = true;
diff --git a/engines/access/room.h b/engines/access/room.h
index dd8a359665..2ecc1e8538 100644
--- a/engines/access/room.h
+++ b/engines/access/room.h
@@ -129,6 +129,7 @@ public:
int _tileSize;
int _selectCommand;
bool _conFlag;
+ int _rMouse[10][2];
public:
Room(AccessEngine *vm);
--
cgit v1.2.3
From 022b81bbc3e1cc20b88b6984c3ef94baaadea17f Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Fri, 2 Jan 2015 22:49:36 +0100
Subject: ACCESS: MM - Fix charMenu
---
engines/access/char.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/engines/access/char.cpp b/engines/access/char.cpp
index 49b8c2b082..01b3349c84 100644
--- a/engines/access/char.cpp
+++ b/engines/access/char.cpp
@@ -158,8 +158,14 @@ void CharManager::charMenu() {
screen.saveScreen();
screen.setDisplayScan();
- screen.plotImage(spr, 17, Common::Point(0, 176));
- screen.plotImage(spr, 18, Common::Point(155, 176));
+ if (_vm->getGameID() == GType_MartianMemorandum) {
+ screen.plotImage(spr, 17, Common::Point(0, 184));
+ screen.plotImage(spr, 18, Common::Point(193, 184));
+ } else if (_vm->getGameID() == GType_Amazon) {
+ screen.plotImage(spr, 17, Common::Point(0, 176));
+ screen.plotImage(spr, 18, Common::Point(155, 176));
+ } else
+ error("Game not supported");
screen.restoreScreen();
delete spr;
--
cgit v1.2.3
From 7e45ce9096eb86309e22ec0db966621f9d3b830c Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sat, 3 Jan 2015 10:25:05 +0100
Subject: ACCESS: MM - Make cmdTexSpeak game-dependent
---
engines/access/scripts.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index 2e22d9a2ce..0188457a5a 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -614,14 +614,18 @@ void Scripts::cmdCharSpeak() {
void Scripts::cmdTexSpeak() {
_vm->_screen->_printOrg = _texsOrg;
_vm->_screen->_printStart = _texsOrg;
- _vm->_screen->_maxChars = 20;
+ _vm->_screen->_maxChars = (_vm->getGameID() == GType_MartianMemorandum) ? 23 : 20;
byte v;
Common::String tmpStr = "";
while ((v = _data->readByte()) != 0)
tmpStr += (char)v;
- _vm->_bubbleBox->_bubbleDisplStr = Common::String("JASON");
+ if (_vm->getGameID() == GType_MartianMemorandum)
+ _vm->_bubbleBox->_bubbleDisplStr = Common::String("TEX");
+ else
+ _vm->_bubbleBox->_bubbleDisplStr = Common::String("JASON");
+
_vm->_bubbleBox->placeBubble1(tmpStr);
findNull();
}
--
cgit v1.2.3
From c3def28b9964066165b8627d0129578504734ab2 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sat, 3 Jan 2015 20:17:47 +0100
Subject: FULLPIPE: Fix crash in scene04
---
engines/fullpipe/mgm.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/engines/fullpipe/mgm.cpp b/engines/fullpipe/mgm.cpp
index aacfd5452a..1c8ca2a7b1 100644
--- a/engines/fullpipe/mgm.cpp
+++ b/engines/fullpipe/mgm.cpp
@@ -155,13 +155,14 @@ void MGM::rebuildTables(int objId) {
if (!obj)
return;
- for (uint i = 0; i < obj->_staticsList.size(); i++)
+ for (uint i = 0; i < obj->_staticsList.size(); i++) {
_items[idx]->statics.push_back((Statics *)obj->_staticsList[i]);
+ _items[idx]->subItems.push_back(new MGMSubItem);
+ }
+
for (uint i = 0; i < obj->_movements.size(); i++)
_items[idx]->movements1.push_back((Movement *)obj->_movements[i]);
-
- _items[idx]->subItems.clear();
}
int MGM::getItemIndexById(int objId) {
--
cgit v1.2.3
From ee9b60676a3efe015638763eed69161ee76ed846 Mon Sep 17 00:00:00 2001
From: Joel Teichroeb
Date: Sun, 4 Jan 2015 09:39:55 -0800
Subject: SDL: Warn if the selected joystick does not exist
---
backends/events/sdl/sdl-events.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 2480e7c370..284e0970fd 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -55,16 +55,18 @@ SdlEventSource::SdlEventSource()
memset(&_km, 0, sizeof(_km));
int joystick_num = ConfMan.getInt("joystick_num");
- if (joystick_num > -1) {
+ if (joystick_num >= 0) {
// Initialize SDL joystick subsystem
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
error("Could not initialize SDL: %s", SDL_GetError());
}
// Enable joystick
- if (SDL_NumJoysticks() > 0) {
- debug("Using joystick: %s", SDL_JoystickName(0));
+ if (SDL_NumJoysticks() > joystick_num) {
+ debug("Using joystick: %s", SDL_JoystickName(joystick_num));
_joystick = SDL_JoystickOpen(joystick_num);
+ } else {
+ warning("Invalid joystick: %d", joystick_num);
}
}
}
--
cgit v1.2.3
From 308bfe3b9cfda6ae2dd0558fcecfaa628e816b60 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 19:16:34 +0100
Subject: FULLPIPE: Remove redundant check
---
engines/fullpipe/scenes/scene16.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/fullpipe/scenes/scene16.cpp b/engines/fullpipe/scenes/scene16.cpp
index e9d3a37efd..df005950d2 100644
--- a/engines/fullpipe/scenes/scene16.cpp
+++ b/engines/fullpipe/scenes/scene16.cpp
@@ -182,7 +182,7 @@ void sceneHandler16_fillMug() {
mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
mq->replaceKeyCode(-1, g_vars->scene16_walkingBoy->_okeyCode);
- if (!mq || mq->chain(g_vars->scene16_walkingBoy))
+ if (mq->chain(g_vars->scene16_walkingBoy))
return;
} else {
if (!g_vars->scene16_walkingGirl)
--
cgit v1.2.3
From 4393d38a311df69f473febc5c2fdf135694609e9 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 19:18:41 +0100
Subject: FULLPIPE: Plug memory leak
---
engines/fullpipe/statics.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 880c2eb0df..6b35159fd1 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1048,8 +1048,11 @@ MessageQueue *StaticANIObject::changeStatics1(int msgNum) {
if (_flags & 1)
_messageQueueId = mq->_id;
} else {
- if (!queueMessageQueue(mq))
+ if (!queueMessageQueue(mq)) {
+ delete mq;
+
return 0;
+ }
g_fp->_globalMessageQueueList->addMessageQueue(mq);
}
--
cgit v1.2.3
From 882e0ca8cbc507cfba8dec1a340be9f5462069c3 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 19:23:43 +0100
Subject: FULLPIPE: Sanity check
---
engines/fullpipe/statics.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 6b35159fd1..de3e1ea728 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1597,6 +1597,12 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
newSize = src->_dynamicPhases.size();
}
+ if (!newSize) {
+ warning("Movement::Movement: newSize = 0");
+
+ return;
+ }
+
_framePosOffsets = (Common::Point **)calloc(newSize, sizeof(Common::Point *));
for (int i = 0; i < newSize; i++)
--
cgit v1.2.3
From 7da48233ce9a0154364bf26c1e419d24e70f2a26 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 19:32:26 +0100
Subject: FULLPIPE: Fix bug in inventory
---
engines/fullpipe/inventory.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index e79f9c54df..f9b507c50b 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -126,7 +126,7 @@ void Inventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int prio
int idx = getInventoryItemIndexById(itemId);
if (idx >= 0) {
- if (_inventoryItems[idx]->itemId >> 16) {
+ if (_inventoryItems[idx]->count) {
removeItem(itemId, 1);
Scene *sc = g_fp->accessScene(_sceneId);
--
cgit v1.2.3
From 5b19913eb83d7f82ac0d2a153e11db43e7e88616 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 20:22:04 +0100
Subject: CONFIGURE: define HAVE_INT64 when we have 64-bit types.
This has been hanging in the air forever, but for the sake of cleanness
now is defined.
---
configure | 1 +
1 file changed, 1 insertion(+)
diff --git a/configure b/configure
index eba1ebcb32..7c4c87e3af 100755
--- a/configure
+++ b/configure
@@ -4504,6 +4504,7 @@ $_def_64bit_type_unsigned
#else
$_def_64bit_type_unsigned
#endif
+#define HAVE_INT64
EOF
fi
--
cgit v1.2.3
From f1765db70fd7d1350e163a306a78ca293ef119cb Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 20:41:50 +0100
Subject: COMMON: Put all 64-bit code under new HAVE_INT64 constant
I regrouped all functions in order to make the code less noisy
with #ifdefs
---
common/endian.h | 126 ++++++++++++++++++++++++++++++++++----------------------
1 file changed, 77 insertions(+), 49 deletions(-)
diff --git a/common/endian.h b/common/endian.h
index a18e6f088b..70cc8b434f 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -49,7 +49,7 @@
# error No endianness defined
#endif
-
+#ifdef HAVE_INT64
#define SWAP_CONSTANT_64(a) \
((uint64)((((a) >> 56) & 0x000000FF) | \
(((a) >> 40) & 0x0000FF00) | \
@@ -59,6 +59,7 @@
(((a) & 0x00FF0000) << 24) | \
(((a) & 0x0000FF00) << 40) | \
(((a) & 0x000000FF) << 56) ))
+#endif
#define SWAP_CONSTANT_32(a) \
((uint32)((((a) >> 24) & 0x00FF) | \
@@ -70,6 +71,7 @@
((uint16)((((a) >> 8) & 0x00FF) | \
(((a) << 8) & 0xFF00) ))
+#ifdef HAVE_INT64
/**
* Swap the bytes in a 64 bit word in order to convert LE encoded data to BE
* and vice versa.
@@ -122,10 +124,11 @@
return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) |
(uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) |
(((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) |
- (uint16)((highHigh >> 8) | (highHigh << 8)))
+ (uint16)((highHigh >> 8) | (highHigh << 8)));
}
#endif
+#endif // HAVE_INT64
/**
* Swap the bytes in a 32 bit word in order to convert LE encoded data to BE
* and vice versa.
@@ -240,11 +243,6 @@
return ((const Unaligned32 *)ptr)->val;
}
- FORCEINLINE uint64 READ_UINT64(const void *ptr) {
- struct Unaligned64 { uint64 val; } __attribute__ ((__packed__, __may_alias__));
- return ((const Unaligned64 *)ptr)->val;
- }
-
FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__));
((Unaligned16 *)ptr)->val = value;
@@ -255,10 +253,17 @@
((Unaligned32 *)ptr)->val = value;
}
+#ifdef HAVE_INT64
+ FORCEINLINE uint64 READ_UINT64(const void *ptr) {
+ struct Unaligned64 { uint64 val; } __attribute__ ((__packed__, __may_alias__));
+ return ((const Unaligned64 *)ptr)->val;
+ }
+
FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
struct Unaligned64 { uint64 val; } __attribute__((__packed__, __may_alias__));
((Unaligned64 *)ptr)->val = value;
}
+#endif
#elif !defined(SCUMM_NEED_ALIGNMENT)
@@ -270,10 +275,6 @@
return *(const uint32 *)(ptr);
}
- FORCEINLINE uint64 READ_UINT64(const void *ptr) {
- return *(const uint64 *)(ptr);
- }
-
FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
@@ -282,9 +283,15 @@
*(uint32 *)(ptr) = value;
}
+#ifdef HAVE_INT64
+ FORCEINLINE uint64 READ_UINT64(const void *ptr) {
+ return *(const uint64 *)(ptr);
+ }
+
FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
*(uint64 *)(ptr) = value;
}
+#endif
// use software fallback by loading each byte explicitely
@@ -300,10 +307,6 @@
const uint8 *b = (const uint8 *)ptr;
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
}
- inline uint64 READ_UINT64(const void *ptr) {
- const uint8 *b = (const uint8 *)ptr;
- return (b[7] << 56) | (b[6] << 48) | (b[5] << 40) | (b[4] << 32) | (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
- }
inline void WRITE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 0);
@@ -316,6 +319,11 @@
b[2] = (uint8)(value >> 16);
b[3] = (uint8)(value >> 24);
}
+#ifdef HAVE_INT64
+ inline uint64 READ_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[7] << 56) | (b[6] << 48) | (b[5] << 40) | (b[4] << 32) | (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
+ }
inline void WRITE_UINT64(void *ptr, uint64 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 0);
@@ -327,6 +335,7 @@
b[6] = (uint8)(value >> 48);
b[7] = (uint8)(value >> 56);
}
+#endif
# elif defined(SCUMM_BIG_ENDIAN)
@@ -338,10 +347,6 @@
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
}
- inline uint64 READ_UINT64(const void *ptr) {
- const uint8 *b = (const uint8 *)ptr;
- return (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3] << 32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
- }
inline void WRITE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 8);
@@ -354,6 +359,11 @@
b[2] = (uint8)(value >> 8);
b[3] = (uint8)(value >> 0);
}
+#ifdef HAVE_INT64
+ inline uint64 READ_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3] << 32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
+ }
inline void WRITE_UINT64(void *ptr, uint64 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 56);
@@ -365,6 +375,7 @@
b[6] = (uint8)(value >> 8);
b[7] = (uint8)(value >> 0);
}
+#endif
# endif
@@ -376,36 +387,39 @@
#define READ_LE_UINT16(a) READ_UINT16(a)
#define READ_LE_UINT32(a) READ_UINT32(a)
- #define READ_LE_UINT64(a) READ_UINT64(a)
#define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v)
#define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v)
- #define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v)
- #define FROM_LE_64(a) ((uint64)(a))
#define FROM_LE_32(a) ((uint32)(a))
#define FROM_LE_16(a) ((uint16)(a))
- #define FROM_BE_64(a) SWAP_BYTES_64(a)
#define FROM_BE_32(a) SWAP_BYTES_32(a)
#define FROM_BE_16(a) SWAP_BYTES_16(a)
- #define TO_LE_64(a) ((uint64)(a))
#define TO_LE_32(a) ((uint32)(a))
#define TO_LE_16(a) ((uint16)(a))
- #define TO_BE_64(a) SWAP_BYTES_64(a)
#define TO_BE_32(a) SWAP_BYTES_32(a)
#define TO_BE_16(a) SWAP_BYTES_16(a)
- #define CONSTANT_LE_64(a) ((uint64)(a))
#define CONSTANT_LE_32(a) ((uint32)(a))
#define CONSTANT_LE_16(a) ((uint16)(a))
- #define CONSTANT_BE_64(a) SWAP_CONSTANT_64(a)
#define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a)
#define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a)
+#ifdef HAVE_INT64
+ #define READ_LE_UINT64(a) READ_UINT64(a)
+ #define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v)
+ #define FROM_LE_64(a) ((uint64)(a))
+ #define FROM_BE_64(a) SWAP_BYTES_64(a)
+ #define TO_LE_64(a) ((uint64)(a))
+ #define TO_BE_64(a) SWAP_BYTES_64(a)
+ #define CONSTANT_LE_64(a) ((uint64)(a))
+ #define CONSTANT_BE_64(a) SWAP_CONSTANT_64(a)
+#endif
+
// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
# if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
@@ -417,10 +431,6 @@
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
}
- inline uint64 READ_BE_UINT64(const void *ptr) {
- const uint8 *b = (const uint8 *)ptr;
- return (b[0] << 56) | b[1] << 48) | b[2] << 40) | b[3] << 32) | b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
- }
inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 8);
@@ -433,6 +443,11 @@
b[2] = (uint8)(value >> 8);
b[3] = (uint8)(value >> 0);
}
+#ifdef HAVE_INT64
+ inline uint64 READ_BE_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[0] << 56) | b[1] << 48) | b[2] << 40) | b[3] << 32) | b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
+ }
inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 56);
@@ -444,6 +459,8 @@
b[6] = (uint8)(value >> 8);
b[7] = (uint8)(value >> 0);
}
+#endif
+
# else
inline uint16 READ_BE_UINT16(const void *ptr) {
@@ -452,18 +469,20 @@
inline uint32 READ_BE_UINT32(const void *ptr) {
return SWAP_BYTES_32(READ_UINT32(ptr));
}
- inline uint32 READ_BE_UINT64(const void *ptr) {
- return SWAP_BYTES_64(READ_UINT64(ptr));
- }
inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
WRITE_UINT16(ptr, SWAP_BYTES_16(value));
}
inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
WRITE_UINT32(ptr, SWAP_BYTES_32(value));
}
+#ifdef HAVE_INT64
+ inline uint32 READ_BE_UINT64(const void *ptr) {
+ return SWAP_BYTES_64(READ_UINT64(ptr));
+ }
inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
WRITE_UINT64(ptr, SWAP_BYTES_64(value));
}
+#endif
# endif // if defined(SCUMM_NEED_ALIGNMENT)
@@ -471,36 +490,39 @@
#define READ_BE_UINT16(a) READ_UINT16(a)
#define READ_BE_UINT32(a) READ_UINT32(a)
- #define READ_BE_UINT64(a) READ_UINT64(a)
#define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v)
#define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v)
- #define WRITE_BE_UINT64(a, v) WRITE_UINT64(a, v)
- #define FROM_LE_64(a) SWAP_BYTES_64(a)
#define FROM_LE_32(a) SWAP_BYTES_32(a)
#define FROM_LE_16(a) SWAP_BYTES_16(a)
- #define FROM_BE_64(a) ((uint64)(a))
#define FROM_BE_32(a) ((uint32)(a))
#define FROM_BE_16(a) ((uint16)(a))
- #define TO_LE_64(a) SWAP_BYTES_64(a)
#define TO_LE_32(a) SWAP_BYTES_32(a)
#define TO_LE_16(a) SWAP_BYTES_16(a)
- #define TO_BE_64(a) ((uint64)(a))
#define TO_BE_32(a) ((uint32)(a))
#define TO_BE_16(a) ((uint16)(a))
- #define CONSTANT_LE_64(a) SWAP_CONSTANT_64(a)
#define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a)
#define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a)
- #define CONSTANT_BE_64(a) ((uint64)(a))
#define CONSTANT_BE_32(a) ((uint32)(a))
#define CONSTANT_BE_16(a) ((uint16)(a))
+#ifdef HAVE_INT64
+ #define READ_BE_UINT64(a) READ_UINT64(a)
+ #define WRITE_BE_UINT64(a, v) WRITE_UINT64(a, v)
+ #define FROM_LE_64(a) SWAP_BYTES_64(a)
+ #define FROM_BE_64(a) ((uint64)(a))
+ #define TO_LE_64(a) SWAP_BYTES_64(a)
+ #define TO_BE_64(a) ((uint64)(a))
+ #define CONSTANT_LE_64(a) SWAP_CONSTANT_64(a)
+ #define CONSTANT_BE_64(a) ((uint64)(a))
+#endif
+
// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
# if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
@@ -512,10 +534,6 @@
const uint8 *b = (const uint8 *)ptr;
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
}
- inline uint64 READ_LE_UINT64(const void *ptr) {
- const uint8 *b = (const uint8 *)ptr;
- return (b[7] << 56) | (b[6] << 48) | (b[5] << 40) | (b[4] << 32) | (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
- }
inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 0);
@@ -528,6 +546,12 @@
b[2] = (uint8)(value >> 16);
b[3] = (uint8)(value >> 24);
}
+
+#ifdef HAVE_INT64
+ inline uint64 READ_LE_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return (b[7] << 56) | (b[6] << 48) | (b[5] << 40) | (b[4] << 32) | (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
+ }
inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 0);
@@ -539,6 +563,8 @@
b[6] = (uint8)(value >> 48);
b[7] = (uint8)(value >> 56);
}
+#endif
+
# else
inline uint16 READ_LE_UINT16(const void *ptr) {
@@ -547,18 +573,20 @@
inline uint32 READ_LE_UINT32(const void *ptr) {
return SWAP_BYTES_32(READ_UINT32(ptr));
}
- inline uint64 READ_LE_UINT64(const void *ptr) {
- return SWAP_BYTES_64(READ_UINT64(ptr));
- }
inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
WRITE_UINT16(ptr, SWAP_BYTES_16(value));
}
inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
WRITE_UINT32(ptr, SWAP_BYTES_32(value));
}
+#ifdef HAVE_INT64
+ inline uint64 READ_LE_UINT64(const void *ptr) {
+ return SWAP_BYTES_64(READ_UINT64(ptr));
+ }
inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
WRITE_UINT64(ptr, SWAP_BYTES_64(value));
}
+#endif
# endif // if defined(SCUMM_NEED_ALIGNMENT)
--
cgit v1.2.3
From 7865c7821140a2b83a1473c66e90644cbf39a2c9 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 20:47:12 +0100
Subject: COMMON: Put more 64-bit stuff under HAVE_INT64
---
common/stream.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/common/stream.h b/common/stream.h
index 251995001c..3021df304c 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -125,10 +125,12 @@ public:
write(&value, 4);
}
+#ifdef HAVE_INT64
void writeUint64LE(uint64 value) {
value = TO_LE_64(value);
write(&value, 8);
}
+#endif
void writeUint16BE(uint16 value) {
value = TO_BE_16(value);
@@ -140,10 +142,12 @@ public:
write(&value, 4);
}
+#ifdef HAVE_INT64
void writeUint64BE(uint64 value) {
value = TO_BE_64(value);
write(&value, 8);
}
+#endif
FORCEINLINE void writeSint16LE(int16 value) {
writeUint16LE((uint16)value);
@@ -153,9 +157,11 @@ public:
writeUint32LE((uint32)value);
}
+#ifdef HAVE_INT64
FORCEINLINE void writeSint64LE(int64 value) {
writeUint64LE((uint64)value);
}
+#endif
FORCEINLINE void writeSint16BE(int16 value) {
writeUint16BE((uint16)value);
@@ -165,9 +171,11 @@ public:
writeUint32BE((uint32)value);
}
+#ifdef HAVE_INT64
FORCEINLINE void writeSint64BE(int64 value) {
writeUint64BE((uint64)value);
}
+#endif
/**
* Write the given string to the stream.
@@ -259,6 +267,7 @@ public:
return FROM_LE_32(val);
}
+#ifdef HAVE_INT64
/**
* Read an unsigned 64-bit word stored in little endian (LSB first) order
* from the stream and return it.
@@ -271,6 +280,7 @@ public:
read(&val, 8);
return FROM_LE_64(val);
}
+#endif
/**
* Read an unsigned 16-bit word stored in big endian (MSB first) order
@@ -298,6 +308,7 @@ public:
return FROM_BE_32(val);
}
+#ifdef HAVE_INT64
/**
* Read an unsigned 64-bit word stored in big endian (MSB first) order
* from the stream and return it.
@@ -310,6 +321,7 @@ public:
read(&val, 8);
return FROM_BE_64(val);
}
+#endif
/**
* Read a signed 16-bit word stored in little endian (LSB first) order
@@ -333,6 +345,7 @@ public:
return (int32)readUint32LE();
}
+#ifdef HAVE_INT64
/**
* Read a signed 64-bit word stored in little endian (LSB first) order
* from the stream and return it.
@@ -343,6 +356,7 @@ public:
FORCEINLINE int64 readSint64LE() {
return (int64)readUint64LE();
}
+#endif
/**
* Read a signed 16-bit word stored in big endian (MSB first) order
@@ -366,6 +380,7 @@ public:
return (int32)readUint32BE();
}
+#ifdef HAVE_INT64
/**
* Read a signed 64-bit word stored in big endian (MSB first) order
* from the stream and return it.
@@ -376,6 +391,7 @@ public:
FORCEINLINE int64 readSint64BE() {
return (int64)readUint64BE();
}
+#endif
/**
* Read the specified amount of data into a malloc'ed buffer
--
cgit v1.2.3
From ce45caaf83cae5990416aa2d6e833f309f7ce5c0 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 21:06:49 +0100
Subject: SWORD25: Fix warning
---
engines/sword25/util/lua_persist.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
index 6fe88fe9a3..03f305b2c5 100644
--- a/engines/sword25/util/lua_persist.cpp
+++ b/engines/sword25/util/lua_persist.cpp
@@ -645,8 +645,7 @@ static void persistProto(SerializationInfo *info) {
// Serialize inner Proto refs
info->writeStream->writeSint32LE(proto->sizep);
- for (int i = 0; i < proto->sizep; ++i)
- {
+ for (int i = 0; i < proto->sizep; ++i) {
pushProto(info->luaState, proto->p[i]);
// >>>>> permTbl indexTbl ...... proto subProto */
@@ -668,8 +667,7 @@ static void persistProto(SerializationInfo *info) {
// Serialize upvalue names
info->writeStream->writeSint32LE(proto->sizeupvalues);
- for (int i = 0; i < proto->sizeupvalues; ++i)
- {
+ for (int i = 0; i < proto->sizeupvalues; ++i) {
pushString(info->luaState, proto->upvalues[i]);
// >>>>> permTbl indexTbl ...... proto str
@@ -710,7 +708,7 @@ static void persistProto(SerializationInfo *info) {
info->writeStream->writeSint32LE(proto->sizelineinfo);
if (proto->sizelineinfo) {
- uint32 len = static_cast(sizeof(int) * proto->sizelineinfo);
+ len = static_cast(sizeof(int) * proto->sizelineinfo);
info->writeStream->write(proto->lineinfo, len);
}
--
cgit v1.2.3
From f1e58efe90e2c3ae6740a41db4642b3e47c0c81f Mon Sep 17 00:00:00 2001
From: Johannes Schickel
Date: Sun, 4 Jan 2015 20:55:01 +0100
Subject: TEST: Fix C++11 compat warnings.
---
test/common/endian.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/common/endian.h b/test/common/endian.h
index f083d1248c..08e93e41ef 100644
--- a/test/common/endian.h
+++ b/test/common/endian.h
@@ -11,13 +11,13 @@ class EndianTestSuite : public CxxTest::TestSuite
}
void test_READ_BE_UINT64() {
- const char data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
+ const byte data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
uint64 value = READ_BE_UINT64(data);
TS_ASSERT_EQUALS(value, 0x123456789ABCDEFFULL);
}
void test_READ_LE_UINT64() {
- const char data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
+ const byte data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
uint64 value = READ_LE_UINT64(data);
TS_ASSERT_EQUALS(value, 0xFFEDCBA978563412ULL);
}
--
cgit v1.2.3
From eb4d1a69255b06f93c497aabd9cf950bfe0756ec Mon Sep 17 00:00:00 2001
From: Johannes Schickel
Date: Sun, 4 Jan 2015 21:07:36 +0100
Subject: COMMON: Add missing readUint64/readSint64 to ReadStreamEndian.
---
common/stream.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/common/stream.h b/common/stream.h
index 3021df304c..abe5192b70 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -517,6 +517,14 @@ public:
return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val);
}
+#ifdef HAVE_INT64
+ uint64 readUint64() {
+ uint64 val;
+ read(&val, 8);
+ return (_bigEndian) ? TO_BE_64(val) : TO_LE_64(val);
+ }
+#endif
+
FORCEINLINE int16 readSint16() {
return (int16)readUint16();
}
@@ -524,6 +532,12 @@ public:
FORCEINLINE int32 readSint32() {
return (int32)readUint32();
}
+
+#ifdef HAVE_INT64
+ FORCEINLINE int64 readSint64() {
+ return (int64)readUint64();
+ }
+#endif
};
/**
--
cgit v1.2.3
From daa8fca001c0eddd5b0856d60aa7ecd59c7d6acc Mon Sep 17 00:00:00 2001
From: Johannes Schickel
Date: Sun, 4 Jan 2015 20:58:19 +0100
Subject: TEST: Fix uint64 endian related test code.
This does not fix the actual implementation issues which are present right
now!
---
test/common/endian.h | 2 +-
test/common/memoryreadstreamendian.h | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/common/endian.h b/test/common/endian.h
index 08e93e41ef..065b6997fc 100644
--- a/test/common/endian.h
+++ b/test/common/endian.h
@@ -19,7 +19,7 @@ class EndianTestSuite : public CxxTest::TestSuite
void test_READ_LE_UINT64() {
const byte data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
uint64 value = READ_LE_UINT64(data);
- TS_ASSERT_EQUALS(value, 0xFFEDCBA978563412ULL);
+ TS_ASSERT_EQUALS(value, 0xFFDEBC9A78563412ULL);
}
void test_READ_BE_UINT32() {
diff --git a/test/common/memoryreadstreamendian.h b/test/common/memoryreadstreamendian.h
index 515128ea2a..c25ec29e1a 100644
--- a/test/common/memoryreadstreamendian.h
+++ b/test/common/memoryreadstreamendian.h
@@ -82,7 +82,7 @@ class MemoryReadStreamEndianTestSuite : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.readUint64BE(), 0x0708090A0B0C0D0EULL);
TS_ASSERT_EQUALS(ms.pos(), 14);
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
TS_ASSERT_EQUALS(ms.pos(), 15);
@@ -97,7 +97,7 @@ class MemoryReadStreamEndianTestSuite : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32(), 0x06050403UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
+ TS_ASSERT_EQUALS(ms.readUint64(), 0x0E0D0C0B0A090807ULL);
TS_ASSERT_EQUALS(ms.pos(), 14);
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
TS_ASSERT_EQUALS(ms.pos(), 15);
@@ -112,7 +112,7 @@ class MemoryReadStreamEndianTestSuite : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.readUint64(), 0x0708090A0B0C0D0EULL);
TS_ASSERT_EQUALS(ms.pos(), 14);
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
TS_ASSERT_EQUALS(ms.pos(), 15);
--
cgit v1.2.3
From 64bad2ec4a2bfe9d607883ca06df03279ba83943 Mon Sep 17 00:00:00 2001
From: Johannes Schickel
Date: Sun, 4 Jan 2015 21:17:33 +0100
Subject: COMMON: Fix some syntax issues.
Not compile tested. Then again it didn't look test before either. So, yay!
---
common/endian.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/endian.h b/common/endian.h
index 70cc8b434f..21e0d9ee11 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -446,7 +446,7 @@
#ifdef HAVE_INT64
inline uint64 READ_BE_UINT64(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
- return (b[0] << 56) | b[1] << 48) | b[2] << 40) | b[3] << 32) | b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
+ return (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3] << 32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
}
inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
uint8 *b = (uint8 *)ptr;
--
cgit v1.2.3
From ba228f2bea145f6f8c6d575affc8efac4ed5e87f Mon Sep 17 00:00:00 2001
From: Johannes Schickel
Date: Sun, 4 Jan 2015 21:22:43 +0100
Subject: TEST: Fix another typo in uint64 endian tests.
---
test/common/memoryreadstream.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/common/memoryreadstream.h b/test/common/memoryreadstream.h
index 79c4079e9b..3e1472f408 100644
--- a/test/common/memoryreadstream.h
+++ b/test/common/memoryreadstream.h
@@ -82,7 +82,7 @@ class MemoryReadStreamTestSuite : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.readUint64BE(), 0x0708090A0B0C0D0EULL);
TS_ASSERT_EQUALS(ms.pos(), 14);
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
TS_ASSERT_EQUALS(ms.pos(), 15);
--
cgit v1.2.3
From e2e61184c6c75554702721434920d0e5772976cf Mon Sep 17 00:00:00 2001
From: Johannes Schickel
Date: Sun, 4 Jan 2015 21:30:05 +0100
Subject: COMMON: Fix return type of one READ_BE_UINT64 implementation.
This makes all unit tests pass for my on amd64 again. Thanks clone2727.
---
common/endian.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/endian.h b/common/endian.h
index 21e0d9ee11..9a6c0cd42c 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -476,7 +476,7 @@
WRITE_UINT32(ptr, SWAP_BYTES_32(value));
}
#ifdef HAVE_INT64
- inline uint32 READ_BE_UINT64(const void *ptr) {
+ inline uint64 READ_BE_UINT64(const void *ptr) {
return SWAP_BYTES_64(READ_UINT64(ptr));
}
inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
--
cgit v1.2.3
From fa07048bc4be0339b45d650873643f941aee96b2 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Sun, 4 Jan 2015 21:38:37 +0100
Subject: ACCESS: Improve the use of _establishTable as a boolean
---
engines/access/room.cpp | 4 ++--
engines/access/scripts.cpp | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index f10ba86a40..fa0c0c4510 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -199,8 +199,8 @@ void Room::loadRoomData(const byte *roomData) {
_vm->_establishFlag = false;
if (roomInfo._estIndex != -1) {
_vm->_establishFlag = true;
- if (_vm->_establishTable[roomInfo._estIndex] != 1) {
- _vm->_establishTable[roomInfo._estIndex] = 1;
+ if (!_vm->_establishTable[roomInfo._estIndex]) {
+ _vm->_establishTable[roomInfo._estIndex] = true;
_vm->establish(0, roomInfo._estIndex);
}
}
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index 0188457a5a..a74cc7b12e 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -572,7 +572,7 @@ void Scripts::cmdSpecial() {
int p2 = _data->readUint16LE();
if (_specialFunction == 1) {
- if (_vm->_establishTable[p2] == 1)
+ if (_vm->_establishTable[p2])
return;
_vm->_screen->savePalette();
--
cgit v1.2.3
From 7c7bdf3543ee198b4dfbb06c9a95ea387342b56d Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sun, 4 Jan 2015 21:49:56 +0100
Subject: COMMON: Swap order of functions to 16, 32, 64
---
common/endian.h | 101 +++++++++++++++++++++++++++++---------------------------
1 file changed, 53 insertions(+), 48 deletions(-)
diff --git a/common/endian.h b/common/endian.h
index 9a6c0cd42c..9f10b63053 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -71,64 +71,36 @@
((uint16)((((a) >> 8) & 0x00FF) | \
(((a) << 8) & 0xFF00) ))
-#ifdef HAVE_INT64
+
+
/**
- * Swap the bytes in a 64 bit word in order to convert LE encoded data to BE
+ * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
* and vice versa.
*/
-// machine/compiler-specific variants come first, fallback last
+// compilerspecific variants come first, fallback last
// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
-//
-// TODO: Fix this #if statement. It isn't changed from 32 bit. Is there a 64 bit swap instruction?
#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
- FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) {
+ FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
if (__builtin_constant_p(a)) {
- return SWAP_CONSTANT_32(a);
+ return SWAP_CONSTANT_16(a);
} else {
- uint32 result;
-# if defined(__psp__)
- // use special allegrex instruction
- __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
-# else
- __asm__ ("wsbh %0,%1\n"
- "rotr %0,%0,16" : "=r" (result) : "r" (a));
-# endif
+ uint16 result;
+ __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
return result;
}
}
-
-// Test for GCC >= 4.3.0 as this version added the bswap builtin
-#elif GCC_ATLEAST(4, 3)
-
- FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
- return __builtin_bswap64(a);
- }
-
-#elif defined(_MSC_VER)
-
- FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
- return _byteswap_uint64(a);
- }
-
-// generic fallback
#else
- inline uint64 SWAP_BYTES_64(uint64 a) {
- uint32 low = (uint32)a, high = (uint32)(a >> 32);
- uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16),
- highLow = (uint16)high, highHigh = (uint16)(high >> 16);
-
- return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) |
- (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) |
- (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) |
- (uint16)((highHigh >> 8) | (highHigh << 8)));
+ inline uint16 SWAP_BYTES_16(const uint16 a) {
+ return (a >> 8) | (a << 8);
}
#endif
-#endif // HAVE_INT64
+
+
/**
* Swap the bytes in a 32 bit word in order to convert LE encoded data to BE
* and vice versa.
@@ -178,32 +150,65 @@
}
#endif
+#ifdef HAVE_INT64
/**
- * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
+ * Swap the bytes in a 64 bit word in order to convert LE encoded data to BE
* and vice versa.
*/
-// compilerspecific variants come first, fallback last
+// machine/compiler-specific variants come first, fallback last
// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
+//
+// TODO: Fix this #if statement. It isn't changed from 32 bit. Is there a 64 bit swap instruction?
#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
- FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
+ FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) {
if (__builtin_constant_p(a)) {
- return SWAP_CONSTANT_16(a);
+ return SWAP_CONSTANT_32(a);
} else {
- uint16 result;
- __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
+ uint32 result;
+# if defined(__psp__)
+ // use special allegrex instruction
+ __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
+# else
+ __asm__ ("wsbh %0,%1\n"
+ "rotr %0,%0,16" : "=r" (result) : "r" (a));
+# endif
return result;
}
}
+
+// Test for GCC >= 4.3.0 as this version added the bswap builtin
+#elif GCC_ATLEAST(4, 3)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return __builtin_bswap64(a);
+ }
+
+#elif defined(_MSC_VER)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return _byteswap_uint64(a);
+ }
+
+// generic fallback
#else
- inline uint16 SWAP_BYTES_16(const uint16 a) {
- return (a >> 8) | (a << 8);
+ inline uint64 SWAP_BYTES_64(uint64 a) {
+ uint32 low = (uint32)a, high = (uint32)(a >> 32);
+ uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16),
+ highLow = (uint16)high, highHigh = (uint16)(high >> 16);
+
+ return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) |
+ (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) |
+ (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) |
+ (uint16)((highHigh >> 8) | (highHigh << 8)));
}
#endif
+#endif // HAVE_INT64
+
/**
* A wrapper macro used around four character constants, like 'DATA', to
--
cgit v1.2.3
From 1084f2eea67d3a7f2293392af0c7a2c1d97b1b2b Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn
Date: Sun, 4 Jan 2015 21:54:11 +0100
Subject: COMMON: Implement MIPS SWAP_BYTES_64 in terms of SWAP_BYTES_32
---
common/endian.h | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/common/endian.h b/common/endian.h
index 9f10b63053..0c6b3db621 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -160,22 +160,17 @@
// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
//
-// TODO: Fix this #if statement. It isn't changed from 32 bit. Is there a 64 bit swap instruction?
#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
- FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) {
+ FORCEINLINE uint64 SWAP_BYTES_64(const uint64 a) {
if (__builtin_constant_p(a)) {
- return SWAP_CONSTANT_32(a);
+ return SWAP_CONSTANT_64(a);
} else {
- uint32 result;
-# if defined(__psp__)
- // use special allegrex instruction
- __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
-# else
- __asm__ ("wsbh %0,%1\n"
- "rotr %0,%0,16" : "=r" (result) : "r" (a));
-# endif
- return result;
+ uint32 low = (uint32)a, high = (uint32)(a >> 32);
+ low = SWAP_BYTES_32(low);
+ high = SWAP_BYTES_32(high);
+
+ return (((uint64)low) << 32) | high;
}
}
--
cgit v1.2.3
From 17fe53a34c442da7ccf28721179a88ed2087f7b2 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 22:09:46 +0100
Subject: SWORD25: Hopefully fix compilation errors
---
engines/sword25/util/double_serialization.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/engines/sword25/util/double_serialization.cpp b/engines/sword25/util/double_serialization.cpp
index 48fd75cb33..0d41ddc503 100644
--- a/engines/sword25/util/double_serialization.cpp
+++ b/engines/sword25/util/double_serialization.cpp
@@ -77,13 +77,13 @@ uint64 encodeDouble_64(double value) {
uint64 uintsignificand = (uint64)shiftedsignificand;
return ((uint64)(value < 0 ? 1 : 0) << 63) | // Sign
((uint64)(exponent + 1023) << 52) | // Exponent stored as an offset to 1023
- (uintsignificand & 0x000FFFFFFFFFFFFF); // significand with MSB inferred
+ (uintsignificand & 0x000FFFFFFFFFFFFFLL); // significand with MSB inferred
}
double decodeDouble_64(uint64 value) {
// Expand the exponent and significand
int exponent = (int)((value >> 52) & 0x7FF) - 1023;
- double expandedsignificand = (double)(0x10000000000000 /* Inferred MSB */ | (value & 0x000FFFFFFFFFFFFF));
+ double expandedsignificand = (double)(0x10000000000000LL /* Inferred MSB */ | (value & 0x000FFFFFFFFFFFFFLL));
// Deflate the significand
int temp;
@@ -93,7 +93,7 @@ double decodeDouble_64(uint64 value) {
double returnValue = ldexp(significand, exponent);
// Check the sign bit and return
- return ((value & 0x8000000000000000) == 0x8000000000000000) ? -returnValue : returnValue;
+ return ((value & 0x8000000000000000LL) == 0x8000000000000000LL) ? -returnValue : returnValue;
}
CompactSerializedDouble encodeDouble_Compact(double value) {
--
cgit v1.2.3
From baacf0be61cf8f31a72b593d320c62393241e951 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 22:16:50 +0100
Subject: SWORD25: Commend unused and unportable functions
---
engines/sword25/util/double_serialization.cpp | 6 ++++++
engines/sword25/util/double_serialization.h | 3 +++
2 files changed, 9 insertions(+)
diff --git a/engines/sword25/util/double_serialization.cpp b/engines/sword25/util/double_serialization.cpp
index 0d41ddc503..a34eb0fbff 100644
--- a/engines/sword25/util/double_serialization.cpp
+++ b/engines/sword25/util/double_serialization.cpp
@@ -65,6 +65,10 @@ double decodeDouble(SerializedDouble value) {
return ((value.signAndSignificandTwo & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
}
+#if 0
+
+// Why these are needed?
+
uint64 encodeDouble_64(double value) {
// Split the value into its significand and exponent
int exponent;
@@ -135,4 +139,6 @@ double decodeDouble_Compact(CompactSerializedDouble value) {
return ((value.signAndSignificandOne & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
}
+#endif
+
} // End of namespace Sword25
diff --git a/engines/sword25/util/double_serialization.h b/engines/sword25/util/double_serialization.h
index e90338c369..a910a66f20 100644
--- a/engines/sword25/util/double_serialization.h
+++ b/engines/sword25/util/double_serialization.h
@@ -56,6 +56,7 @@ SerializedDouble encodeDouble(double value);
*/
double decodeDouble(SerializedDouble value);
+#if 0
/**
* Encodes a double as a uint64
*
@@ -90,6 +91,8 @@ CompactSerializedDouble encodeDouble_Compact(double value);
*/
double decodeDouble_Compact(CompactSerializedDouble value);
+#endif
+
} // End of namespace Sword25
#endif
--
cgit v1.2.3
From f7ba09dcfcef0b7009e0b48bee2daf3f7b09194c Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 23:18:16 +0100
Subject: NEWS: Mention DOTT easter egg support
---
NEWS | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/NEWS b/NEWS
index 470ddc01bd..d66eb55d0e 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,10 @@ For a more comprehensive changelog of the latest experimental code, see:
head scene (bug #6728). It may have been happening in other scenes as
well.
+SCUMM:
+ - It is now possible to play Maniac Mansion from within Day of the
+ Tentacle, with a few caveats. See README for details.
+
1.7.0 (2014-07-21)
New Games:
- Added support for Chivalry is Not Dead.
--
cgit v1.2.3
From c44c0f09bfdff1567f2560962c5f2053156245f8 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 23:18:37 +0100
Subject: README: Describe DOTT easter egg support. Text by eriktorbjorn.
---
README | 111 +++++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 67 insertions(+), 44 deletions(-)
diff --git a/README b/README
index 5b0569089c..b78ee24dfd 100644
--- a/README
+++ b/README
@@ -15,26 +15,27 @@ Table of Contents:
* 2.1 Reporting Bugs
3.0) Supported Games
* 3.1 Copy Protection
- * 3.2 Commodore64 games notes
- * 3.3 Maniac Mansion NES notes
- * 3.4 Macintosh games notes
- * 3.5 Multi-CD games notes
- * 3.6 The Curse of Monkey Island notes
- * 3.7 Broken Sword games notes
- * 3.8 Beneath a Steel Sky notes
- * 3.9 Flight of the Amazon Queen notes
- * 3.10 Gobliiins notes
- * 3.11 Inherit the Earth: Quest for the Orb notes
- * 3.12 Simon the Sorcerer notes
- * 3.13 The Feeble Files notes
- * 3.14 The Legend of Kyrandia notes
- * 3.15 Sierra AGI games Predictive Input Dialog notes
- * 3.16 Mickey's Space Adventure notes
- * 3.17 Winnie the Pooh notes
- * 3.18 Troll's Tale notes
- * 3.19 Dragon History notes
- * 3.20 Simultaneous speech and subtitles in Sierra SCI games
- * 3.21 Known Problems
+ * 3.2 Day of the Tentacle notes
+ * 3.3 Commodore64 games notes
+ * 3.4 Maniac Mansion NES notes
+ * 3.5 Macintosh games notes
+ * 3.6 Multi-CD games notes
+ * 3.7 The Curse of Monkey Island notes
+ * 3.8 Broken Sword games notes
+ * 3.9 Beneath a Steel Sky notes
+ * 3.10 Flight of the Amazon Queen notes
+ * 3.11 Gobliiins notes
+ * 3.12 Inherit the Earth: Quest for the Orb notes
+ * 3.13 Simon the Sorcerer notes
+ * 3.14 The Feeble Files notes
+ * 3.15 The Legend of Kyrandia notes
+ * 3.16 Sierra AGI games Predictive Input Dialog notes
+ * 3.17 Mickey's Space Adventure notes
+ * 3.18 Winnie the Pooh notes
+ * 3.19 Troll's Tale notes
+ * 3.20 Dragon History notes
+ * 3.21 Simultaneous speech and subtitles in Sierra SCI games
+ * 3.22 Known Problems
4.0) Supported Platforms
5.0) Running ScummVM
* 5.1 Command Line Options
@@ -410,7 +411,29 @@ ScummVM will skip copy protection in the following games:
* Zak McKracken and the Alien Mindbenders
-3.2) Commodore64 games notes:
+3.2) Day of the Tentacle notes:
+---- --------------------------
+
+At one point in the game, you come across a computer that allows you
+to play the original Maniac Mansion as an easter egg. ScummVM supports
+this, with a few caveats:
+
+ScummVM will scan your configuration file for a game that's in a
+'Maniac' sub-folder of your Day of the Tentacle folder. If you've
+copied the data files from the CD version, this should already be the
+case but you have to add the game to ScummVM as well.
+
+To return to Day of the Tentacle, press F5 and select "Return to
+Launcher".
+
+This means that you could in theory use any game as the easter egg.
+Indeed, there is a "secret" configuration setting, "easter_egg", to
+override the ID of the game to run. Be aware, though, that not all
+games support returning to the launcher, and setting it up to use Day
+of the Tentacle itself as the easter egg game is not recommended.
+
+
+3.3) Commodore64 games notes:
---- ------------------------
Both Maniac Mansion and Zak McKracken run but Maniac Mansion is not yet
playable. Simply name the D64 disks "maniac1.d64" and "maniac2.d64"
@@ -424,7 +447,7 @@ to Commodore64. We recommend using the much simpler approach described
in the previous paragraph.
-3.3) Maniac Mansion NES notes:
+3.4) Maniac Mansion NES notes:
---- -------------------------
Supported versions are English GB (E), French (F), German (G), Italian (I),
Swedish (SW) and English US (U). ScummVM requires just the PRG section
@@ -453,7 +476,7 @@ section. To do so use the 'extract_mm_nes' utility from the tools
package.
-3.4) Macintosh games notes:
+3.5) Macintosh games notes:
---- ----------------------
All LucasArts SCUMM based adventures, except COMI, also exist in versions
for the Macintosh. ScummVM can use most (all?) of them, however, in some
@@ -481,7 +504,7 @@ disk see:
http://wiki.scummvm.org/index.php/HOWTO-Mac_Games
-3.5) Multi-CD games notes:
+3.6) Multi-CD games notes:
---- ---------------------
In general, ScummVM does not deal very well with Multi-CD games. This is
because ScummVM assumes everything about a game can be found in one
@@ -496,7 +519,7 @@ files. Usually, when a file appears on more than one CD you can pick
either of them.
-3.6) The Curse of Monkey Island notes:
+3.7) The Curse of Monkey Island notes:
---- ---------------------------------
For this game, you will need the comi.la0, comi.la1 and comi.la2 files.
The comi.la0 file can be found on either CD, but since they are
@@ -508,7 +531,7 @@ two CDs. Some of the files appear on both CDs, but again they're
identical.
-3.7) Broken Sword games notes:
+3.8) Broken Sword games notes:
---- -------------------------
The instructions for the Broken Sword games are for the Sold-Out
Software versions, with each game on two CDs, since these were the
@@ -517,7 +540,7 @@ them. Hopefully they are general enough to be useful to other releases
as well.
-3.7.1) Broken Sword games cutscenes:
+3.8.1) Broken Sword games cutscenes:
------ -----------------------------
The cutscenes for the Broken Sword games have a bit of a history (see
the next section, if you are interested), but in general all you need to
@@ -558,7 +581,7 @@ currently does not work when running PlayStation videos. (Broken Sword
II already has subtitles; no extra work is needed for them.)
-3.7.2) Broken Sword games cutscenes, in retrospect:
+3.8.2) Broken Sword games cutscenes, in retrospect:
------ --------------------------------------------
The original releases of the Broken Sword games used RAD Game Tools's
Smacker(tm) format. As RAD was unwilling to open the older legacy
@@ -583,7 +606,7 @@ decoding MPEG movies added a lot of complexity, and they didn't look as
good as the Smacker and DXA versions anyway.
-3.7.3) Broken Sword:
+3.8.3) Broken Sword:
------ -------------
For this game, you will need all of the files from the clusters
directories on both CDs. For the Windows and Macintosh versions, you
@@ -600,7 +623,7 @@ makes little difference. The PlayStation version requires tunes.dat and
tunes.tab.
-3.7.4) Broken Sword II:
+3.8.4) Broken Sword II:
------ ----------------
For this game, you will need all of the files from the clusters
directories on both CDs. (Actually, a few of them may not be strictly
@@ -615,7 +638,7 @@ In addition, you will need the cd.inf and, optionally, the startup.inf
files from the sword2 directory on CD 1.
-3.8) Beneath a Steel Sky notes:
+3.9) Beneath a Steel Sky notes:
---- --------------------------
Starting with ScummVM 0.8.0 you need the additional 'SKY.CPT' file to
run Beneath a Steel Sky.
@@ -626,7 +649,7 @@ files (SKY.DNR, SKY.DSK), in your extrapath, or in the directory where
your ScummVM executable resides.
-3.9) Flight of the Amazon Queen notes:
+3.10) Flight of the Amazon Queen notes:
---- ---------------------------------
In order to use a non-freeware version of Flight of the Amazon Queen
(from original CD), you will need to place the 'queen.tbl' file
@@ -641,7 +664,7 @@ specific version, and thus removing the run-time dependency on the
sound effects with MP3, OGG or FLAC.
-3.10) Gobliiins notes:
+3.11) Gobliiins notes:
----- ----------------
The CD versions of the Gobliiins series contain one big audio track
which you need to rip (see the section on using compressed audio files)
@@ -651,7 +674,7 @@ track and its volume is therefore changed with the music volume control
as well.
-3.11) Inherit the Earth: Quest for the Orb notes:
+3.12) Inherit the Earth: Quest for the Orb notes:
----- -------------------------------------------
In order to run the Mac OS X Wyrmkeep re-release of the game you will
need to copy over data from the CD to your hard disk. If you're on a PC
@@ -671,14 +694,14 @@ format, as they should include both resource and data forks. Copy all
'ITE *' files.
-3.12) Simon the Sorcerer 1 and 2 notes:
+3.13) Simon the Sorcerer 1 and 2 notes:
----- ---------------------------------
If you have the dual version of Simon the Sorcerer 1 or 2 on CD, you
will find the Windows version in the main directory of the CD and the
DOS version in the DOS directory of the CD.
-3.13) The Feeble Files notes:
+3.14) The Feeble Files notes:
----- -----------------------
If you have the Windows version of The Feeble Files, there are several
things to note.
@@ -696,7 +719,7 @@ Rename voices.wav on CD3 to voices3.wav
Rename voices.wav on CD4 to voices4.wav
-3.14) The Legend of Kyrandia notes:
+3.15) The Legend of Kyrandia notes:
----- -----------------------------
To run The Legend of Kyrandia under ScummVM you need the 'kyra.dat'
file. The file should always be included in official ScummVM packages.
@@ -707,7 +730,7 @@ thus you only need to grab it in case ScummVM complains about the file
being missing.
-3.15) Sierra AGI games Predictive Input Dialog notes:
+3.16) Sierra AGI games Predictive Input Dialog notes:
----- -----------------------------------------------
The Predictive Input Dialog is a ScummVM aid for running AGI engine
games (which notoriously require command line input) on devices with
@@ -761,7 +784,7 @@ naturally mapping the functionality to the numeric keypad. Also, the
dialog's buttons can be navigated with the arrow and the enter keys.
-3.16) Mickey's Space Adventure notes:
+3.17) Mickey's Space Adventure notes:
----- -------------------------------
To run Mickey's Space Adventure under ScummVM, the original executable
of the game (mickey.exe) is needed together with the game's data files.
@@ -776,7 +799,7 @@ game's screen to change location, similar to many adventure games, which
is simpler and more straightforward than moving around using the menu.
-3.17) Winnie the Pooh notes:
+3.18) Winnie the Pooh notes:
----- ----------------------
It is possible to import saved games from the original interpreter of the
game into ScummVM.
@@ -791,14 +814,14 @@ game's screen to change location, similar to many adventure games, which
is simpler and more straightforward than moving around using the menu.
-3.18) Troll's Tale notes:
+3.19) Troll's Tale notes:
----- -------------------
The original game came in a PC booter disk, therefore it is necessary to
dump the contents of that disk in an image file and name it "troll.img"
to be able to play the game under ScummVM.
-3.19) Dragon History notes:
+3.20) Dragon History notes:
----- ---------------------
There are 4 language variants of the game: Czech, English, Polish and
German. Each of them is distributed in a separate archive. The only
@@ -816,7 +839,7 @@ All game files and the walkthrough can be downloaded from
http://www.ucw.cz/draci-historie/index-en.html
-3.20) Simultaneous speech and subtitles in Sierra SCI games:
+3.21) Simultaneous speech and subtitles in Sierra SCI games:
----- ------------------------------------------------------
Certain CD versions of Sierra SCI games had both speech and text
resources. Some have an option to toggle between the two, but there are
@@ -864,7 +887,7 @@ Space Quest 4 CD:
options dialog, or via ScummVM's audio options.
-3.21) Known Problems:
+3.22) Known Problems:
----- ---------------
This release has the following known problems. There is no need to
report them, although patches to fix them are welcome. If you discover a
--
cgit v1.2.3
From 1d596b023024abe7b4781803ee7442462719bcc8 Mon Sep 17 00:00:00 2001
From: Eugene Sandulenko
Date: Sun, 4 Jan 2015 23:55:54 +0100
Subject: README: A (huge) update of compatible games
Somehow we missed to update it for ages!
---
README | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 97 insertions(+), 20 deletions(-)
diff --git a/README b/README
index b78ee24dfd..e5a4229afd 100644
--- a/README
+++ b/README
@@ -201,7 +201,7 @@ SCUMM Games by LucasArts:
The Dig [dig]
The Curse of Monkey Island [comi]
-AGI Games by Sierra:
+AGI and preAGI Games by Sierra:
The Black Cauldron [bc]
Gold Rush! [goldrush]
King's Quest I [kq1]
@@ -218,6 +218,9 @@ AGI Games by Sierra:
Space Quest I: The Sarien Encounter [sq1]
Space Quest II: Vohaul's Revenge [sq2]
Fanmade Games [agi-fanmade]
+ Mickey's Space Adventure [mickey]
+ Troll's Tale [troll]
+ Winnie the Pooh in the Hundred Acre Wood [winnie]
AGOS Games by Adventuresoft/Horrorsoft:
Elvira - Mistress of the Dark [elvira1]
@@ -236,6 +239,13 @@ AGOS Games by Adventuresoft/Horrorsoft:
- Swampy Adventures [swampy]
The Feeble Files [feeble]
+Composer Games by Animation Magic:
+ Darby the Dragon [darby]
+ Gregory and the Hot Air Balloon [gregory]
+ Magic Tales: Liam Finds a Story [liam]
+ The Princess and the Crab [princess]
+ Sleeping Cub's Test of Courage [sleepingcub]
+
GOB Games by Coktel Vision:
Bambou le sauveur de la jungle [bambou]
Bargon Attack [bargon]
@@ -251,6 +261,22 @@ GOB Games by Coktel Vision:
Urban Runner [urban]
Ween: The Prophecy [ween]
+Living Books Games:
+ Aesop's Fables: The Tortoise and the Hare [tortoise]
+ Arthur's Birthday [arthurbday]
+ Arthur's Teacher Trouble [arthur]
+ Dr. Seuss's ABC [seussabc]
+ Green Eggs and Ham [greeneggs]
+ Harry and the Haunted House [harryhh]
+ Just Grandma and Me [grandma]
+ Little Monster at School [lilmonster]
+ Ruff's Bone [ruff]
+ Sheila Rae, the Brave [sheila]
+ Stellaluna [stellaluna]
+ The Berenstain Bears Get in a Fight [bearfight]
+ The Berenstain Bears in the Dark [beardark]
+ The New Kid on the Block [newkid]
+
MADE Games by Activision:
Leather Goddesses of Phobos 2 [lgop2]
Return to Zork [rtz]
@@ -258,34 +284,102 @@ MADE Games by Activision:
The Manhole [manhole]
Other Games:
+ 3 Skulls of the Toltecs [toltecs]
+ Blue Force [blueforce]
Beneath a Steel Sky [sky]
Broken Sword: The Shadow of the Templars [sword1]
Broken Sword II: The Smoking Mirror [sword2]
+ Bud Tucker in Double Trouble [tucker]
Cruise for a Corpse [cruise]
Discworld [dw]
Discworld 2: Missing Presumed ...!? [dw2]
Dragon History [draci]
Drascula: The Vampire Strikes Back [drascula]
+ DreamWeb [dreamweb]
Eye of the Beholder [eob]
Eye of the Beholder II: The Legend of
Darkmoon [eob2]
Flight of the Amazon Queen [queen]
Future Wars [fw]
+ Hopkins FBI [hopkins]
+ Hugo's House of Horrors [hugo1]
+ Hugo 2: Whodunit? [hugo2]
+ Hugo 3: Jungle of Doom [hugo3]
+ I Have No Mouth, and I Must Scream [ihnm]
Inherit the Earth: Quest for the Orb [ite]
Nippon Safes Inc. [nippon]
Lands of Lore: The Throne of Chaos [lol]
+ Lure of the Temptress [lure]
+ Mortville Manor [mortevielle]
+ Nippon Safes Inc. [nippon]
+ Ringworld: Revenge Of The Patriarch [ringworld]
+ Return to Ringworld [ringworld2]
+ Sfinx [sfinx]
+ Soltys [soltys]
+ TeenAgent [teenagent]
The Journeyman Project: Pegasus Prime [pegasus]
The Legend of Kyrandia [kyra1]
The Legend of Kyrandia: The Hand of Fate [kyra2]
The Legend of Kyrandia: Malcolm's Revenge [kyra3]
+ The 7th Guest [t7g]
+ The Neverhood [neverhood]
+ Tony Tough and the Night of Roasted Moths [tony]
+ Toonstruck [toon]
Touche: The Adventures of the Fifth
Musketeer [touche]
+ Voyeur [voyeur]
+
+SCI Games by Sierra Entertainment:
+ Castle of Dr. Brain [castlebrain]
+ Codename: ICEMAN [iceman]
+ Conquests of Camelot [camelot]
+ Conquests of the Longbow [longbow]
+ EcoQuest: The Search for Cetus [ecoquest]
+ EcoQuest 2: Lost Secret of the Rainforest [ecoquest2]
+ Freddy Pharkas: Frontier Pharmacist [freddypharkas]
+ Hoyle's Book of Games 1 [hoyle1]
+ Hoyle's Book of Games 2 [hoyle2]
+ Hoyle's Book of Games 3 [hoyle3]
+ Hoyle Classic Card Games [hoyle4]
+ Jones in the Fast Lane [jones]
+ King's Quest I [kq1sci]
+ King's Quest IV [kq4sci]
+ King's Quest V [kq5]
+ King's Quest VI [kq6]
+ Laura Bow: The Colonel's Bequest [laurabow]
+ Laura Bow 2: The Dagger of Amon Ra [laurabow2]
+ Leisure Suit Larry 1 [lsl1sci]
+ Leisure Suit Larry 2 [lsl2]
+ Leisure Suit Larry 3 [lsl3]
+ Leisure Suit Larry 5 [lsl5]
+ Leisure Suit Larry 6 [lsl6]
+ Mixed-up Fairy Tales [fairytales]
+ Mixed-up Mother Goose [mothergoose]
+ Pepper's Adventures in Time [pepper]
+ Police Quest 1 [pq1sci]
+ Police Quest 2 [pq2]
+ Police Quest 3 [pq3]
+ Quest for Glory 1/Hero's Quest [qfg1]
+ Quest for Glory 1 [qfg1vga]
+ Quest for Glory 2 [qfg2]
+ Quest for Glory 3 [qfg3]
+ Slater & Charlie Go Camping [slater]
+ Space Quest I [sq1sci]
+ Space Quest III [sq3]
+ Space Quest IV [sq4]
+ Space Quest V [sq5]
+ The Island of Dr. Brain [islandbrain]
+
+Wintermute Games:
+ Chivalry is Not Dead [chivalry]
SCUMM Games by Humongous Entertainment:
Backyard Baseball [baseball]
Backyard Baseball 2001 [baseball2001]
Backyard Baseball 2003 [baseball2003]
Backyard Football [football]
+ Backyard Football 2002 [football2002]
+ Bear Stormin' [brstorm]
Big Thinkers First Grade [thinker1]
Big Thinkers Kindergarten [thinkerk]
Blue's 123 Time Activities [Blues123Time]
@@ -310,6 +404,7 @@ SCUMM Games by Humongous Entertainment:
Let's Explore the Airport with Buzzy [airport]
Let's Explore the Farm with Buzzy [farm]
Let's Explore the Jungle with Buzzy [jungle]
+ Pajama Sam: Games to Play on Any Day [pjgames]
Pajama Sam 1: No Need to Hide When It's
Dark Outside [pajama]
Pajama Sam 2: Thunder and Lightning
@@ -334,38 +429,20 @@ SCUMM Games by Humongous Entertainment:
SPY Fox in Cheese Chase [chase]
SPY Fox in Hold the Mustard [mustard]
-Living Books Games:
- Aesop's Fables: The Tortoise and the Hare [tortoise]
- Arthur's Birthday [arthurbday]
- Arthur's Teacher Trouble [arthur]
- Dr. Seuss's ABC [seussabc]
- Green Eggs and Ham [greeneggs]
- Harry and the Haunted House [harryhh]
- Just Grandma and Me [grandma]
- Little Monster at School [lilmonster]
- Ruff's Bone [ruff]
- Sheila Rae, the Brave [sheila]
- Stellaluna [stellaluna]
- The Berenstain Bears Get in a Fight [bearfight]
- The Berenstain Bears in the Dark [beardark]
- The New Kid on the Block [newkid]
-
The following games should load, but are not yet fully playable. Play
these at your own risk, and please do not file bug reports about them.
If you want the latest updates on game compatibility, visit our web site
and view the compatibility chart.
- Backyard Football 2002 [football2002]
Backyard Soccer [soccer]
Backyard Soccer MLS [soccermls]
Backyard Soccer 2004 [soccer2004]
Blue's Treasure Hunt [BluesTreasureHunt]
- Pajama Sam: Games to Play on Any Day [pjgames]
The following games are based on the SCUMM engine, but NOT supported
by ScummVM (yet):
- Other Humongous Entertainment games
+ Moonbase Commander
Please be aware that the engines may contain bugs and unimplemented
features that sometimes make it impossible to finish the game. Save
--
cgit v1.2.3
From 02e3e82e8210abe9f496f978917c9b134b5e0ad9 Mon Sep 17 00:00:00 2001
From: Kirben
Date: Mon, 5 Jan 2015 22:33:19 +1100
Subject: SCUMM: Correct game flags for HE72 version of Putt-Putt Saves the
Zoo.
---
engines/scumm/detection_tables.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 82a8b4452b..6eab5c752f 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -310,7 +310,7 @@ static const GameSettings gameVariantsTable[] = {
// Changed o_getResourceSize to cover all resource types
{"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "", 0, GID_PUTTZOO, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"puttzoo", "HE 72", 0, GID_PUTTZOO, 6, 72, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 72", 0, GID_PUTTZOO, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "HE 98.5", 0, GID_PUTTZOO, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "HE 99", 0, GID_PUTTZOO, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "HE 100", 0, GID_PUTTZOO, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
--
cgit v1.2.3
From 7225101e6257d0574fb94be8a6016a3b67a09855 Mon Sep 17 00:00:00 2001
From: Fedor Strizhnev
Date: Mon, 5 Jan 2015 16:53:35 +0300
Subject: Add Theora support to systems which use libtremor
---
video/theora_decoder.cpp | 4 ++++
video/theora_decoder.h | 5 +++++
2 files changed, 9 insertions(+)
diff --git a/video/theora_decoder.cpp b/video/theora_decoder.cpp
index cb6289bd60..ba596c6032 100644
--- a/video/theora_decoder.cpp
+++ b/video/theora_decoder.cpp
@@ -360,7 +360,11 @@ static double rint(double v) {
}
bool TheoraDecoder::VorbisAudioTrack::decodeSamples() {
+#ifdef USE_TREMOR
+ ogg_int32_t **pcm;
+#else
float **pcm;
+#endif
// if there's pending, decoded audio, grab it
int ret = vorbis_synthesis_pcmout(&_vorbisDSP, &pcm);
diff --git a/video/theora_decoder.h b/video/theora_decoder.h
index feb4c6b49e..5b683cf6af 100644
--- a/video/theora_decoder.h
+++ b/video/theora_decoder.h
@@ -33,7 +33,12 @@
#include "graphics/surface.h"
#include
+
+#ifdef USE_TREMOR
+#include
+#else
#include
+#endif
namespace Common {
class SeekableReadStream;
--
cgit v1.2.3
From 76f681efdfc0c9389ba09d63652847e156a65364 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 5 Jan 2015 18:15:12 +0100
Subject: ACCESS: Make opcodes dependant to game versions
---
engines/access/access.cpp | 4 +
engines/access/access.h | 4 +
engines/access/amazon/amazon_scripts.cpp | 2 +
engines/access/martian/martian_game.h | 1 -
engines/access/scripts.cpp | 131 +++++++++++++++++++++----------
engines/access/scripts.h | 6 ++
6 files changed, 104 insertions(+), 44 deletions(-)
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 14aa68c9dc..dabcd1351b 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -93,6 +93,10 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_vidX = _vidY = 0;
_cheatFl = false;
_restartFl = false;
+
+ for (int i = 0; i < 7; i++)
+ TRAVEL[i] = 0;
+ STARTTRAVELITEM = STARTTRAVELBOX = 0;
}
AccessEngine::~AccessEngine() {
diff --git a/engines/access/access.h b/engines/access/access.h
index 8801c1b04f..de44905f9b 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -206,6 +206,10 @@ public:
uint32 _newDate;
int _flags[256];
+ int TRAVEL[7];
+ int STARTTRAVELITEM;
+ int STARTTRAVELBOX;
+
bool _clearSummaryFlag;
bool _cheatFl;
bool _restartFl;
diff --git a/engines/access/amazon/amazon_scripts.cpp b/engines/access/amazon/amazon_scripts.cpp
index 633188e4dd..d7ca408eca 100644
--- a/engines/access/amazon/amazon_scripts.cpp
+++ b/engines/access/amazon/amazon_scripts.cpp
@@ -33,6 +33,8 @@ namespace Amazon {
AmazonScripts::AmazonScripts(AccessEngine *vm) : Scripts(vm) {
_game = (AmazonEngine *)_vm;
+
+ setOpcodes_v2();
}
void AmazonScripts::cLoop() {
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
index 03f3e0f5fa..155642a4e4 100644
--- a/engines/access/martian/martian_game.h
+++ b/engines/access/martian/martian_game.h
@@ -61,7 +61,6 @@ protected:
void displayNote(const Common::String &msg);
public:
MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc);
-
virtual ~MartianEngine();
void doSpecial5(int param1);
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index a74cc7b12e..62366fd626 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -37,12 +37,94 @@ Scripts::Scripts(AccessEngine *vm) : Manager(vm) {
_choiceStart = 0;
_charsOrg = Common::Point(0, 0);
_texsOrg = Common::Point(0, 0);
+ setOpcodes();
}
Scripts::~Scripts() {
freeScriptData();
}
+void Scripts::setOpcodes() {
+ COMMAND_LIST[0] = &Scripts::cmdObject;
+ COMMAND_LIST[1] = &Scripts::cmdEndObject;
+ COMMAND_LIST[2] = &Scripts::cmdJumpLook;
+ COMMAND_LIST[3] = &Scripts::cmdJumpHelp;
+ COMMAND_LIST[4] = &Scripts::cmdJumpGet;
+ COMMAND_LIST[5] = &Scripts::cmdJumpMove;
+ COMMAND_LIST[6] = &Scripts::cmdJumpUse;
+ COMMAND_LIST[7] = &Scripts::cmdJumpTalk;
+ COMMAND_LIST[8] = &Scripts::cmdNull;
+ COMMAND_LIST[9] = &Scripts::cmdPrint;
+ COMMAND_LIST[10] = &Scripts::cmdRetPos;
+ COMMAND_LIST[11] = &Scripts::cmdAnim;
+ COMMAND_LIST[12] = &Scripts::cmdSetFlag;
+ COMMAND_LIST[13] = &Scripts::cmdCheckFlag;
+ COMMAND_LIST[14] = &Scripts::cmdGoto;
+ COMMAND_LIST[15] = &Scripts::cmdAddScore;
+ COMMAND_LIST[16] = &Scripts::cmdSetInventory;
+ COMMAND_LIST[17] = &Scripts::cmdCheckInventory;
+ COMMAND_LIST[18] = &Scripts::cmdSetTex;
+ COMMAND_LIST[19] = &Scripts::cmdNewRoom;
+ COMMAND_LIST[20] = &Scripts::cmdConverse;
+ COMMAND_LIST[21] = &Scripts::cmdCheckFrame;
+ COMMAND_LIST[22] = &Scripts::cmdCheckAnim;
+ COMMAND_LIST[23] = &Scripts::cmdSnd;
+ COMMAND_LIST[24] = &Scripts::cmdRetNeg;
+ COMMAND_LIST[25] = &Scripts::cmdRetPos;
+ COMMAND_LIST[26] = &Scripts::cmdCheckLoc;
+ COMMAND_LIST[27] = &Scripts::cmdSetAnim;
+ COMMAND_LIST[28] = &Scripts::cmdDispInv;
+ COMMAND_LIST[29] = &Scripts::cmdSetAbout;
+ COMMAND_LIST[30] = &Scripts::cmdSetTimer;
+ COMMAND_LIST[31] = &Scripts::cmdCheckTimer;
+ COMMAND_LIST[32] = &Scripts::cmdSetTravel;
+ COMMAND_LIST[33] = &Scripts::cmdJumpGoto;
+ COMMAND_LIST[34] = &Scripts::cmdSetVideo;
+ COMMAND_LIST[35] = &Scripts::cmdPlayVideo;
+ COMMAND_LIST[36] = &Scripts::cmdPlotImage;
+ COMMAND_LIST[37] = &Scripts::cmdSetDisplay;
+ COMMAND_LIST[38] = &Scripts::cmdSetBuffer;
+ COMMAND_LIST[39] = &Scripts::cmdSetScroll;
+ COMMAND_LIST[40] = &Scripts::cmdSaveRect;
+ COMMAND_LIST[41] = &Scripts::cmdVideoEnded;
+ COMMAND_LIST[42] = &Scripts::cmdSetBufVid;
+ COMMAND_LIST[43] = &Scripts::cmdPlayBufVid;
+ COMMAND_LIST[44] = &Scripts::cmdRemoveLast;
+ COMMAND_LIST[45] = &Scripts::cmdDoTravel;
+ COMMAND_LIST[46] = &Scripts::cmdCheckAbout;
+ COMMAND_LIST[47] = &Scripts::cmdSpecial;
+ COMMAND_LIST[48] = &Scripts::cmdSetCycle;
+ COMMAND_LIST[49] = &Scripts::cmdCycle;
+ COMMAND_LIST[50] = &Scripts::cmdCharSpeak;
+ COMMAND_LIST[51] = &Scripts::cmdTexSpeak;
+ COMMAND_LIST[52] = &Scripts::cmdTexChoice;
+ COMMAND_LIST[53] = &Scripts::cmdWait;
+ COMMAND_LIST[54] = &Scripts::cmdSetConPos;
+ COMMAND_LIST[55] = &Scripts::cmdCheckVFrame;
+ COMMAND_LIST[56] = &Scripts::cmdJumpChoice;
+ COMMAND_LIST[57] = &Scripts::cmdReturnChoice;
+ COMMAND_LIST[58] = &Scripts::cmdClearBlock;
+ COMMAND_LIST[59] = &Scripts::cmdLoadSound;
+ COMMAND_LIST[60] = &Scripts::cmdFreeSound;
+ COMMAND_LIST[61] = &Scripts::cmdSetVideoSound;
+ COMMAND_LIST[62] = &Scripts::cmdPlayVideoSound;
+ COMMAND_LIST[63] = &Scripts::cmdPrintWatch;
+ COMMAND_LIST[64] = &Scripts::cmdDispAbout;
+ COMMAND_LIST[65] = &Scripts::cmdPushLocation;
+ COMMAND_LIST[66] = &Scripts::cmdCheckTravel;
+ COMMAND_LIST[67] = &Scripts::cmdBlock;
+ COMMAND_LIST[68] = &Scripts::cmdPlayerOff;
+ COMMAND_LIST[69] = &Scripts::cmdPlayerOn;
+ COMMAND_LIST[70] = &Scripts::cmdDead;
+ COMMAND_LIST[71] = &Scripts::cmdFadeOut;
+ COMMAND_LIST[72] = &Scripts::cmdEndVideo;
+}
+
+void Scripts::setOpcodes_v2() {
+ COMMAND_LIST[15] = &Scripts::cmdSetInventory;
+ COMMAND_LIST[29] = &Scripts::cmdSetTimer();
+}
+
void Scripts::setScript(Resource *res, bool restartFlag) {
_resource = res;
_data = res->_stream;
@@ -107,37 +189,7 @@ int Scripts::executeScript() {
return _returnCode;
}
-typedef void(Scripts::*ScriptMethodPtr)();
-
void Scripts::executeCommand(int commandIndex) {
- static const ScriptMethodPtr COMMAND_LIST[] = {
- &Scripts::cmdObject, &Scripts::cmdEndObject, &Scripts::cmdJumpLook,
- &Scripts::cmdJumpHelp, &Scripts::cmdJumpGet, &Scripts::cmdJumpMove,
- &Scripts::cmdJumpUse, &Scripts::cmdJumpTalk, &Scripts::cmdNull,
- &Scripts::cmdPrint, &Scripts::cmdRetPos, &Scripts::cmdAnim,
- &Scripts::cmdSetFlag, &Scripts::cmdCheckFlag, &Scripts::cmdGoto,
- &Scripts::cmdAddScore, &Scripts::cmdSetInventory, &Scripts::cmdCheckInventory,
- &Scripts::cmdSetTex, &Scripts::cmdNewRoom, &Scripts::cmdConverse,
- &Scripts::cmdCheckFrame, &Scripts::cmdCheckAnim, &Scripts::cmdSnd,
- &Scripts::cmdRetNeg, &Scripts::cmdRetPos, &Scripts::cmdCheckLoc,
- &Scripts::cmdSetAnim, &Scripts::cmdDispInv, &Scripts::cmdSetAbout,
- &Scripts::cmdSetTimer, &Scripts::cmdCheckTimer, &Scripts::cmdSetTravel,
- &Scripts::cmdJumpGoto, &Scripts::cmdSetVideo, &Scripts::cmdPlayVideo,
- &Scripts::cmdPlotImage, &Scripts::cmdSetDisplay, &Scripts::cmdSetBuffer,
- &Scripts::cmdSetScroll, &Scripts::cmdSaveRect, &Scripts::cmdVideoEnded,
- &Scripts::cmdSetBufVid, &Scripts::cmdPlayBufVid, &Scripts::cmdRemoveLast,
- &Scripts::cmdDoTravel, &Scripts::cmdCheckAbout, &Scripts::cmdSpecial,
- &Scripts::cmdSetCycle, &Scripts::cmdCycle, &Scripts::cmdCharSpeak,
- &Scripts::cmdTexSpeak, &Scripts::cmdTexChoice, &Scripts::cmdWait,
- &Scripts::cmdSetConPos, &Scripts::cmdCheckVFrame, &Scripts::cmdJumpChoice,
- &Scripts::cmdReturnChoice, &Scripts::cmdClearBlock, &Scripts::cmdLoadSound,
- &Scripts::cmdFreeSound, &Scripts::cmdSetVideoSound, &Scripts::cmdPlayVideoSound,
- &Scripts::cmdPrintWatch, &Scripts::cmdDispAbout, &Scripts::cmdPushLocation,
- &Scripts::cmdCheckTravel, &Scripts::cmdBlock, &Scripts::cmdPlayerOff,
- &Scripts::cmdPlayerOn, &Scripts::cmdDead, &Scripts::cmdFadeOut,
- &Scripts::cmdEndVideo
- };
-
(this->*COMMAND_LIST[commandIndex])();
}
@@ -266,11 +318,6 @@ void Scripts::cmdGoto() {
}
void Scripts::cmdAddScore() {
- if (!_vm->isDemo()) {
- cmdSetInventory();
- return;
- }
-
_data->skip(1);
}
@@ -412,11 +459,6 @@ void Scripts::cmdDispInv() {
}
void Scripts::cmdSetAbout() {
- if (!_vm->isDemo()) {
- cmdSetTimer();
- return;
- }
-
error("TODO: DEMO - cmdSetAbout");
}
@@ -459,11 +501,14 @@ void Scripts::cmdCheckTimer() {
}
void Scripts::cmdSetTravel() {
- if (!_vm->isDemo()) {
+ if ((_vm->getGameID() == GType_Amazon) && !_vm->isDemo()) {
cmdJumpGoto();
- return;
+ } else {
+ int idx = _data->readByte();
+ int dest = _data->readByte();
+ _vm->TRAVEL[idx] = dest;
+ _vm->STARTTRAVELITEM = _vm->STARTTRAVELBOX = 0;
}
- error("TODO: DEMO - cmdSetTravel");
}
void Scripts::cmdJumpGoto() {
diff --git a/engines/access/scripts.h b/engines/access/scripts.h
index cfadf6d901..f61d35f81d 100644
--- a/engines/access/scripts.h
+++ b/engines/access/scripts.h
@@ -35,6 +35,8 @@ class Scripts;
#define SCRIPT_START_BYTE 0xE0
#define ROOM_SCRIPT 2000
+typedef void(Scripts::*ScriptMethodPtr)();
+
class Scripts : public Manager {
private:
Resource *_resource;
@@ -43,6 +45,7 @@ private:
void charLoop();
protected:
Common::SeekableReadStream *_data;
+ ScriptMethodPtr COMMAND_LIST[100];
virtual void executeSpecial(int commandIndex, int param1, int param2) = 0;
virtual void executeCommand(int commandIndex);
@@ -143,6 +146,9 @@ public:
virtual ~Scripts();
+ void setOpcodes();
+ void setOpcodes_v2();
+
void setScript(Resource *data, bool restartFlag = false);
void freeScriptData();
--
cgit v1.2.3
From 0f9174fca7c06d157736056a78238f0086298055 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 5 Jan 2015 19:36:38 +0100
Subject: ACCESS: MM - Split some more opcodes
---
engines/access/scripts.cpp | 46 +++++++++-------------------------------------
1 file changed, 9 insertions(+), 37 deletions(-)
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index 62366fd626..05c2d93cea 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -122,7 +122,11 @@ void Scripts::setOpcodes() {
void Scripts::setOpcodes_v2() {
COMMAND_LIST[15] = &Scripts::cmdSetInventory;
- COMMAND_LIST[29] = &Scripts::cmdSetTimer();
+ COMMAND_LIST[29] = &Scripts::cmdSetTimer;
+ COMMAND_LIST[32] = &Scripts::cmdJumpGoto;
+ COMMAND_LIST[40] = &Scripts::cmdVideoEnded;
+ COMMAND_LIST[45] = COMMAND_LIST[46] = &Scripts::cmdSpecial;
+ COMMAND_LIST[63] = COMMAND_LIST[64] = COMMAND_LIST[66] = COMMAND_LIST[67] = &Scripts::cmdPushLocation;
}
void Scripts::setScript(Resource *res, bool restartFlag) {
@@ -501,14 +505,10 @@ void Scripts::cmdCheckTimer() {
}
void Scripts::cmdSetTravel() {
- if ((_vm->getGameID() == GType_Amazon) && !_vm->isDemo()) {
- cmdJumpGoto();
- } else {
- int idx = _data->readByte();
- int dest = _data->readByte();
- _vm->TRAVEL[idx] = dest;
- _vm->STARTTRAVELITEM = _vm->STARTTRAVELBOX = 0;
- }
+ int idx = _data->readByte();
+ int dest = _data->readByte();
+ _vm->TRAVEL[idx] = dest;
+ _vm->STARTTRAVELITEM = _vm->STARTTRAVELBOX = 0;
}
void Scripts::cmdJumpGoto() {
@@ -560,10 +560,6 @@ void Scripts::cmdSetScroll() {
}
void Scripts::cmdSaveRect() {
- if (!_vm->isDemo()) {
- cmdVideoEnded();
- return;
- }
error("TODO: DEMO - cmdSaveRect");
}
@@ -596,18 +592,10 @@ void Scripts::cmdRemoveLast() {
}
void Scripts::cmdDoTravel() {
- if (!_vm->isDemo()) {
- cmdSpecial();
- return;
- }
error("TODO: DEMO - cmdDoTravel");
}
void Scripts::cmdCheckAbout() {
- if (!_vm->isDemo()) {
- cmdSpecial();
- return;
- }
error("TODO: DEMO - cmdCheckAbout");
}
@@ -874,18 +862,10 @@ void Scripts::cmdPlayVideoSound() {
}
void Scripts::cmdPrintWatch() {
- if (!_vm->isDemo()) {
- cmdPushLocation();
- return;
- }
error("TODO: DEMO - cmdPrintWatch");
}
void Scripts::cmdDispAbout() {
- if (!_vm->isDemo()) {
- cmdPushLocation();
- return;
- }
error("TODO: DEMO - cmdDispAbout");
}
@@ -894,18 +874,10 @@ void Scripts::cmdPushLocation() {
}
void Scripts::cmdCheckTravel() {
- if (!_vm->isDemo()) {
- cmdPushLocation();
- return;
- }
error("TODO: DEMO - cmdCheckTravel");
}
void Scripts::cmdBlock() {
- if (!_vm->isDemo()) {
- cmdPushLocation();
- return;
- }
error("TODO: DEMO - cmdBlock");
}
--
cgit v1.2.3
From e1ded539ea428efe811d763b8c025bf09c2559df Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Mon, 5 Jan 2015 22:43:21 +0100
Subject: ACCESS: MM - Implement some game specific opcodes
---
engines/access/access.cpp | 4 ++++
engines/access/access.h | 4 +++-
engines/access/scripts.cpp | 26 ++++++++++++++++++++++----
engines/access/scripts.h | 1 +
4 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index dabcd1351b..5973f3bd28 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -97,6 +97,10 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
for (int i = 0; i < 7; i++)
TRAVEL[i] = 0;
STARTTRAVELITEM = STARTTRAVELBOX = 0;
+ for (int i = 0; i < 16; i++)
+ ASK[i];
+ _startAboutItem = 0;
+ _vidEnd = false;
}
AccessEngine::~AccessEngine() {
diff --git a/engines/access/access.h b/engines/access/access.h
index de44905f9b..c853276c12 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -209,7 +209,9 @@ public:
int TRAVEL[7];
int STARTTRAVELITEM;
int STARTTRAVELBOX;
-
+ int ASK[16];
+ int _startAboutItem;
+ bool _vidEnd;
bool _clearSummaryFlag;
bool _cheatFl;
bool _restartFl;
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index 05c2d93cea..a9f01f137f 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -170,6 +170,10 @@ void Scripts::charLoop() {
_endFlag = endFlag;
}
+void Scripts::printWatch() {
+ warning("TODO: printWatch");
+}
+
void Scripts::findNull() {
// No implementation required in ScummVM, the strings in the script files are already skipped by the use of readByte()
}
@@ -463,7 +467,11 @@ void Scripts::cmdDispInv() {
}
void Scripts::cmdSetAbout() {
- error("TODO: DEMO - cmdSetAbout");
+ int idx = _data->readByte();
+ int val = _data->readByte();
+ _vm->ASK[idx] = val;
+ _vm->_startAboutBox = 0;
+ _vm->_startAboutItem = 0;
}
void Scripts::cmdSetTimer() {
@@ -560,7 +568,10 @@ void Scripts::cmdSetScroll() {
}
void Scripts::cmdSaveRect() {
- error("TODO: DEMO - cmdSaveRect");
+ if (_vm->_vidEnd)
+ cmdGoto();
+ else
+ _data->skip(2);
}
void Scripts::cmdVideoEnded() {
@@ -596,7 +607,13 @@ void Scripts::cmdDoTravel() {
}
void Scripts::cmdCheckAbout() {
- error("TODO: DEMO - cmdCheckAbout");
+ int idx = _data->readSint16LE();
+ int val = _data->readSint16LE();
+
+ if (_vm->ASK[idx] == val)
+ cmdGoto();
+ else
+ _data->skip(2);
}
void Scripts::cmdSpecial() {
@@ -862,7 +879,8 @@ void Scripts::cmdPlayVideoSound() {
}
void Scripts::cmdPrintWatch() {
- error("TODO: DEMO - cmdPrintWatch");
+ printWatch();
+ findNull();
}
void Scripts::cmdDispAbout() {
diff --git a/engines/access/scripts.h b/engines/access/scripts.h
index f61d35f81d..4d074b681a 100644
--- a/engines/access/scripts.h
+++ b/engines/access/scripts.h
@@ -43,6 +43,7 @@ private:
int _specialFunction;
void charLoop();
+ void printWatch();
protected:
Common::SeekableReadStream *_data;
ScriptMethodPtr COMMAND_LIST[100];
--
cgit v1.2.3
From 64d8d49b88c062eeb581518fea0d58aed9502ae9 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Tue, 6 Jan 2015 00:39:33 +0100
Subject: ACCESS: MM - Format CURSOR data
---
engines/access/martian/martian_resources.cpp | 119 +++++++++++++++++++--------
1 file changed, 84 insertions(+), 35 deletions(-)
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index f460800a97..29d309ebe7 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -41,47 +41,96 @@ const char *const FILENAMES[] = {
};
const byte MOUSE0[] = {
- 0, 0, 0, 0, 0, 2, 0xF7, 5, 0, 3, 0xF7, 0xF7, 5, 0, 3,
- 0xF7, 0xF7, 5, 0, 4, 0xF7, 0xF7, 0xF7, 5, 0, 4, 0xF7,
- 0xF7, 0xF7, 5, 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 5,
- 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 6, 0xF7, 0xF7, 0xF7, 0xF7,
- 0xF7, 5, 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 7,
- 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 6, 0xF7, 0xF7,
- 0xF7, 0xF7, 0xF7, 5, 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5,
- 2, 3, 0xF7, 0xF7, 5, 3, 3, 0xF7, 0xF7, 5, 3, 3, 0xF7,
- 0xF7, 5, 4, 2, 0xF7, 5
+ // hotspot x and y, uint16 LE
+ 0, 0, 0, 0,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0, 2, 0xF7, 5,
+ 0, 3, 0xF7, 0xF7, 5,
+ 0, 3, 0xF7, 0xF7, 5,
+ 0, 4, 0xF7, 0xF7, 0xF7, 5,
+ 0, 4, 0xF7, 0xF7, 0xF7, 5,
+ 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 0, 7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 2, 3, 0xF7, 0xF7, 5,
+ 3, 3, 0xF7, 0xF7, 5,
+ 3, 3, 0xF7, 0xF7, 5,
+ 4, 2, 0xF7, 5
};
const byte MOUSE1[] = {
- 7, 0, 7, 0, 6, 1, 0xF7, 4, 5, 0xFF, 0xFF, 0, 0xFF, 0xFF,
- 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, 2, 9, 0xFF, 0, 0, 0,
- 0xF7, 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, 0, 0,
- 0, 0, 0xFF, 0, 13, 0xF7, 0, 0, 0xF7, 0, 0xF7, 0, 0xF7,
- 0, 0xF7, 0, 0, 0xF7, 1, 11, 0xFF, 0, 0, 0, 0, 0xF7,
- 0, 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0xFF, 2, 9, 0xFF, 0, 0, 0, 0xF7, 0, 0, 0, 0xFF,
- 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, 4, 5, 0xFF, 0xFF, 0,
- 0xFF, 0xFF, 6, 1, 0xF7, 0, 0, 0, 0, 0, 0
+ // hotspot x and y, uint16 LE
+ 7, 0, 7, 0,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 6, 1, 0xF7,
+ 4, 5, 0xFF, 0xFF, 0, 0xFF, 0xFF,
+ 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF,
+ 2, 9, 0xFF, 0, 0, 0, 0xF7, 0, 0, 0, 0xFF,
+ 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF,
+ 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, 0, 0, 0, 0, 0xFF,
+ 0, 13, 0xF7, 0, 0, 0xF7, 0, 0xF7, 0, 0xF7, 0, 0xF7, 0, 0, 0xF7,
+ 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, 0, 0, 0, 0, 0xFF,
+ 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF,
+ 2, 9, 0xFF, 0, 0, 0, 0xF7, 0, 0, 0, 0xFF,
+ 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF,
+ 4, 5, 0xFF, 0xFF, 0, 0xFF, 0xFF,
+ 6, 1, 0xF7,
+ 0, 0,
+ 0, 0,
+ 0, 0
};
const byte MOUSE2[] = {
- 8, 0, 8, 0, 0, 0, 0, 0, 7, 2, 4, 5, 7, 2, 4, 5, 7, 2,
- 4, 5, 7, 2, 4, 5, 7, 2, 4, 5, 2, 12, 4, 4, 4, 4, 4,
- 0, 4, 4, 4, 4, 4, 5, 7, 2, 4, 5, 7, 2, 4, 5, 7, 2, 4,
- 5, 7, 2, 4, 5, 7, 2, 4, 5, 0, 0, 0, 0, 0, 0
+ // hotspot x and y, uint16 LE
+ 8, 0, 8, 0,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0, 0,
+ 0, 0,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 2, 12, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 5,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 7, 2, 4, 5,
+ 0, 0,
+ 0, 0,
+ 0, 0
};
const byte MOUSE3[] = {
- 0, 0, 0, 0, 0, 11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 0, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 0, 12,
- 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, 0, 12, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 5,
- 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 5, 0, 0, 6, 6,
- 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 0, 6, 6, 6, 6, 6, 5,
- 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6,
- 6, 6, 5, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 5,
- 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 5, 1, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
- 0, 0, 0, 0, 0
+ // hotspot x and y, uint16 LE
+ 0, 0, 0, 0,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0, 11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 0, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5,
+ 0, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5,
+ 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 5, 0, 0, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 0, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,
+ 1, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 0,
+ 0, 0,
+ 0, 0
};
const byte *const CURSORS[4] = { MOUSE0, MOUSE1, MOUSE2, MOUSE3 };
--
cgit v1.2.3
From cc75fb5fe0a5eaef623da48badf28a2d9fa05ed3 Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Tue, 6 Jan 2015 00:40:13 +0100
Subject: ACCESS: MM - Fix TRAVEL array size
---
engines/access/access.cpp | 2 +-
engines/access/access.h | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 5973f3bd28..996780dfe7 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -94,7 +94,7 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_cheatFl = false;
_restartFl = false;
- for (int i = 0; i < 7; i++)
+ for (int i = 0; i < 60; i++)
TRAVEL[i] = 0;
STARTTRAVELITEM = STARTTRAVELBOX = 0;
for (int i = 0; i < 16; i++)
diff --git a/engines/access/access.h b/engines/access/access.h
index c853276c12..e26dce1de6 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -206,11 +206,12 @@ public:
uint32 _newDate;
int _flags[256];
- int TRAVEL[7];
+ int TRAVEL[60];
int STARTTRAVELITEM;
int STARTTRAVELBOX;
int ASK[16];
int _startAboutItem;
+
bool _vidEnd;
bool _clearSummaryFlag;
bool _cheatFl;
--
cgit v1.2.3
From 7323140847b8c1c47ef9e0f7a825fa667ddf99cc Mon Sep 17 00:00:00 2001
From: Strangerke
Date: Tue, 6 Jan 2015 00:41:10 +0100
Subject: ACCESS: MM - Fix cmdSaveRect, implement cmdCheckTravel
---
engines/access/scripts.cpp | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index a9f01f137f..2a70fe3542 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -568,10 +568,11 @@ void Scripts::cmdSetScroll() {
}
void Scripts::cmdSaveRect() {
- if (_vm->_vidEnd)
- cmdGoto();
- else
- _data->skip(2);
+ int x = _vm->_screen->_lastBoundsX;
+ int y = _vm->_screen->_lastBoundsY;
+ int w = _vm->_screen->_lastBoundsW;
+ int h = _vm->_screen->_lastBoundsH;
+ _vm->_newRects.push_back(Common::Rect(x, y, x + w, x + h));
}
void Scripts::cmdVideoEnded() {
@@ -892,7 +893,13 @@ void Scripts::cmdPushLocation() {
}
void Scripts::cmdCheckTravel() {
- error("TODO: DEMO - cmdCheckTravel");
+ int idx = _data->readSint16LE();
+ int val = _data->readUint16LE();
+
+ if (_vm->TRAVEL[idx] == val)
+ cmdGoto();
+ else
+ _data->skip(2);
}
void Scripts::cmdBlock() {
--
cgit v1.2.3
From 59934881a1dc27e0c6030d2133ec3f9aae583df7 Mon Sep 17 00:00:00 2001
From: Joel Teichroeb
Date: Mon, 5 Jan 2015 20:14:17 -0800
Subject: ANDROID: Remove unpacker and fix support for non arm
---
backends/platform/android/android.cpp | 12 -
backends/platform/android/android.h | 8 -
backends/platform/android/android.mk | 6 +-
backends/platform/android/jni.cpp | 46 ---
backends/platform/android/jni.h | 2 -
.../org/scummvm/scummvm/PluginProvider.java | 63 ----
.../android/org/scummvm/scummvm/ScummVM.java | 7 +-
.../org/scummvm/scummvm/ScummVMActivity.java | 7 -
.../org/scummvm/scummvm/ScummVMApplication.java | 31 --
.../android/org/scummvm/scummvm/Unpacker.java | 388 ---------------------
configure | 2 +
dists/android/AndroidManifest.xml | 19 +-
dists/android/AndroidManifest.xml.in | 19 +-
dists/android/jni/Android.mk | 2 +-
dists/android/mkplugin.sh | 16 -
dists/android/plugin-manifest.xml | 35 --
dists/android/plugin-manifest.xml.in | 35 --
dists/android/plugin-strings.xml | 6 -
dists/android/res/drawable/gradient.xml | 7 -
dists/android/res/layout/splash.xml | 19 -
20 files changed, 8 insertions(+), 722 deletions(-)
delete mode 100644 backends/platform/android/org/scummvm/scummvm/PluginProvider.java
delete mode 100644 backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java
delete mode 100644 backends/platform/android/org/scummvm/scummvm/Unpacker.java
delete mode 100755 dists/android/mkplugin.sh
delete mode 100644 dists/android/plugin-manifest.xml
delete mode 100644 dists/android/plugin-manifest.xml.in
delete mode 100644 dists/android/plugin-strings.xml
delete mode 100644 dists/android/res/drawable/gradient.xml
delete mode 100644 dists/android/res/layout/splash.xml
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 3ff1b939ef..798772cc24 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -396,12 +396,6 @@ void OSystem_Android::initBackend() {
EventsBaseBackend::initBackend();
}
-void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
- ENTER();
-
- JNI::getPluginDirectories(dirs);
-}
-
bool OSystem_Android::hasFeature(Feature f) {
return (f == kFeatureFullscreenMode ||
f == kFeatureAspectRatioCorrection ||
@@ -600,10 +594,4 @@ Common::String OSystem_Android::getSystemProperty(const char *name) const {
return Common::String(value, len);
}
-#ifdef DYNAMIC_MODULES
-void AndroidPluginProvider::addCustomDirectories(Common::FSList &dirs) const {
- ((OSystem_Android *)g_system)->addPluginDirectories(dirs);
-}
-#endif
-
#endif
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index 28016f5e3e..ade84dd42d 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -96,13 +96,6 @@ extern void checkGlError(const char *expr, const char *file, int line);
#define GLTHREADCHECK do { } while (false)
#endif
-#ifdef DYNAMIC_MODULES
-class AndroidPluginProvider : public POSIXPluginProvider {
-protected:
- virtual void addCustomDirectories(Common::FSList &dirs) const;
-};
-#endif
-
class OSystem_Android : public EventsBaseBackend, public PaletteManager {
private:
// passed from the dark side
@@ -177,7 +170,6 @@ public:
virtual ~OSystem_Android();
virtual void initBackend();
- void addPluginDirectories(Common::FSList &dirs) const;
void enableZoning(bool enable) { _enable_zoning = enable; }
virtual bool hasFeature(Feature f);
diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index f9a2bc9813..5be9f86770 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -5,7 +5,7 @@ ANDROID_VERSIONCODE = 6
ANDROID_TARGET_VERSION = 14
-NDK_BUILD = $(ANDROID_NDK)/ndk-build
+NDK_BUILD = $(ANDROID_NDK)/ndk-build APP_ABI=$(ABI)
SDK_ANDROID = $(ANDROID_SDK)/tools/android
PATH_DIST = $(srcdir)/dists/android
@@ -18,8 +18,6 @@ RESOURCES = \
$(PATH_BUILD_RES)/values/strings.xml \
$(PATH_BUILD_RES)/values-television/margins.xml \
$(PATH_BUILD_RES)/layout/main.xml \
- $(PATH_BUILD_RES)/layout/splash.xml \
- $(PATH_BUILD_RES)/drawable/gradient.xml \
$(PATH_BUILD_RES)/drawable/scummvm.png \
$(PATH_BUILD_RES)/drawable/scummvm_big.png \
$(PATH_BUILD_RES)/drawable-xhdpi/ouya_icon.png
@@ -30,7 +28,7 @@ DIST_BUILD_XML = $(PATH_DIST)/custom_rules.xml
PATH_BUILD = ./build.tmp
PATH_BUILD_ASSETS = $(PATH_BUILD)/assets
PATH_BUILD_RES = $(PATH_BUILD)/res
-PATH_BUILD_LIBSCUMMVM = $(PATH_BUILD)/mylib/armeabi/libscummvm.so
+PATH_BUILD_LIBSCUMMVM = $(PATH_BUILD)/lib/$(ABI)/libscummvm.so
FILE_MANIFEST_SRC = $(srcdir)/dists/android/AndroidManifest.xml
FILE_MANIFEST = $(PATH_BUILD)/AndroidManifest.xml
diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp
index 764c84ce1c..22e6a749c2 100644
--- a/backends/platform/android/jni.cpp
+++ b/backends/platform/android/jni.cpp
@@ -79,7 +79,6 @@ jmethodID JNI::_MID_displayMessageOnOSD = 0;
jmethodID JNI::_MID_setWindowCaption = 0;
jmethodID JNI::_MID_showVirtualKeyboard = 0;
jmethodID JNI::_MID_getSysArchives = 0;
-jmethodID JNI::_MID_getPluginDirectories = 0;
jmethodID JNI::_MID_initSurface = 0;
jmethodID JNI::_MID_deinitSurface = 0;
@@ -293,46 +292,6 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
}
}
-void JNI::getPluginDirectories(Common::FSList &dirs) {
- JNIEnv *env = JNI::getEnv();
-
- jobjectArray array =
- (jobjectArray)env->CallObjectMethod(_jobj, _MID_getPluginDirectories);
-
- if (env->ExceptionCheck()) {
- LOGE("Error finding plugin directories");
-
- env->ExceptionDescribe();
- env->ExceptionClear();
-
- return;
- }
-
- jsize size = env->GetArrayLength(array);
- for (jsize i = 0; i < size; ++i) {
- jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
-
- if (path_obj == 0)
- continue;
-
- const char *path = env->GetStringUTFChars(path_obj, 0);
-
- if (path == 0) {
- LOGE("Error getting string characters from plugin directory");
-
- env->ExceptionClear();
- env->DeleteLocalRef(path_obj);
-
- continue;
- }
-
- dirs.push_back(Common::FSNode(path));
-
- env->ReleaseStringUTFChars(path_obj, path);
- env->DeleteLocalRef(path_obj);
- }
-}
-
bool JNI::initSurface() {
JNIEnv *env = JNI::getEnv();
@@ -454,7 +413,6 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
FIND_METHOD(, displayMessageOnOSD, "(Ljava/lang/String;)V");
FIND_METHOD(, showVirtualKeyboard, "(Z)V");
FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
- FIND_METHOD(, getPluginDirectories, "()[Ljava/lang/String;");
FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
FIND_METHOD(, deinitSurface, "()V");
@@ -543,10 +501,6 @@ jint JNI::main(JNIEnv *env, jobject self, jobjectArray args) {
env->DeleteLocalRef(arg);
}
-#ifdef DYNAMIC_MODULES
- PluginManager::instance().addPluginProvider(new AndroidPluginProvider());
-#endif
-
LOGI("Entering scummvm_main with %d args", argc);
res = scummvm_main(argc, argv);
diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h
index 326869b1ee..70feaaf72a 100644
--- a/backends/platform/android/jni.h
+++ b/backends/platform/android/jni.h
@@ -55,7 +55,6 @@ public:
static void setReadyForEvents(bool ready);
- static void getPluginDirectories(Common::FSList &dirs);
static void setWindowCaption(const char *caption);
static void getDPI(float *values);
static void displayMessageOnOSD(const char *msg);
@@ -93,7 +92,6 @@ private:
static jmethodID _MID_setWindowCaption;
static jmethodID _MID_showVirtualKeyboard;
static jmethodID _MID_getSysArchives;
- static jmethodID _MID_getPluginDirectories;
static jmethodID _MID_initSurface;
static jmethodID _MID_deinitSurface;
diff --git a/backends/platform/android/org/scummvm/scummvm/PluginProvider.java b/backends/platform/android/org/scummvm/scummvm/PluginProvider.java
deleted file mode 100644
index e27e8d41a8..0000000000
--- a/backends/platform/android/org/scummvm/scummvm/PluginProvider.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.util.ArrayList;
-
-public class PluginProvider extends BroadcastReceiver {
- private final static String LOG_TAG = "ScummVM";
-
- public final static String META_UNPACK_LIB =
- "org.scummvm.scummvm.meta.UNPACK_LIB";
-
- public void onReceive(Context context, Intent intent) {
- if (!intent.getAction().equals(ScummVMApplication.ACTION_PLUGIN_QUERY))
- return;
-
- Bundle extras = getResultExtras(true);
-
- final ActivityInfo info;
- final PackageInfo pinfo;
- try {
- info = context.getPackageManager()
- .getReceiverInfo(new ComponentName(context, this.getClass()),
- PackageManager.GET_META_DATA);
- pinfo = context.getPackageManager()
- .getPackageInfo(context.getPackageName(), 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Error finding my own info?", e);
- return;
- }
-
- String host_version = extras.getString(ScummVMApplication.EXTRA_VERSION);
- if (!pinfo.versionName.equals(host_version)) {
- Log.e(LOG_TAG, "Plugin version " + pinfo.versionName + " is not equal to ScummVM version " + host_version);
- return;
- }
-
- String mylib = info.metaData.getString(META_UNPACK_LIB);
- if (mylib != null) {
- ArrayList all_libs =
- extras.getStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS);
- all_libs.add(new Uri.Builder()
- .scheme("plugin")
- .authority(context.getPackageName())
- .path(mylib)
- .toString());
-
- extras.putStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS,
- all_libs);
- }
-
- setResultExtras(extras);
- }
-}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 5047502e61..3b370a583d 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -54,7 +54,6 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
abstract protected void getDPI(float[] values);
abstract protected void displayMessageOnOSD(String msg);
abstract protected void setWindowCaption(String caption);
- abstract protected String[] getPluginDirectories();
abstract protected void showVirtualKeyboard(boolean enable);
abstract protected String[] getSysArchives();
@@ -444,10 +443,6 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
}
}
- File cache_dir = ScummVMApplication.getLastCacheDir();
- String libname = System.mapLibraryName("scummvm");
- File libpath = new File(cache_dir, libname);
-
- System.load(libpath.getPath());
+ System.loadLibrary("scummvm");
}
}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index f4eb7ddd0b..5b2dcae175 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -83,13 +83,6 @@ public class ScummVMActivity extends Activity {
});
}
- @Override
- protected String[] getPluginDirectories() {
- String[] dirs = new String[1];
- dirs[0] = ScummVMApplication.getLastCacheDir().getPath();
- return dirs;
- }
-
@Override
protected void showVirtualKeyboard(final boolean enable) {
runOnUiThread(new Runnable() {
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java b/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java
deleted file mode 100644
index 0adc166222..0000000000
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.app.Application;
-
-import java.io.File;
-
-public class ScummVMApplication extends Application {
- public final static String ACTION_PLUGIN_QUERY = "org.scummvm.scummvm.action.PLUGIN_QUERY";
- public final static String EXTRA_UNPACK_LIBS = "org.scummvm.scummvm.extra.UNPACK_LIBS";
- public final static String EXTRA_VERSION = "org.scummvm.scummvm.extra.VERSION";
-
- private static File _cache_dir;
-
- @Override
- public void onCreate() {
- super.onCreate();
-
- // This is still on /data :(
- _cache_dir = getCacheDir();
- // This is mounted noexec :(
- //cache_dir = new File(Environment.getExternalStorageDirectory(),
- // "/.ScummVM.tmp");
- // This is owned by download manager and requires special
- // permissions to access :(
- //cache_dir = Environment.getDownloadCacheDirectory();
- }
-
- public static File getLastCacheDir() {
- return _cache_dir;
- }
-}
diff --git a/backends/platform/android/org/scummvm/scummvm/Unpacker.java b/backends/platform/android/org/scummvm/scummvm/Unpacker.java
deleted file mode 100644
index da76ceb5e5..0000000000
--- a/backends/platform/android/org/scummvm/scummvm/Unpacker.java
+++ /dev/null
@@ -1,388 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.ProgressBar;
-
-import java.io.IOException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipEntry;
-
-public class Unpacker extends Activity {
- protected final static String LOG_TAG = "ScummVM";
- // TODO don't hardcode this
- private final static boolean PLUGINS_ENABLED = false;
- private final static String META_NEXT_ACTIVITY =
- "org.scummvm.unpacker.nextActivity";
- private ProgressBar mProgress;
- private File mUnpackDest; // location to unpack into
- private AsyncTask mUnpacker;
- private final static int REQUEST_MARKET = 1;
-
- // Android 3.1+ only
- public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32;
-
- private static class UnpackJob {
- public ZipFile zipfile;
- public Set paths;
-
- public UnpackJob(ZipFile zipfile, Set paths) {
- this.zipfile = zipfile;
- this.paths = paths;
- }
-
- public long UnpackSize() {
- long size = 0;
- for (String path: paths) {
- ZipEntry entry = zipfile.getEntry(path);
- if (entry != null) size += entry.getSize();
- }
- return size;
- }
- }
-
- private class UnpackTask extends AsyncTask {
- @Override
- protected void onProgressUpdate(Integer... progress) {
- mProgress.setIndeterminate(false);
- mProgress.setMax(progress[1]);
- mProgress.setProgress(progress[0]);
- mProgress.postInvalidate();
- }
-
- @Override
- protected void onPostExecute(Void result) {
- Bundle md = getMetaData();
- String nextActivity = md.getString(META_NEXT_ACTIVITY);
- if (nextActivity != null) {
- final ComponentName cn =
- ComponentName.unflattenFromString(nextActivity);
- if (cn != null) {
- final Intent origIntent = getIntent();
- Intent intent = new Intent();
- intent.setComponent(cn);
- if (origIntent.getExtras() != null)
- intent.putExtras(origIntent.getExtras());
- intent.putExtra(Intent.EXTRA_INTENT, origIntent);
- intent.setDataAndType(origIntent.getData(),
- origIntent.getType());
- //intent.fillIn(getIntent(), 0);
- intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
- Log.i(LOG_TAG,
- "Starting next activity with intent " + intent);
- startActivity(intent);
- } else {
- Log.w(LOG_TAG,
- "Unable to extract a component name from " + nextActivity);
- }
- }
-
- finish();
- }
-
- @Override
- protected Void doInBackground(String... all_libs) {
- // This will contain all unpack jobs
- Map unpack_jobs =
- new HashMap(all_libs.length);
-
- // This will contain all unpack filenames (so we can
- // detect stale files in the unpack directory)
- Set all_files = new HashSet(all_libs.length);
-
- for (String lib: all_libs) {
- final Uri uri = Uri.parse(lib);
- final String pkg = uri.getAuthority();
- final String path = uri.getPath().substring(1); // skip first /
-
- all_files.add(new File(path).getName());
-
- UnpackJob job = unpack_jobs.get(pkg);
- if (job == null) {
- try {
- // getPackageResourcePath is hidden in Context,
- // but exposed in ContextWrapper...
- ContextWrapper context =
- new ContextWrapper(createPackageContext(pkg, 0));
- ZipFile zipfile =
- new ZipFile(context.getPackageResourcePath());
- job = new UnpackJob(zipfile, new HashSet(1));
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Package " + pkg +
- " not found", e);
- continue;
- } catch (IOException e) {
- // FIXME: show some sort of GUI error dialog
- Log.e(LOG_TAG,
- "Error opening ZIP for package " + pkg, e);
- continue;
- }
- unpack_jobs.put(pkg, job);
- }
- job.paths.add(path);
- }
-
- // Delete stale filenames from mUnpackDest
- for (File file: mUnpackDest.listFiles()) {
- if (!all_files.contains(file.getName())) {
- Log.i(LOG_TAG,
- "Deleting stale cached file " + file);
- file.delete();
- }
- }
-
- int total_size = 0;
- for (UnpackJob job: unpack_jobs.values())
- total_size += job.UnpackSize();
-
- publishProgress(0, total_size);
-
- mUnpackDest.mkdirs();
-
- int progress = 0;
-
- for (UnpackJob job: unpack_jobs.values()) {
- try {
- ZipFile zipfile = job.zipfile;
- for (String path: job.paths) {
- ZipEntry zipentry = zipfile.getEntry(path);
- if (zipentry == null)
- throw new FileNotFoundException(
- "Couldn't find " + path + " in zip");
- File dest = new File(mUnpackDest, new File(path).getName());
- if (dest.exists() &&
- dest.lastModified() == zipentry.getTime() &&
- dest.length() == zipentry.getSize()) {
- // Already unpacked
- progress += zipentry.getSize();
- } else {
- if (dest.exists())
- Log.d(LOG_TAG,
- "Replacing " + dest.getPath() +
- " old.mtime=" + dest.lastModified() +
- " new.mtime=" + zipentry.getTime() +
- " old.size=" + dest.length() +
- " new.size=" + zipentry.getSize());
- else
- Log.i(LOG_TAG,
- "Extracting " + zipentry.getName() +
- " from " + zipfile.getName() +
- " to " + dest.getPath());
-
- long next_update = progress;
-
- InputStream in = zipfile.getInputStream(zipentry);
- OutputStream out = new FileOutputStream(dest);
- int len;
- byte[] buffer = new byte[4096];
- while ((len = in.read(buffer)) != -1) {
- out.write(buffer, 0, len);
- progress += len;
- if (progress >= next_update) {
- publishProgress(progress, total_size);
- // Arbitrary limit of 2% update steps
- next_update += total_size / 50;
- }
- }
-
- in.close();
- out.close();
- dest.setLastModified(zipentry.getTime());
- }
- publishProgress(progress, total_size);
- }
-
- zipfile.close();
- } catch (IOException e) {
- // FIXME: show some sort of GUI error dialog
- Log.e(LOG_TAG, "Error unpacking plugin", e);
- }
- }
-
- if (progress != total_size)
- Log.d(LOG_TAG, "Ended with progress " + progress +
- " != total size " + total_size);
-
- setResult(RESULT_OK);
-
- return null;
- }
- }
-
- private class PluginBroadcastReciever extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!intent.getAction()
- .equals(ScummVMApplication.ACTION_PLUGIN_QUERY)) {
- Log.e(LOG_TAG,
- "Received unexpected action " + intent.getAction());
- return;
- }
-
- Bundle extras = getResultExtras(false);
- if (extras == null) {
- // Nothing for us to do.
- Unpacker.this.setResult(RESULT_OK);
- finish();
- }
-
- ArrayList unpack_libs =
- extras.getStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS);
-
- if (unpack_libs != null && !unpack_libs.isEmpty()) {
- final String[] libs =
- unpack_libs.toArray(new String[unpack_libs.size()]);
- mUnpacker = new UnpackTask().execute(libs);
- }
- }
- }
-
- private void initPlugins() {
- Bundle extras = new Bundle(1);
-
- ArrayList unpack_libs = new ArrayList(1);
- // This is the common ScummVM code (not really a "plugin" as such)
- unpack_libs.add(new Uri.Builder()
- .scheme("plugin")
- .authority(getPackageName())
- .path("mylib/armeabi/libscummvm.so")
- .toString());
- extras.putStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS,
- unpack_libs);
-
- final PackageInfo info;
- try {
- info = getPackageManager().getPackageInfo(getPackageName(), 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Error finding my own info?", e);
- return;
- }
- extras.putString(ScummVMApplication.EXTRA_VERSION, info.versionName);
-
- Intent intent = new Intent(ScummVMApplication.ACTION_PLUGIN_QUERY);
- // Android 3.1 defaults to FLAG_EXCLUDE_STOPPED_PACKAGES, and since
- // none of our plugins will ever be running, that is not helpful
- intent.setFlags(FLAG_INCLUDE_STOPPED_PACKAGES);
- sendOrderedBroadcast(intent, Manifest.permission.SCUMMVM_PLUGIN,
- new PluginBroadcastReciever(),
- null, RESULT_OK, null, extras);
- }
-
- @Override
- public void onCreate(Bundle b) {
- super.onCreate(b);
-
- mUnpackDest = ScummVMApplication.getLastCacheDir();
-
- setContentView(R.layout.splash);
- mProgress = (ProgressBar)findViewById(R.id.progress);
-
- setResult(RESULT_CANCELED);
-
- tryUnpack();
- }
-
- private void tryUnpack() {
- Intent intent = new Intent(ScummVMApplication.ACTION_PLUGIN_QUERY);
- List plugins = getPackageManager()
- .queryBroadcastReceivers(intent, 0);
- if (PLUGINS_ENABLED && plugins.isEmpty()) {
- // No plugins installed
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.no_plugins_title)
- .setMessage(R.string.no_plugins_found)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- finish();
- }
- })
- .setNegativeButton(R.string.quit,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- });
-
- final Uri uri = Uri.parse("market://search?q=ScummVM plugin");
- final Intent market_intent = new Intent(Intent.ACTION_VIEW, uri);
- if (getPackageManager().resolveActivity(market_intent, 0) != null) {
- alert.setPositiveButton(R.string.to_market,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- try {
- startActivityForResult(market_intent,
- REQUEST_MARKET);
- } catch (ActivityNotFoundException e) {
- Log.e(LOG_TAG,
- "Error starting market", e);
- }
- }
- });
- }
-
- alert.show();
-
- } else {
- // Already have at least one plugin installed
- initPlugins();
- }
- }
-
- @Override
- public void onStop() {
- if (mUnpacker != null)
- mUnpacker.cancel(true);
- super.onStop();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
- switch (requestCode) {
- case REQUEST_MARKET:
- if (resultCode != RESULT_OK)
- Log.w(LOG_TAG, "Market returned " + resultCode);
- tryUnpack();
- break;
- }
- }
-
- private Bundle getMetaData() {
- try {
- ActivityInfo ai = getPackageManager()
- .getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
- return ai.metaData;
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(LOG_TAG, "Unable to find my own meta-data", e);
- return new Bundle();
- }
- }
-}
diff --git a/configure b/configure
index 7c4c87e3af..5f73d77242 100755
--- a/configure
+++ b/configure
@@ -4533,6 +4533,8 @@ WIN32PATH=$_win32path
AMIGAOSPATH=$_amigaospath
STATICLIBPATH=$_staticlibpath
+ABI := $ABI
+
BACKEND := $_backend
MODULES += $MODULES
MODULE_DIRS += $MODULE_DIRS
diff --git a/dists/android/AndroidManifest.xml b/dists/android/AndroidManifest.xml
index db8a9adc54..ba1046e85c 100644
--- a/dists/android/AndroidManifest.xml
+++ b/dists/android/AndroidManifest.xml
@@ -5,7 +5,6 @@
package="org.scummvm.scummvm"
android:versionCode="@ANDROID_VERSIONCODE@"
android:versionName="1.8.0git"
- android:installLocation="preferExternal"
android:sharedUserId="org.scummvm.scummvm">