aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Page2008-08-10 21:58:18 +0000
committerChristopher Page2008-08-10 21:58:18 +0000
commitfcc00f20b93d719c9f7bce848ed7c3600be982b9 (patch)
tree48b9fd1c842cb376985a91592ef7b062fed0cfa7
parentce3d1e1a7d9ec9860d3fc42d8127a1634051d950 (diff)
parent9d0b0523cf119fdc400bf477c2f9d6f4f37ddce6 (diff)
downloadscummvm-rg350-fcc00f20b93d719c9f7bce848ed7c3600be982b9.tar.gz
scummvm-rg350-fcc00f20b93d719c9f7bce848ed7c3600be982b9.tar.bz2
scummvm-rg350-fcc00f20b93d719c9f7bce848ed7c3600be982b9.zip
Merged revisions 33719,33721-33723,33725-33727,33729-33730,33733,33736,33742,33754,33756,33758,33761,33763,33766 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk svn-id: r33769
-rw-r--r--backends/platform/wii/Makefile97
-rw-r--r--backends/platform/wii/main.cpp4
-rw-r--r--backends/platform/wii/osystem.cpp6
-rw-r--r--backends/platform/wii/osystem.h4
-rw-r--r--backends/platform/wince/CEActionsPocket.cpp9
-rw-r--r--backends/platform/wince/CEActionsSmartphone.cpp9
-rw-r--r--backends/platform/wince/Makefile4
-rw-r--r--common/config-manager.cpp6
-rw-r--r--common/system.cpp18
-rw-r--r--dists/wii/READMII24
-rw-r--r--engines/agos/midi.cpp6
-rw-r--r--engines/cine/anim.cpp2
-rw-r--r--engines/cine/anim.h2
-rw-r--r--engines/cine/cine.cpp19
-rw-r--r--engines/cine/gfx.cpp55
-rw-r--r--engines/cine/main_loop.cpp4
-rw-r--r--engines/cine/object.cpp9
-rw-r--r--engines/cine/object.h15
-rw-r--r--engines/cine/various.cpp15
-rw-r--r--engines/cine/various.h4
-rw-r--r--engines/drascula/detection.cpp32
-rw-r--r--engines/drascula/drascula.cpp39
-rw-r--r--engines/drascula/saveload.cpp8
-rw-r--r--engines/kyra/kyra_hof.cpp33
-rw-r--r--engines/kyra/kyra_hof.h3
-rw-r--r--engines/kyra/kyra_lok.cpp6
-rw-r--r--engines/kyra/kyra_lok.h2
-rw-r--r--engines/kyra/kyra_mr.cpp10
-rw-r--r--engines/kyra/kyra_v1.h6
-rw-r--r--engines/kyra/staticres.cpp132
-rw-r--r--sound/midiparser.h6
-rw-r--r--sound/midiparser_xmidi.cpp66
32 files changed, 442 insertions, 213 deletions
diff --git a/backends/platform/wii/Makefile b/backends/platform/wii/Makefile
index a52ceb1774..d17a7cb41e 100644
--- a/backends/platform/wii/Makefile
+++ b/backends/platform/wii/Makefile
@@ -1,26 +1,32 @@
+# this enables port specific debug messages and redirects stdout/err over
+# usbgecko in memcard slot b
DEBUG_WII = 1
-ENABLE_SCUMM = 1
-ENABLE_SCUMM_7_8 = 1
-ENABLE_HE = 1
-# ENABLE_AGI = 1
-ENABLE_AGOS = 1
-ENABLE_CINE = 1
-ENABLE_CRUISE = 1
-ENABLE_DRASCULA = 1
-ENABLE_GOB = 1
-ENABLE_IGOR = 1
-ENABLE_KYRA = 1
-ENABLE_LURE = 1
-ENABLE_M4 = 1
-ENABLE_MADE = 1
-ENABLE_PARALLACTION = 1
-ENABLE_QUEEN = 1
-ENABLE_SAGA = 1
-ENABLE_SKY = 1
-ENABLE_SWORD1 = 1
-ENABLE_SWORD2 = 1
-ENABLE_TOUCHE = 1
+# builds a gamecube version. cleanup object files before flipping this
+GAMECUBE = 0
+
+ENABLE_SCUMM = STATIC_PLUGIN
+ENABLE_SCUMM_7_8 = STATIC_PLUGIN
+ENABLE_HE = STATIC_PLUGIN
+# ENABLE_AGI = STATIC_PLUGIN
+ENABLE_AGOS = STATIC_PLUGIN
+ENABLE_CINE = STATIC_PLUGIN
+ENABLE_CRUISE = STATIC_PLUGIN
+ENABLE_DRASCULA = STATIC_PLUGIN
+ENABLE_GOB = STATIC_PLUGIN
+ENABLE_IGOR = STATIC_PLUGIN
+ENABLE_KYRA = STATIC_PLUGIN
+ENABLE_LURE = STATIC_PLUGIN
+ENABLE_M4 = STATIC_PLUGIN
+ENABLE_MADE = STATIC_PLUGIN
+ENABLE_PARALLACTION = STATIC_PLUGIN
+ENABLE_QUEEN = STATIC_PLUGIN
+ENABLE_SAGA = STATIC_PLUGIN
+ENABLE_SKY = STATIC_PLUGIN
+ENABLE_SWORD1 = STATIC_PLUGIN
+ENABLE_SWORD2 = STATIC_PLUGIN
+ENABLE_TINSEL = STATIC_PLUGIN
+ENABLE_TOUCHE = STATIC_PLUGIN
DISABLE_HQ_SCALERS = 1
DISABLE_SCALERS = 1
@@ -30,7 +36,11 @@ USE_MAD = 1
USE_TREMOR = 1
USE_FLAC = 1
USE_MPEG2 = 1
+ifeq ($(GAMECUBE),1)
+USE_MT32EMU = 0
+else
USE_MT32EMU = 1
+endif
srcdir = ../../..
VPATH = $(srcdir)
@@ -54,21 +64,28 @@ MKDIR = mkdir -p
RM = rm -f
CP = cp -f
+ifeq ($(GAMECUBE),1)
+TARGET = scummvm-gc
+MACHDEP = -DGEKKO -DGAMECUBE -mogc -mcpu=750 -meabi -mhard-float \
+ -ffunction-sections -fdata-sections -fmodulo-sched
+LIBDIR = $(DEVKITPRO)/libogc/lib/cube
+LIBS = -lstdc++ -lfat -logc -lm
+else
TARGET = scummvm-wii
-
MACHDEP = -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float \
-ffunction-sections -fdata-sections -fmodulo-sched
+LIBDIR = $(DEVKITPRO)/libogc/lib/wii
+LIBS = -lstdc++ -lfat -lwiiuse -lbte -logc -lm
+endif
INCDIR = $(srcdir) . $(srcdir)/engines/ $(DEVKITPRO)/libogc/include
-LIBDIR = $(DEVKITPRO)/libogc/lib/wii
CXXFLAGS = -g -Os -Wall $(MACHDEP) -D__WII__ -Wno-multichar -Wno-long-long \
- -Wno-unknown-pragmas -Wno-reorder -fno-exceptions -fno-rtti
+ -Wno-unknown-pragmas -Wno-reorder -fno-exceptions -fno-rtti
CXXFLAGS += $(addprefix -I,$(INCDIR))
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(TARGET).elf.map
LDFLAGS += $(addprefix -L,$(LIBDIR))
-LIBS = -lstdc++ -lfat -lwiiuse -lbte -logc -lm
CXXFLAGS += -I$(DEVKITPRO)/3rd/wii/include
LDFLAGS += -L$(DEVKITPRO)/3rd/wii/lib
@@ -137,20 +154,26 @@ distclean: distclean-wii
distclean-wii:
@-$(RM) dist
+ifeq ($(GAMECUBE),1)
upload:
$(DEVKITPPC)/bin/wiiload $(TARGET).dol
+endif
dist:
- $(MKDIR) dist/apps/scummvm
- $(CP) $(TARGET).dol dist/apps/scummvm/boot.dol
- $(CP) $(DISTPATH)/meta.xml dist/apps/scummvm/
- $(CP) $(DISTPATH)/icon.png dist/apps/scummvm/
- $(CP) $(DISTPATH)/READMII dist/apps/scummvm/
- $(CP) $(srcdir)/AUTHORS dist/apps/scummvm/
- $(CP) $(srcdir)/COPYING dist/apps/scummvm/
- $(CP) $(srcdir)/COPYRIGHT dist/apps/scummvm/
- $(CP) $(srcdir)/NEWS dist/apps/scummvm/
- $(CP) $(srcdir)/README dist/apps/scummvm/
- $(CP) $(DIST_FILES_THEMES) dist/apps/scummvm/
- $(CP) $(DIST_FILES_ENGINEDATA) dist/apps/scummvm/
+ $(MKDIR) dist/scummvm
+ifeq ($(GAMECUBE),1)
+ $(CP) $(TARGET).dol dist/scummvm/
+else
+ $(CP) $(TARGET).dol dist/scummvm/boot.dol
+ $(CP) $(DISTPATH)/meta.xml dist/scummvm/
+ $(CP) $(DISTPATH)/icon.png dist/scummvm/
+ $(CP) $(DISTPATH)/READMII dist/scummvm/
+ $(CP) $(srcdir)/AUTHORS dist/scummvm/
+ $(CP) $(srcdir)/COPYING dist/scummvm/
+ $(CP) $(srcdir)/COPYRIGHT dist/scummvm/
+ $(CP) $(srcdir)/NEWS dist/scummvm/
+ $(CP) $(srcdir)/README dist/scummvm/
+ $(CP) $(DIST_FILES_THEMES) dist/scummvm/
+ $(CP) $(DIST_FILES_ENGINEDATA) dist/scummvm/
+endif
diff --git a/backends/platform/wii/main.cpp b/backends/platform/wii/main.cpp
index 5753ecefe4..8bb1bff904 100644
--- a/backends/platform/wii/main.cpp
+++ b/backends/platform/wii/main.cpp
@@ -62,7 +62,9 @@ int main(int argc, char *argv[]) {
printf("startup\n");
SYS_SetResetCallback(reset_cb);
+#ifndef GAMECUBE
SYS_SetPowerCallback(power_cb);
+#endif
if (!fatInitDefault()) {
printf("fatInitDefault failed\n");
@@ -75,7 +77,7 @@ int main(int argc, char *argv[]) {
if (!strcmp(buf, "fat:/"))
chdir("/apps/scummvm");
- //fatEnableReadAhead(PI_DEFAULT, 32, 128);
+ fatEnableReadAhead(PI_DEFAULT, 32, 128);
}
g_system = new OSystem_Wii();
diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp
index 9e708345c5..3ec32126f0 100644
--- a/backends/platform/wii/osystem.cpp
+++ b/backends/platform/wii/osystem.cpp
@@ -89,8 +89,12 @@ OSystem_Wii::~OSystem_Wii() {
void OSystem_Wii::initBackend() {
_startup_time = gettime();
+
+ char buf[MAXPATHLEN];
+ if (!getcwd(buf, MAXPATHLEN))
+ strcpy(buf, "/");
- _savefile = new DefaultSaveFileManager();
+ _savefile = new DefaultSaveFileManager(buf);
_mixer = new Audio::MixerImpl(this);
_timer = new DefaultTimerManager();
diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h
index 7fbc560b1a..71bf9bce2e 100644
--- a/backends/platform/wii/osystem.h
+++ b/backends/platform/wii/osystem.h
@@ -22,9 +22,9 @@
#ifndef _WII_OSYSTEM_H_
#define _WII_OSYSTEM_H_
-#include "common/system.h"
#include "base/main.h"
-
+#include "common/system.h"
+#include "common/fs.h"
#include "common/rect.h"
#include "common/events.h"
diff --git a/backends/platform/wince/CEActionsPocket.cpp b/backends/platform/wince/CEActionsPocket.cpp
index 932599004d..95047ecf5c 100644
--- a/backends/platform/wince/CEActionsPocket.cpp
+++ b/backends/platform/wince/CEActionsPocket.cpp
@@ -129,11 +129,13 @@ void CEActionsPocket::initInstanceGame() {
bool is_parallaction = (gameid == "parallaction");
bool is_lure = (gameid == "lure");
bool is_feeble = (gameid == "feeble");
+ bool is_drascula = (strncmp(gameid.c_str(), "drascula",8) == 0);
GUI_Actions::initInstanceGame();
// See if a right click mapping could be needed
- if (is_sword1 || is_sword2 || is_sky || is_queen || is_comi || is_gob || is_samnmax || is_cine || is_touche || is_parallaction)
+ if (is_sword1 || is_sword2 || is_sky || is_queen || is_comi || is_gob ||
+ is_samnmax || is_cine || is_touche || is_parallaction || is_drascula)
_right_click_needed = true;
// See if a "hide toolbar" mapping could be needed
@@ -153,7 +155,7 @@ void CEActionsPocket::initInstanceGame() {
} else if (is_sky) {
_action_enabled[POCKET_ACTION_SAVE] = true;
_key_action[POCKET_ACTION_SAVE].setKey(Common::ASCII_F5, SDLK_F5);
- } else if (is_cine) {
+ } else if (is_cine || is_drascula) {
_action_enabled[POCKET_ACTION_SAVE] = true;
_key_action[POCKET_ACTION_SAVE].setKey(Common::ASCII_F10, SDLK_F10); // F10
} else if (is_agi) {
@@ -171,7 +173,8 @@ void CEActionsPocket::initInstanceGame() {
// Skip
if (!is_cine && !is_parallaction)
_action_enabled[POCKET_ACTION_SKIP] = true;
- if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_saga || is_kyra || is_touche || is_lure || is_feeble)
+ if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob ||
+ is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula)
_key_action[POCKET_ACTION_SKIP].setKey(VK_ESCAPE);
else
_key_action[POCKET_ACTION_SKIP].setKey(KEY_ALL_SKIP);
diff --git a/backends/platform/wince/CEActionsSmartphone.cpp b/backends/platform/wince/CEActionsSmartphone.cpp
index 6877c343e3..dbcddac98c 100644
--- a/backends/platform/wince/CEActionsSmartphone.cpp
+++ b/backends/platform/wince/CEActionsSmartphone.cpp
@@ -119,11 +119,13 @@ void CEActionsSmartphone::initInstanceGame() {
bool is_parallaction = (gameid == "parallaction");
bool is_lure = (gameid == "lure");
bool is_feeble = (gameid == "feeble");
+ bool is_drascula = (strncmp(gameid.c_str(), "drascula",8) == 0);
GUI_Actions::initInstanceGame();
// See if a right click mapping could be needed
- if (is_sword1 || is_sword2 || is_sky || is_queen || is_comi || is_gob || is_samnmax || is_cine || is_touche || is_parallaction)
+ if (is_sword1 || is_sword2 || is_sky || is_queen || is_comi || is_gob ||
+ is_samnmax || is_cine || is_touche || is_parallaction || is_drascula)
_right_click_needed = true;
// Initialize keys for different actions
@@ -136,7 +138,7 @@ void CEActionsSmartphone::initInstanceGame() {
} else if (is_sky) {
_action_enabled[SMARTPHONE_ACTION_SAVE] = true;
_key_action[SMARTPHONE_ACTION_SAVE].setKey(Common::ASCII_F5, SDLK_F5);
- } else if (is_cine) {
+ } else if (is_cine || is_drascula) {
_action_enabled[SMARTPHONE_ACTION_SAVE] = true;
_key_action[SMARTPHONE_ACTION_SAVE].setKey(Common::ASCII_F10, SDLK_F10); //F10
} else if (is_agi) {
@@ -151,7 +153,8 @@ void CEActionsSmartphone::initInstanceGame() {
}
// Skip
_action_enabled[SMARTPHONE_ACTION_SKIP] = true;
- if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_saga || is_kyra || is_touche || is_lure || is_feeble)
+ if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob ||
+ is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula)
_key_action[SMARTPHONE_ACTION_SKIP].setKey(VK_ESCAPE);
else
_key_action[SMARTPHONE_ACTION_SKIP].setKey(KEY_ALL_SKIP);
diff --git a/backends/platform/wince/Makefile b/backends/platform/wince/Makefile
index 176971067e..4400d50e3a 100644
--- a/backends/platform/wince/Makefile
+++ b/backends/platform/wince/Makefile
@@ -34,9 +34,11 @@ ENABLE_SWORD1 = STATIC_PLUGIN
ENABLE_SWORD2 = STATIC_PLUGIN
ENABLE_TOUCHE = STATIC_PLUGIN
ENABLE_PARALLACTION = STATIC_PLUGIN
+ENABLE_DRASCULA = STATIC_PLUGIN
#ENABLE_CRUISE = STATIC_PLUGIN
-#ENABLE_DRASCULA = STATIC_PLUGIN
#ENABLE_IGOR = STATIC_PLUGIN
+#ENABLE_M4 = STATIC_PLUGIN
+#ENABLE_MADE = STATIC_PLUGIN
########################################################################
## Pick which libraries you want to use here
diff --git a/common/config-manager.cpp b/common/config-manager.cpp
index a424c4f6c7..138fcc201f 100644
--- a/common/config-manager.cpp
+++ b/common/config-manager.cpp
@@ -64,9 +64,9 @@ void ConfigManager::loadDefaultConfigFile() {
SeekableReadStream *stream = g_system->openConfigFileForReading();
_filename.clear(); // clear the filename to indicate that we are using the default config file
- // ... load it ...
- assert(stream);
- loadFromStream(*stream);
+ // ... load it, if available ...
+ if (stream)
+ loadFromStream(*stream);
// ... and close it again.
delete stream;
diff --git a/common/system.cpp b/common/system.cpp
index 3e07e4ac4c..d0548cdd2d 100644
--- a/common/system.cpp
+++ b/common/system.cpp
@@ -163,25 +163,15 @@ static Common::String getDefaultConfigFileName() {
}
Common::SeekableReadStream *OSystem::openConfigFileForReading() {
- Common::File *confFile = new Common::File();
- assert(confFile);
- if (!confFile->open(getDefaultConfigFileName())) {
- delete confFile;
- confFile = 0;
- }
- return confFile;
+ FilesystemNode file(getDefaultConfigFileName());
+ return file.openForReading();
}
Common::WriteStream *OSystem::openConfigFileForWriting() {
#ifdef __DC__
return 0;
#else
- Common::DumpFile *confFile = new Common::DumpFile();
- assert(confFile);
- if (!confFile->open(getDefaultConfigFileName())) {
- delete confFile;
- confFile = 0;
- }
- return confFile;
+ FilesystemNode file(getDefaultConfigFileName());
+ return file.openForWriting();
#endif
}
diff --git a/dists/wii/READMII b/dists/wii/READMII
index 4f157dffe7..87efe21d68 100644
--- a/dists/wii/READMII
+++ b/dists/wii/READMII
@@ -6,12 +6,18 @@ features not compiled in:
REQUIREMENTS
- - sd card
- - wiimote or gamecube controller in port 1
+ wii:
+ - sd card
+ - wiimote or gamecube controller in port 1
+
+ gamecube:
+ - sd card
+ - sd gecko adapter
+ - gamecube controller in port 1
INSTALL
- - copy the "apps" folder to the root of your sd card
+ - copy the "scummvm" folder into the "/apps" folder of your sd card
- copy your demos and/or games onto the same sd card
each game goes into its own subdirectory, do not place those under
"/apps/scummvm", and do not set the "theme" or "extra" path to that folder
@@ -20,17 +26,21 @@ INSTALL
RUN
- either use the homebrew channel, available at
+ wii:
+ either use the homebrew channel, available at
+
+ http://hbc.hackmii.com/
- http://hbc.hackmii.com/
+ or load "/apps/scummvm/boot.dol" with your favorite loader
- or load "boot.dol" with your favorite loader
+ gamecube:
+ load "/apps/scummvm/scummvm-gc.dol" with your favorite loader
CONTROLS
wiimote
- analog stick: mouse movement
+ IR: mouse movement
a: left mouse button
b: right mouse button
minus: escape
diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp
index 6d24c7db2c..fd0e4eaa9d 100644
--- a/engines/agos/midi.cpp
+++ b/engines/agos/midi.cpp
@@ -556,7 +556,11 @@ void MidiPlayer::loadXMIDI(Common::File *in, bool sfx) {
error("Expected 'FORM' tag but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]);
}
- MidiParser *parser = MidiParser::createParser_XMIDI();
+ // In the DOS version of Simon the Sorcerer 2, the music contains lots
+ // of XMIDI callback controller events. As far as we know, they aren't
+ // actually used, so we disable the callback handler explicitly.
+
+ MidiParser *parser = MidiParser::createParser_XMIDI(NULL);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
if (!parser->loadMusic(p->data, size))
diff --git a/engines/cine/anim.cpp b/engines/cine/anim.cpp
index c19435c59a..c2c815596e 100644
--- a/engines/cine/anim.cpp
+++ b/engines/cine/anim.cpp
@@ -49,7 +49,7 @@ struct AnimHeader2Struct {
uint16 field_E;
};
-AnimData animDataTable[NUM_MAX_ANIMDATA];
+Common::Array<AnimData> animDataTable;
static const AnimDataEntry transparencyData[] = {
{"ALPHA", 0xF},
diff --git a/engines/cine/anim.h b/engines/cine/anim.h
index 317654064b..8b1541eb3f 100644
--- a/engines/cine/anim.h
+++ b/engines/cine/anim.h
@@ -150,7 +150,7 @@ public:
#define NUM_MAX_ANIMDATA 255
-extern AnimData animDataTable[NUM_MAX_ANIMDATA];
+extern Common::Array<AnimData> animDataTable;
void freeAnimDataTable(void);
void freeAnimDataRange(byte startIdx, byte numIdx);
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 127d390f66..c30cac63a5 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -124,6 +124,22 @@ int CineEngine::modifyGameSpeed(int speedChange) {
}
void CineEngine::initialize() {
+ // Resize object table to its correct size and reset all its elements
+ objectTable.resize(NUM_MAX_OBJECT);
+ resetObjectTable();
+
+ // Resize animation data table to its correct size and reset all its elements
+ animDataTable.resize(NUM_MAX_ANIMDATA);
+ freeAnimDataTable();
+
+ // Resize zone data table to its correct size and reset all its elements
+ zoneData.resize(NUM_MAX_ZONE);
+ Common::set_to(zoneData.begin(), zoneData.end(), 0);
+
+ // Resize zone query table to its correct size and reset all its elements
+ zoneQuery.resize(NUM_MAX_ZONE);
+ Common::set_to(zoneQuery.begin(), zoneQuery.end(), 0);
+
_timerDelayMultiplier = 12; // Set default speed
setupOpcodes();
@@ -160,8 +176,7 @@ void CineEngine::initialize() {
freeAnimDataTable();
overlayList.clear();
messageTable.clear();
-
- memset(objectTable, 0, sizeof(objectTable));
+ resetObjectTable();
var8 = 0;
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
index b882c9760e..c6c5faf464 100644
--- a/engines/cine/gfx.cpp
+++ b/engines/cine/gfx.cpp
@@ -276,9 +276,11 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte colo
/*! \brief Draw rectangle on screen
* \param x Top left corner coordinate
* \param y Top left corner coordinate
- * \param width Rectangle width
- * \param height Rectangle height
+ * \param width Rectangle width (Negative values draw the box horizontally flipped)
+ * \param height Rectangle height (Negative values draw the box vertically flipped)
* \param color Fill color
+ * \note Rectangle's drawn width is always at least one.
+ * \note Rectangle's drawn height is always at least one.
*/
void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) {
int i;
@@ -313,12 +315,18 @@ void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) {
height = 0;
}
- // Draw the box if it's not empty
- if (width > 0 && height > 0) {
- byte *dest = _backBuffer + y * 320 + x;
- for (i = 0; i < height; i++) {
- memset(dest + i * 320, color, width);
- }
+ // Make width and height at least one
+ // which forces this function to always draw something.
+ // This fixes at least the showing of the oxygen gauge meter in
+ // Operation Stealth's first arcade sequence where this function
+ // is called with a height of zero.
+ width = MAX(1, width);
+ height = MAX(1, height);
+
+ // Draw the filled rectangle
+ byte *dest = _backBuffer + y * 320 + x;
+ for (i = 0; i < height; i++) {
+ memset(dest + i * 320, color, width);
}
}
@@ -428,7 +436,7 @@ void FWRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
switch (it->type) {
// color sprite
case 0:
- sprite = animDataTable + objectTable[it->objIdx].frame;
+ sprite = &animDataTable[objectTable[it->objIdx].frame];
len = sprite->_realWidth * sprite->_height;
mask = new byte[len];
memcpy(mask, sprite->mask(), len);
@@ -463,7 +471,7 @@ void FWRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
// bitmap
case 4:
assert(it->objIdx < NUM_MAX_OBJECT);
- obj = objectTable + it->objIdx;
+ obj = &objectTable[it->objIdx];
if (obj->frame < 0) {
return;
@@ -1066,7 +1074,7 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
if (objectTable[it->objIdx].frame < 0) {
break;
}
- sprite = animDataTable + objectTable[it->objIdx].frame;
+ sprite = &animDataTable[objectTable[it->objIdx].frame];
len = sprite->_realWidth * sprite->_height;
mask = new byte[len];
generateMask(sprite->data(), mask, len, objectTable[it->objIdx].part);
@@ -1099,8 +1107,8 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
case 20:
assert(it->objIdx < NUM_MAX_OBJECT);
var5 = it->x; // A global variable updated here!
- obj = objectTable + it->objIdx;
- sprite = animDataTable + obj->frame;
+ obj = &objectTable[it->objIdx];
+ sprite = &animDataTable[obj->frame];
if (obj->frame < 0 || it->x < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) {
break;
@@ -1109,13 +1117,24 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y);
break;
- // TODO: Figure out what this overlay type is and name it
- // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing)
+ // FIXME: Looking at Operation Stealth's disassembly I can't find any codepath that
+ // will draw a type 21 overlay. But looking at the first arcade sequence's scripts
+ // it looks like the oxygen gauge meter is implemented using a type 21 overlay.
+ // So for the time being I'm simply drawing type 21 overlays as type 22 overlays
+ // and hoping for the best.
+ // TODO: Check how the original game looks under DOSBox to see if the oxygen gauge works in it
+ case 21:
+ // A filled rectangle:
case 22: {
+ // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing).
assert(it->objIdx < NUM_MAX_OBJECT);
- obj = objectTable + it->objIdx;
- byte transCol = obj->part & 0x0F;
- drawPlainBox(obj->x, obj->y, obj->frame, obj->costume, transCol);
+ obj = &objectTable[it->objIdx];
+ byte color = obj->part & 0x0F;
+ int width = obj->frame;
+ int height = obj->costume;
+ drawPlainBox(obj->x, obj->y, width, height, color);
+ debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d",
+ it->type, obj->x, obj->y, width, height, color);
break;
}
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
index 9361eb3822..3b0dc80bfb 100644
--- a/engines/cine/main_loop.cpp
+++ b/engines/cine/main_loop.cpp
@@ -333,9 +333,7 @@ void CineEngine::mainLoop(int bootScriptIdx) {
// Clear the zoneQuery table (Operation Stealth specific)
if (g_cine->getGameType() == Cine::GType_OS) {
- for (uint i = 0; i < NUM_MAX_ZONE; i++) {
- zoneQuery[i] = 0;
- }
+ Common::set_to(zoneQuery.begin(), zoneQuery.end(), 0);
}
if (g_cine->getGameType() == Cine::GType_OS) {
diff --git a/engines/cine/object.cpp b/engines/cine/object.cpp
index c02e01c8ce..9781975f7c 100644
--- a/engines/cine/object.cpp
+++ b/engines/cine/object.cpp
@@ -35,9 +35,16 @@
namespace Cine {
-objectStruct objectTable[NUM_MAX_OBJECT];
+Common::Array<objectStruct> objectTable;
Common::List<overlay> overlayList;
+/*! \brief Resets all elements in the object table. */
+void resetObjectTable() {
+ for (Common::Array<objectStruct>::iterator it = objectTable.begin(); it != objectTable.end(); it++) {
+ it->clear();
+ }
+}
+
void loadObject(char *pObjectName) {
uint16 numEntry;
uint16 entrySize;
diff --git a/engines/cine/object.h b/engines/cine/object.h
index 7ad65eb75f..3bf6cdcc42 100644
--- a/engines/cine/object.h
+++ b/engines/cine/object.h
@@ -38,6 +38,17 @@ struct objectStruct {
int16 costume;
char name[20];
uint16 part;
+
+ /*! \brief Sets all member variables to zero. */
+ void clear() {
+ this->x = 0;
+ this->y = 0;
+ this->mask = 0;
+ this->frame = 0;
+ this->costume = 0;
+ memset(this->name, 0, sizeof(this->name));
+ this->part = 0;
+ }
};
struct overlay {
@@ -52,10 +63,10 @@ struct overlay {
#define NUM_MAX_OBJECT 255
#define NUM_MAX_VAR 255
-extern objectStruct objectTable[NUM_MAX_OBJECT];
-
+extern Common::Array<objectStruct> objectTable;
extern Common::List<overlay> overlayList;
+void resetObjectTable();
void loadObject(char *pObjectName);
void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint16 param4);
void modifyObjectParam(byte objIdx, byte paramIdx, int16 newValue);
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 0ead13e3ab..2fe2701e52 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -124,8 +124,8 @@ static const int16 canUseOnItemTable[] = { 1, 0, 0, 1, 1, 0, 0 };
CommandeType objectListCommand[20];
int16 objListTab[20];
-uint16 zoneData[NUM_MAX_ZONE];
-uint16 zoneQuery[NUM_MAX_ZONE]; //!< Only exists in Operation Stealth
+Common::Array<uint16> zoneData;
+Common::Array<uint16> zoneQuery; //!< Only exists in Operation Stealth
/*! \brief Move the player character using the keyboard
* \param x Negative values move left, positive right, zero not at all
@@ -616,16 +616,7 @@ void CineEngine::resetEngine() {
relTable.clear();
scriptTable.clear();
messageTable.clear();
-
- for (int i = 0; i < NUM_MAX_OBJECT; i++) {
- objectTable[i].x = 0;
- objectTable[i].y = 0;
- objectTable[i].part = 0;
- objectTable[i].name[0] = 0;
- objectTable[i].frame = 0;
- objectTable[i].mask = 0;
- objectTable[i].costume = 0;
- }
+ resetObjectTable();
globalVars.reset();
diff --git a/engines/cine/various.h b/engines/cine/various.h
index acab15e235..926a1821d9 100644
--- a/engines/cine/various.h
+++ b/engines/cine/various.h
@@ -127,8 +127,8 @@ struct SelectedObjStruct {
};
#define NUM_MAX_ZONE 16
-extern uint16 zoneData[NUM_MAX_ZONE];
-extern uint16 zoneQuery[NUM_MAX_ZONE];
+extern Common::Array<uint16> zoneData;
+extern Common::Array<uint16> zoneQuery;
void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 param5);
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index a426857fbd..9832d58294 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -195,6 +195,38 @@ static const DrasculaGameDescription gameDescriptions[] = {
},
},
+ {
+ // Drascula Spanish version (ScummVM repacked files)
+ {
+ "drascula",
+ 0,
+ {
+ {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
+ {"packet.004", 0, "a289d3cf80d50f25ec569b653248437e", 17205838},
+ {NULL, 0, NULL, 0}
+ },
+ Common::ES_ESP,
+ Common::kPlatformPC,
+ GF_PACKED
+ },
+ },
+
+ {
+ // Drascula Italian version (ScummVM repacked files)
+ {
+ "drascula",
+ 0,
+ {
+ {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
+ {"packet.005", 0, "f80e10e37000a2201eabf8dad82c7f64", 16184223},
+ {NULL, 0, NULL, 0}
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ GF_PACKED
+ },
+ },
+
{ AD_TABLE_END_MARKER }
};
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index 7c843892b6..2d24978f21 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -162,6 +162,12 @@ int DrasculaEngine::init() {
_textmisc = 0;
_textd1 = 0;
+ _color = 0;
+ blinking = 0;
+ leftMouseButton = 0;
+ rightMouseButton = 0;
+ *textName = 0;
+
if (!loadDrasculaDat())
return 1;
@@ -286,6 +292,8 @@ void DrasculaEngine::endChapter() {
bool DrasculaEngine::runCurrentChapter() {
int n;
+ rightMouseButton = 0;
+
if (_lang == kSpanish)
textSurface = extraSurface;
else
@@ -458,21 +466,44 @@ bool DrasculaEngine::runCurrentChapter() {
}
delay(25);
+#ifndef _WIN32_WCE
+ // FIXME
+ // This and the following #ifndefs disable the excess updateEvents() calls *within* the game loop.
+ // Events such as keypresses or mouse clicks are dropped on the ground with no processing
+ // by these calls. They are properly handled by the implicit call through getScan() below.
+ // It is not a good practice to not process events and indeed this created problems with synthesized
+ // events in the wince port.
updateEvents();
+#endif
if (menuScreen == 0 && takeObject == 1)
checkObjects();
+#ifdef _WIN32_WCE
+ if (rightMouseButton)
+ if (menuScreen) {
+#else
if (rightMouseButton == 1 && menuScreen == 1) {
+#endif
if (currentChapter == 2)
loadPic(menuBackground, backSurface);
else
loadPic(99, backSurface);
setPalette((byte *)&gamePalette);
menuScreen = 0;
+#ifndef _WIN32_WCE
+ // FIXME: This call here is in hope that it will catch the rightmouseup event so the
+ // next if block won't be executed. This too is not a good coding practice. I've recoded it
+ // with a mutual exclusive if block for the menu. I would commit this properly but I cannot test
+ // for other (see Desktop) ports right now.
updateEvents();
+#endif
+#ifdef _WIN32_WCE
+ } else {
+#else
}
if (rightMouseButton == 1 && menuScreen == 0) {
+#endif
characterMoved = 0;
if (trackProtagonist == 2)
trackProtagonist = 1;
@@ -485,7 +516,9 @@ bool DrasculaEngine::runCurrentChapter() {
else
loadPic("icons.alg", backSurface);
menuScreen = 1;
+#ifndef _WIN32_WCE
updateEvents();
+#endif
withoutVerb();
}
@@ -671,7 +704,11 @@ void DrasculaEngine::updateEvents() {
AudioCD.updateCD();
+#ifdef _WIN32_WCE
+ if (eventMan->pollEvent(event)) {
+#else
while (eventMan->pollEvent(event)) {
+#endif
switch (event.type) {
case Common::EVENT_KEYDOWN:
_keyPressed = event.kbd;
@@ -989,7 +1026,7 @@ void DrasculaEngine::freeTexts(char ***ptr) {
for (int lang = 0; lang < _numLangs; lang++) {
if (ptr[lang]) {
- free(ptr[lang][0] - DATAALIGNMENT);
+ free(ptr[lang][0]);
free(ptr[lang]);
}
}
diff --git a/engines/drascula/saveload.cpp b/engines/drascula/saveload.cpp
index de82899462..6f88a58fbb 100644
--- a/engines/drascula/saveload.cpp
+++ b/engines/drascula/saveload.cpp
@@ -59,6 +59,8 @@ bool DrasculaEngine::saveLoadScreen() {
select[0] = 0;
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+
for (;;) {
y = 27;
copyBackground(0, 0, 0, 0, 320, 200, bgSurface, screenSurface);
@@ -140,8 +142,10 @@ bool DrasculaEngine::saveLoadScreen() {
}
if (mouseX > 125 && mouseY > 123 && mouseX < 199 && mouseY < 149 && selectionMade == 1) {
- if (!loadGame(file))
+ if (!loadGame(file)) {
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
return false;
+ }
break;
} else if (mouseX > 208 && mouseY > 123 && mouseX < 282 && mouseY < 149 && selectionMade == 1) {
saveGame(file);
@@ -172,6 +176,8 @@ bool DrasculaEngine::saveLoadScreen() {
loadPic(roomNumber, bgSurface, HALF_PAL);
selectionMade = 0;
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+
return true;
}
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 0c9b117866..0722fb262b 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -196,14 +196,18 @@ void KyraEngine_HoF::pauseEngineIntern(bool pause) {
_seqWsaChatTimeout += pausedTime;
_seqWsaChatFrameTimeout += pausedTime;
- for (int x = 0; x < 10; x++) {
- if (_activeText[x].duration != -1)
- _activeText[x].startTime += pausedTime;
+ if (_activeText) {
+ for (int x = 0; x < 10; x++) {
+ if (_activeText[x].duration != -1)
+ _activeText[x].startTime += pausedTime;
+ }
}
- for (int x = 0; x < 8; x++) {
- if (_activeWSA[x].flags != -1)
- _activeWSA[x].nextFrame += pausedTime;
+ if (_activeWSA) {
+ for (int x = 0; x < 8; x++) {
+ if (_activeWSA[x].flags != -1)
+ _activeWSA[x].nextFrame += pausedTime;
+ }
}
_nextIdleAnim += pausedTime;
@@ -1505,15 +1509,19 @@ void KyraEngine_HoF::openTalkFile(int newFile) {
_oldTalkFile = -1;
}
- if (newFile == 0) {
+ if (newFile == 0)
strcpy(talkFilename, "ANYTALK.TLK");
- _res->loadPakFile(talkFilename);
- } else {
+ else
sprintf(talkFilename, "CH%dVOC.TLK", newFile);
- _res->loadPakFile(talkFilename);
- }
_oldTalkFile = newFile;
+
+ if (!_res->loadPakFile(talkFilename)) {
+ if (speechEnabled()) {
+ warning("Couldn't load file '%s' falling back to text only mode", talkFilename);
+ _configVoice = 0;
+ }
+ }
}
void KyraEngine_HoF::snd_playVoiceFile(int id) {
@@ -1549,7 +1557,8 @@ void KyraEngine_HoF::playVoice(int high, int low) {
if (!_flags.isTalkie)
return;
int vocFile = high * 10000 + low * 10;
- snd_playVoiceFile(vocFile);
+ if (speechEnabled())
+ snd_playVoiceFile(vocFile);
}
void KyraEngine_HoF::snd_playSoundEffect(int track, int volume) {
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index 279e9e35a6..f6e887c648 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -302,8 +302,7 @@ protected:
static const int8 _dosTrackMap[];
static const int _dosTrackMapSize;
- const AudioDataStruct *_soundData;
-
+ AudioDataStruct _soundData[3];
protected:
// game initialization
void startup();
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index f668ae8401..afd164958c 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -173,8 +173,7 @@ int KyraEngine_LoK::init() {
initStaticResource();
- if (_soundData)
- _sound->setSoundList(&_soundData[kMusicIntro]);
+ _sound->setSoundList(&_soundData[kMusicIntro]);
_trackMap = _dosTrackMap;
_trackMapSize = _dosTrackMapSize;
@@ -317,8 +316,7 @@ void KyraEngine_LoK::startup() {
debugC(9, kDebugLevelMain, "KyraEngine_LoK::startup()");
static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 };
_screen->setTextColorMap(colorMap);
- if (_soundData)
- _sound->setSoundList(&_soundData[kMusicIngame]);
+ _sound->setSoundList(&_soundData[kMusicIngame]);
_sound->loadSoundFile(0);
// _screen->setFont(Screen::FID_6_FNT);
_screen->setAnimBlockPtr(3750);
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index cb3062847e..1def95ddbf 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -633,7 +633,7 @@ protected:
int _soundFilesIntroSize;
const int32 *_cdaTrackTable;
int _cdaTrackTableSize;
- const AudioDataStruct * _soundData;
+ AudioDataStruct _soundData[3];
// positions of the inventory
static const uint16 _itemPosX[];
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 7097543750..45a277c400 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -508,7 +508,8 @@ void KyraEngine_MR::snd_playVoiceFile(int file) {
char filename[16];
snprintf(filename, 16, "%.08u", (uint)file);
- _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255);
+ if (speechEnabled())
+ _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255);
}
bool KyraEngine_MR::snd_voiceIsPlaying() {
@@ -802,7 +803,12 @@ void KyraEngine_MR::openTalkFile(int file) {
}
_currentTalkFile = file;
- _res->loadPakFile(talkFilename);
+ if (!_res->loadPakFile(talkFilename)) {
+ if (speechEnabled()) {
+ warning("Couldn't load file '%s' falling back to text only mode", talkFilename);
+ _configVoice = 0;
+ }
+ }
}
#pragma mark -
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 6d61bd997f..f4f845c5f7 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -70,9 +70,9 @@ enum {
struct AudioDataStruct {
const char * const *_fileList;
- const int _fileListLen;
- const void * const _cdaTracks;
- const int _cdaNumTracks;
+ int _fileListLen;
+ const void * _cdaTracks;
+ int _cdaNumTracks;
};
// TODO: this is just the start of makeing the debug output of the kyra engine a bit more useable
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 7d7f0cd4b8..bb63c24c36 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -1055,32 +1055,48 @@ void KyraEngine_LoK::initStaticResource() {
static const char *tIntro98[] = { "intro%d.dat" };
static const char *tIngame98[] = { "kyram%d.dat" };
- static const AudioDataStruct soundData_PC[] = {
- { _soundFilesIntro, _soundFilesIntroSize, 0, 0 },
- { _soundFiles, _soundFilesSize, 0, 0 },
- { 0, 0, 0, 0}
- };
-
- static const AudioDataStruct soundData_TOWNS[] = {
- { _soundFiles, _soundFilesSize, _cdaTrackTable, _cdaTrackTableSize },
- { _soundFiles, _soundFilesSize, _cdaTrackTable, _cdaTrackTableSize },
- { 0, 0, 0, 0}
- };
-
- static const AudioDataStruct soundData_PC98[] = {
- { tIntro98, 1, 0, 0 },
- { tIngame98, 1, 0, 0 },
- { 0, 0, 0, 0}
- };
-
- if (_flags.platform == Common::kPlatformPC)
- _soundData = soundData_PC;
- else if (_flags.platform == Common::kPlatformFMTowns)
- _soundData = soundData_TOWNS;
- else if (_flags.platform == Common::kPlatformPC98)
- _soundData = soundData_PC98;
- else
- _soundData = 0;
+ if (_flags.platform == Common::kPlatformPC) {
+ _soundData[0]._fileList = _soundFilesIntro;
+ _soundData[0]._fileListLen = _soundFilesIntroSize;
+ _soundData[0]._cdaTracks = 0;
+ _soundData[0]._cdaNumTracks = 0;
+ _soundData[1]._fileList = _soundFiles;
+ _soundData[1]._fileListLen = _soundFilesSize;
+ _soundData[1]._cdaTracks = 0;
+ _soundData[1]._cdaNumTracks = 0;
+ _soundData[2]._fileList = 0;
+ _soundData[2]._fileListLen = 0;
+ _soundData[2]._cdaTracks = 0;
+ _soundData[2]._cdaNumTracks = 0;
+ } else if (_flags.platform == Common::kPlatformFMTowns) {
+ _soundData[0]._fileList = _soundFiles;
+ _soundData[0]._fileListLen = _soundFilesSize;
+ _soundData[0]._cdaTracks = _cdaTrackTable;
+ _soundData[0]._cdaNumTracks = _cdaTrackTableSize;
+ _soundData[1]._fileList = _soundFiles;
+ _soundData[1]._fileListLen = _soundFilesSize;
+ _soundData[1]._cdaTracks = _cdaTrackTable;
+ _soundData[1]._cdaNumTracks = _cdaTrackTableSize;
+ _soundData[2]._fileList = 0;
+ _soundData[2]._fileListLen = 0;
+ _soundData[2]._cdaTracks = 0;
+ _soundData[2]._cdaNumTracks = 0;
+ } else if (_flags.platform == Common::kPlatformPC98) {
+ _soundData[0]._fileList = tIntro98;
+ _soundData[0]._fileListLen = 1;
+ _soundData[0]._cdaTracks = 0;
+ _soundData[0]._cdaNumTracks = 0;
+ _soundData[1]._fileList = tIngame98;
+ _soundData[1]._fileListLen = 1;
+ _soundData[1]._cdaTracks = 0;
+ _soundData[1]._cdaNumTracks = 0;
+ _soundData[2]._fileList = 0;
+ _soundData[2]._fileListLen = 0;
+ _soundData[2]._cdaTracks = 0;
+ _soundData[2]._cdaNumTracks = 0;
+ } else {
+ memset(_soundData, 0, sizeof(_soundData));
+ }
}
void KyraEngine_LoK::loadMouseShapes() {
@@ -1282,30 +1298,46 @@ void KyraEngine_HoF::initStaticResource() {
static const char *pc98MusicFileListFinale[] = { "finale%d.86" };
static const char *pc98MusicFileListIngame[] = { "km%02d.86" };
- static const AudioDataStruct soundData_PC[] = {
- { _musicFileListIntro, _musicFileListIntroSize, 0, 0 },
- { _musicFileListIngame, _musicFileListIngameSize, 0, 0},
- { _musicFileListFinale, _musicFileListIntroSize, 0, 0 }
- };
-
- static const AudioDataStruct soundData_TOWNS[] = {
- { fmtMusicFileListIntro, 1, _cdaTrackTableIntro, _cdaTrackTableIntroSize >> 1 },
- { fmtMusicFileListIngame, 1, _cdaTrackTableIngame, _cdaTrackTableIngameSize >> 1 },
- { fmtMusicFileListFinale, 1, _cdaTrackTableFinale, _cdaTrackTableFinaleSize >> 1 }
- };
-
- static const AudioDataStruct soundData_PC98[] = {
- { pc98MusicFileListIntro, 1, 0, 0 },
- { pc98MusicFileListIngame, 1, 0, 0 },
- { pc98MusicFileListFinale, 1, 0, 0 }
- };
-
- if (_flags.platform == Common::kPlatformPC)
- _soundData = soundData_PC;
- else if (_flags.platform == Common::kPlatformFMTowns)
- _soundData = soundData_TOWNS;
- else if (_flags.platform == Common::kPlatformPC98)
- _soundData = soundData_PC98;
+ if (_flags.platform == Common::kPlatformPC) {
+ _soundData[0]._fileList = _musicFileListIntro;
+ _soundData[0]._fileListLen = _musicFileListIntroSize;
+ _soundData[0]._cdaTracks = 0;
+ _soundData[0]._cdaNumTracks = 0;
+ _soundData[1]._fileList = _musicFileListIngame;
+ _soundData[1]._fileListLen = _musicFileListIngameSize;
+ _soundData[1]._cdaTracks = 0;
+ _soundData[1]._cdaNumTracks = 0;
+ _soundData[2]._fileList = _musicFileListFinale;
+ _soundData[2]._fileListLen = _musicFileListIntroSize;
+ _soundData[2]._cdaTracks = 0;
+ _soundData[2]._cdaNumTracks = 0;
+ } else if (_flags.platform == Common::kPlatformFMTowns) {
+ _soundData[0]._fileList = fmtMusicFileListIntro;
+ _soundData[0]._fileListLen = 1;
+ _soundData[0]._cdaTracks = _cdaTrackTableIntro;
+ _soundData[0]._cdaNumTracks = _cdaTrackTableIntroSize >> 1;
+ _soundData[1]._fileList = fmtMusicFileListIngame;
+ _soundData[1]._fileListLen = 1;
+ _soundData[1]._cdaTracks = _cdaTrackTableIngame;
+ _soundData[1]._cdaNumTracks = _cdaTrackTableIngameSize >> 1;
+ _soundData[2]._fileList = fmtMusicFileListFinale;
+ _soundData[2]._fileListLen = 1;
+ _soundData[2]._cdaTracks = _cdaTrackTableFinale;
+ _soundData[2]._cdaNumTracks = _cdaTrackTableFinaleSize >> 1;
+ } else if (_flags.platform == Common::kPlatformPC98) {
+ _soundData[0]._fileList = pc98MusicFileListIntro;
+ _soundData[0]._fileListLen = 1;
+ _soundData[0]._cdaTracks = 0;
+ _soundData[0]._cdaNumTracks = 0;
+ _soundData[1]._fileList = pc98MusicFileListIngame;
+ _soundData[1]._fileListLen = 1;
+ _soundData[1]._cdaTracks = 0;
+ _soundData[1]._cdaNumTracks = 0;
+ _soundData[2]._fileList = pc98MusicFileListFinale;
+ _soundData[2]._fileListLen = 1;
+ _soundData[2]._cdaTracks = 0;
+ _soundData[2]._cdaNumTracks = 0;
+ }
// setup sequence data
_sequences = _staticres->loadHofSequenceData(k2SeqplaySeqData, tmpSize);
diff --git a/sound/midiparser.h b/sound/midiparser.h
index d5209acb10..304a9d9f82 100644
--- a/sound/midiparser.h
+++ b/sound/midiparser.h
@@ -352,6 +352,8 @@ public:
};
public:
+ typedef void (*XMidiCallbackProc)(byte eventData, void *refCon);
+
MidiParser();
virtual ~MidiParser() { allNotesOff(); }
@@ -370,8 +372,10 @@ public:
uint32 getPPQN() { return _ppqn; }
virtual uint32 getTick() { return _position._play_tick; }
+ static void defaultXMidiCallback(byte eventData, void *refCon);
+
static MidiParser *createParser_SMF();
- static MidiParser *createParser_XMIDI();
+ static MidiParser *createParser_XMIDI(XMidiCallbackProc proc = defaultXMidiCallback, void *refCon = 0);
static void timerCallback(void *data) { ((MidiParser *) data)->onTimer(); }
};
diff --git a/sound/midiparser_xmidi.cpp b/sound/midiparser_xmidi.cpp
index abc1e20076..0180322927 100644
--- a/sound/midiparser_xmidi.cpp
+++ b/sound/midiparser_xmidi.cpp
@@ -46,13 +46,16 @@ protected:
Loop _loop[4];
int _loopCount;
+ XMidiCallbackProc _callbackProc;
+ void *_callbackData;
+
protected:
uint32 readVLQ2(byte * &data);
void resetTracking();
void parseNextEvent(EventInfo &info);
public:
- MidiParser_XMIDI() : _inserted_delta(0) {}
+ MidiParser_XMIDI(XMidiCallbackProc proc, void *data) : _inserted_delta(0), _callbackProc(proc), _callbackData(data) {}
~MidiParser_XMIDI() { }
bool loadMusic(byte *data, uint32 size);
@@ -103,23 +106,22 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) {
info.basic.param1 = *(_position._play_pos++);
info.basic.param2 = *(_position._play_pos++);
+ // This isn't a full XMIDI implementation, but it should
+ // hopefully be "good enough" for most things.
+
+ switch (info.basic.param1) {
// Simplified XMIDI looping.
- //
- // I would really like to turn the loop events into some sort
- // of NOP event (perhaps a dummy META event?), but for now we
- // just pass them on to the MIDI driver. That has worked in the
- // past, so it shouldn't cause any actual damage...
-
- if (info.basic.param1 == 0x74) {
- // XMIDI_CONTROLLER_FOR_LOOP
- byte *pos = _position._play_pos;
- if (_loopCount < ARRAYSIZE(_loop) - 1)
- _loopCount++;
-
- _loop[_loopCount].pos = pos;
- _loop[_loopCount].repeat = info.basic.param2;
- } else if (info.basic.param1 == 0x75) {
- // XMIDI_CONTROLLER_NEXT_BREAK
+ case 0x74: { // XMIDI_CONTROLLER_FOR_LOOP
+ byte *pos = _position._play_pos;
+ if (_loopCount < ARRAYSIZE(_loop) - 1)
+ _loopCount++;
+
+ _loop[_loopCount].pos = pos;
+ _loop[_loopCount].repeat = info.basic.param2;
+ break;
+ }
+
+ case 0x75: // XMIDI_CONTORLLER_NEXT_BREAK
if (_loopCount >= 0) {
if (info.basic.param2 < 64) {
// End the current loop.
@@ -133,10 +135,26 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) {
}
}
}
- } else if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) {
- warning("Unsupported XMIDI controller %d (0x%2x)",
- info.basic.param1, info.basic.param1);
+ break;
+
+ case 0x77: // XMIDI_CONTROLLER_CALLBACK_TRIG
+ if (_callbackProc)
+ _callbackProc(info.basic.param2, _callbackData);
+ break;
+
+ default:
+ if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) {
+ warning("Unsupported XMIDI controller %d (0x%2x)",
+ info.basic.param1, info.basic.param1);
+ }
+ break;
}
+
+ // Should we really keep passing the XMIDI controller events to
+ // the MIDI driver, or should we turn them into some kind of
+ // NOP events? (Dummy meta events, perhaps?) Ah well, it has
+ // worked so far, so it shouldn't cause any damage...
+
break;
case 0xF: // Meta or SysEx event
@@ -336,4 +354,10 @@ void MidiParser_XMIDI::resetTracking() {
_inserted_delta = 0;
}
-MidiParser *MidiParser::createParser_XMIDI() { return new MidiParser_XMIDI; }
+void MidiParser::defaultXMidiCallback(byte eventData, void *data) {
+ warning("MidiParser: defaultXMidiCallback(%d)", eventData);
+}
+
+MidiParser *MidiParser::createParser_XMIDI(XMidiCallbackProc proc, void *data) {
+ return new MidiParser_XMIDI(proc, data);
+}