aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS7
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp4
-rw-r--r--backends/graphics/opengl/pipelines/shader.cpp4
-rw-r--r--backends/graphics/opengl/shader.cpp5
-rw-r--r--backends/graphics/opengl/texture.cpp1
-rw-r--r--devtools/scumm-md5.txt2
-rw-r--r--doc/de/Neues8
-rw-r--r--engines/agi/agi.cpp8
-rw-r--r--engines/agi/op_cmd.cpp6
-rw-r--r--engines/agi/op_test.cpp4
-rw-r--r--engines/agi/preagi_mickey.cpp4
-rw-r--r--engines/agi/preagi_winnie.cpp2
-rw-r--r--engines/agi/saveload.cpp2
-rw-r--r--engines/agi/text.cpp4
-rw-r--r--engines/agos/string.cpp6
-rw-r--r--engines/agos/string_pn.cpp2
-rw-r--r--engines/cge2/vga13h.cpp5
-rw-r--r--engines/cruise/ctp.cpp2
-rw-r--r--engines/cruise/dataLoader.cpp11
-rw-r--r--engines/fullpipe/statics.cpp3
-rw-r--r--engines/lastexpress/entities/gendarmes.cpp2
-rw-r--r--engines/lastexpress/sound/entry.cpp2
-rw-r--r--engines/lure/game.cpp10
-rw-r--r--engines/lure/hotspots.cpp20
-rw-r--r--engines/lure/scripts.cpp6
-rw-r--r--engines/made/database.cpp1
-rw-r--r--engines/made/made.cpp15
-rw-r--r--engines/made/pmvplayer.cpp5
-rw-r--r--engines/made/redreader.cpp2
-rw-r--r--engines/made/resource.cpp4
-rw-r--r--engines/made/screen.cpp2
-rw-r--r--engines/made/sound.cpp5
-rw-r--r--engines/mads/mads.cpp1
-rw-r--r--engines/mortevielle/mortevielle.cpp1
-rw-r--r--engines/parallaction/objects.cpp2
-rw-r--r--engines/parallaction/parallaction.cpp4
-rw-r--r--engines/parallaction/parallaction_br.cpp2
-rw-r--r--engines/saga/isomap.cpp17
-rw-r--r--engines/saga/puzzle.cpp5
-rw-r--r--engines/saga/saveload.cpp2
-rw-r--r--engines/sci/detection_tables.h121
-rw-r--r--engines/scumm/detection.cpp5
-rw-r--r--engines/scumm/detection_tables.h2
-rw-r--r--engines/scumm/he/intern_he.h7
-rw-r--r--engines/scumm/he/logic/moonbase_logic.cpp (renamed from engines/scumm/he/logic/moonbase.cpp)88
-rw-r--r--engines/scumm/he/moonbase/moonbase.cpp179
-rw-r--r--engines/scumm/he/moonbase/moonbase.h99
-rw-r--r--engines/scumm/he/moonbase/moonbase_fow.cpp410
-rw-r--r--engines/scumm/he/script_v100he.cpp1
-rw-r--r--engines/scumm/he/sound_he.cpp4
-rw-r--r--engines/scumm/he/sprite_he.cpp14
-rw-r--r--engines/scumm/he/sprite_he.h2
-rw-r--r--engines/scumm/he/wiz_he.cpp321
-rw-r--r--engines/scumm/he/wiz_he.h50
-rw-r--r--engines/scumm/module.mk6
-rw-r--r--engines/scumm/scumm-md5.h4
-rw-r--r--engines/scumm/scumm.cpp10
-rw-r--r--engines/sherlock/tattoo/tattoo_fixed_text.h2
-rw-r--r--engines/sherlock/tattoo/tattoo_journal.cpp46
-rw-r--r--engines/sherlock/tattoo/tattoo_people.h3
-rw-r--r--engines/sky/control.cpp2
-rw-r--r--engines/sword2/screen.cpp4
-rw-r--r--engines/sword25/gfx/image/vectorimage.cpp1
-rw-r--r--engines/sword25/gfx/renderobject.cpp29
-rw-r--r--engines/teenagent/music.cpp4
-rw-r--r--engines/teenagent/music.h1
-rw-r--r--engines/teenagent/objects.h4
-rw-r--r--engines/teenagent/scene.cpp27
-rw-r--r--engines/teenagent/scene.h4
-rw-r--r--engines/teenagent/teenagent.cpp7
-rw-r--r--engines/tinsel/bmv.cpp4
-rw-r--r--engines/tinsel/detection.cpp4
-rw-r--r--engines/tinsel/dialogs.cpp22
-rw-r--r--engines/tinsel/handle.cpp2
-rw-r--r--engines/tinsel/saveload.cpp2
-rw-r--r--engines/toltecs/movie.cpp2
-rw-r--r--engines/toltecs/resource.cpp1
-rw-r--r--engines/toltecs/sprite.cpp3
-rw-r--r--engines/tony/gfxcore.cpp14
-rw-r--r--engines/tony/mpal/loadmpc.cpp2
-rw-r--r--engines/tony/mpal/mpal.cpp41
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp2
-rw-r--r--engines/wage/macmenu.cpp3
-rw-r--r--engines/wage/macwindow.cpp2
-rw-r--r--engines/wintermute/base/base_engine.cpp2
-rw-r--r--gui/widgets/popup.cpp2
-rw-r--r--po/de_DE.po6
87 files changed, 1523 insertions, 246 deletions
diff --git a/NEWS b/NEWS
index d06b874819..adba723022 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,13 @@ For a more comprehensive changelog of the latest experimental code, see:
Gob:
- Fixed lock up for some games during sound initialization.
+ KYRA:
+ - Fixed potential crash when using swamp snake potion on the rat in Hand
+ of Fate. (NOTE: This fix was included in version 1.8.0, but it was not
+ added to the NEWS file).
+ - Fixed missing voice reactions when hitting enemies in CD version of
+ Lands of Lore.
+
Lab:
- Fixed lock-up during ending sequence.
- Improved internal game controls.
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
index 685ee99e6f..d536429f4e 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
@@ -1043,12 +1043,12 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
if (value & 0x10) {
_timers[0].smpTillCb = _timers[0].smpPerCb;
- _timers[0].smpTillCbRem = _timers[0].smpTillCbRem;
+ _timers[0].smpTillCbRem = _timers[0].smpPerCbRem;
}
if (value & 0x20) {
_timers[1].smpTillCb = _timers[1].smpPerCb;
- _timers[1].smpTillCbRem = _timers[1].smpTillCbRem;
+ _timers[1].smpTillCbRem = _timers[1].smpPerCbRem;
}
} else if (l == 2) {
// LFO
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
index 8e38458f73..a2dabb7c22 100644
--- a/backends/graphics/opengl/pipelines/shader.cpp
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -56,6 +56,8 @@ void ShaderPipeline::activateInternal() {
}
_activeShader->activate();
+
+ GL_CALL(glVertexAttribPointer(_colorAttribLocation, 4, GL_FLOAT, GL_FALSE, 0, _colorAttributes));
}
void ShaderPipeline::deactivateInternal() {
@@ -74,8 +76,6 @@ void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
*dst++ = b;
*dst++ = a;
}
-
- GL_CALL(glVertexAttribPointer(_colorAttribLocation, 4, GL_FLOAT, GL_FALSE, 0, _colorAttributes));
}
void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 27981f25dc..0b4c677d70 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -37,7 +37,7 @@ namespace {
#pragma mark - Builtin Shader Sources -
-const char *const g_defaultVertexShader =
+const char *const g_defaultVertexShader =
"attribute vec4 position;\n"
"attribute vec2 texCoordIn;\n"
"attribute vec4 blendColorIn;\n"
@@ -286,6 +286,9 @@ GLshader Shader::compileShader(const char *source, GLenum shaderType) {
}
ShaderManager::ShaderManager() : _initializeShaders(true) {
+ for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
+ _builtIn[i] = nullptr;
+ }
}
ShaderManager::~ShaderManager() {
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 8b94549971..33598b5488 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -509,6 +509,7 @@ TextureCLUT8GPU::TextureCLUT8GPU()
// Setup pipeline.
_clut8Pipeline->setFramebuffer(_target);
_clut8Pipeline->setPaletteTexture(&_paletteTexture);
+ _clut8Pipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
}
TextureCLUT8GPU::~TextureCLUT8GPU() {
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 235986a878..92754a27b4 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -237,6 +237,7 @@ monkey The Secret of Monkey Island
71523b539491527d9860f4407faf0411 7607 en DOS Demo EGA Demo - Fingolfin
771bc18ec6f93837b839c992b211904b -1 de DOS Demo EGA Demo - khalek
54a936ad06161ff7bfefcb96200f7bff 7617 en Amiga VGA VGA Demo - khalek
+ c0c9de81fb965e6cbe77f6e5631ca705 9135 en DOS SE Talkie Unofficial SE Talkie v1.02 rootfather
pass Passport to Adventure
e6cd81b25ab1453a8a6d3482118c391e 7857 en DOS - - v1.0 9/14/90 Fingolfin
@@ -269,6 +270,7 @@ monkey2 Monkey Island 2: LeChuck's Revenge
430bc518017b6fac046f58bab6baad5d -1 jp FM-TOWNS FM-TOWNS - - Antti Leimi, Andrea Petrucci
387a544b8b10b26912d8413bab63a853 -1 en DOS - Demo non-interactive khalek
+ f4d20ab4ce19743a646cb48bd93aee72 10835 en DOS SE Talkie Unofficial SE Talkie v0.2 rootfather
atlantis Indiana Jones and the Fate of Atlantis
3a03dab514e4038df192d8a8de469788 -1 en Amiga Floppy Floppy - dhewg
diff --git a/doc/de/Neues b/doc/de/Neues
index 530e2270f8..e3d8f3a607 100644
--- a/doc/de/Neues
+++ b/doc/de/Neues
@@ -40,6 +40,14 @@ Programmcodes finden Sie auf Englisch unter:
Gob:
- Aufhängen während Sound-Initialisierung in mehreren Spielen behoben.
+ KYRA:
+ - Potentieller Absturz behoben, der in "Hand of Fate" auftritt, wenn der
+ Sumpfschlangentrank an der Ratte verwendet wird.
+ (HINWEIS: Dieser Fehler wurde bereits in Version 1.8.0 behoben,
+ jedoch nicht in der Neues-Datei erwähnt).
+ - Fehlende Stimm-Reaktionen korrigiert, wenn Gegner in der CD-Version von
+ Lands of Lore getroffen wurden.
+
Lab:
- Aufhängen während der End-Sequenz behoben.
- Interne Spiel-Bedienelemente verbessert.
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index e566ad12f6..60c8d1f3ef 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -403,6 +403,11 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_lastSaveTime = 0;
+ _playTimeInSecondsAdjust = 0;
+ _lastUsedPlayTimeInCycles = 0;
+ _lastUsedPlayTimeInSeconds = 0;
+ _passedPlayTimeCycles = 0;
+
memset(_keyQueue, 0, sizeof(_keyQueue));
_console = nullptr;
@@ -418,6 +423,9 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_inventory = nullptr;
_keyHoldMode = false;
+
+ _artificialDelayCurrentRoom = 0;
+ _artificialDelayCurrentPicture = 0;
}
void AgiEngine::initialize() {
diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp
index fed07ea986..8a62fce86c 100644
--- a/engines/agi/op_cmd.cpp
+++ b/engines/agi/op_cmd.cpp
@@ -662,7 +662,7 @@ void cmdWordToString(AgiGame *state, AgiEngine *vm, uint8 *parameter) {
uint16 stringNr = parameter[0];
uint16 wordNr = parameter[1];
- strcpy(state->strings[stringNr], state->_vm->_words->getEgoWord(wordNr));
+ Common::strlcpy(state->strings[stringNr], state->_vm->_words->getEgoWord(wordNr), MAX_STRINGLEN);
}
void cmdOpenDialogue(AgiGame *state, AgiEngine *vm, uint8 *parameter) {
@@ -2014,7 +2014,7 @@ void cmdGetString(AgiGame *state, AgiEngine *vm, uint8 *parameter) {
// copy string to destination
// TODO: not sure if set all the time or only when ENTER is pressed
- strcpy(&state->_vm->_game.strings[stringDestNr][0], (char *)textMgr->_inputString);
+ Common::strlcpy(&state->_vm->_game.strings[stringDestNr][0], (char *)textMgr->_inputString, MAX_STRINGLEN);
textMgr->charPos_Pop();
@@ -2102,7 +2102,7 @@ void cmdSetString(AgiGame *state, AgiEngine *vm, uint8 *parameter) {
// CM: to avoid crash in Groza (str = 150)
if (stringNr > MAX_STRINGS)
return;
- strcpy(state->strings[stringNr], state->_curLogic->texts[textNr]);
+ Common::strlcpy(state->strings[stringNr], state->_curLogic->texts[textNr], MAX_STRINGLEN);
}
void cmdDisplay(AgiGame *state, AgiEngine *vm, uint8 *parameter) {
diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp
index 4b215edc63..4505668fd1 100644
--- a/engines/agi/op_test.cpp
+++ b/engines/agi/op_test.cpp
@@ -231,8 +231,8 @@ uint8 AgiEngine::testCompareStrings(uint8 s1, uint8 s2) {
char ms2[MAX_STRINGLEN];
int j, k, l;
- strcpy(ms1, _game.strings[s1]);
- strcpy(ms2, _game.strings[s2]);
+ Common::strlcpy(ms1, _game.strings[s1], MAX_STRINGLEN);
+ Common::strlcpy(ms2, _game.strings[s2], MAX_STRINGLEN);
l = strlen(ms1);
for (k = 0, j = 0; k < l; k++) {
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index 620d5e0baf..e1545cdb68 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -1205,7 +1205,7 @@ void MickeyEngine::printStory() {
clearScreen(IDA_DEFAULT);
for (iRow = 0; iRow < 25; iRow++) {
- strcpy(szLine, buffer + pBuf);
+ Common::strlcpy(szLine, buffer + pBuf, 41);
drawStr(iRow, 0, IDA_DEFAULT, szLine);
pBuf += strlen(szLine) + 1;
}
@@ -1213,7 +1213,7 @@ void MickeyEngine::printStory() {
clearScreen(IDA_DEFAULT);
for (iRow = 0; iRow < 21; iRow++) {
- strcpy(szLine, buffer + pBuf);
+ Common::strlcpy(szLine, buffer + pBuf, 41);
drawStr(iRow, 0, IDA_DEFAULT, szLine);
pBuf += strlen(szLine) + 1;
}
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index 87ac7c19c6..8fb9daca5e 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -292,7 +292,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
}
// extract menu string
- strcpy(szMenu, (char *)(buffer + pc));
+ Common::strlcpy(szMenu, (char *)(buffer + pc), 121);
XOR80(szMenu);
break;
default:
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 0658609cd0..09fce9320b 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -118,7 +118,7 @@ int AgiEngine::saveGame(const Common::String &fileName, const Common::String &de
out->writeByte(2); // was _game.state, 2 = STATE_RUNNING
- strcpy(gameIDstring, _game.id);
+ Common::strlcpy(gameIDstring, _game.id, 8);
out->write(gameIDstring, 8);
debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing game id (%s, %s)", gameIDstring, _game.id);
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 110ba10632..274a654547 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -457,7 +457,7 @@ void TextMgr::drawMessageBox(const char *textPtr, int16 forcedHeight, int16 want
// Caller wants to force specified width/height? set it
if (forcedHeight)
_messageState.textSize_Height = forcedHeight;
-
+
if (forcedWidth) {
if (wantedWidth)
_messageState.textSize_Width = wantedWidth;
@@ -1207,7 +1207,7 @@ char *TextMgr::stringPrintf(const char *originalText) {
}
assert(resultString.size() < sizeof(resultPrintfBuffer));
- strcpy(resultPrintfBuffer, resultString.c_str());
+ Common::strlcpy(resultPrintfBuffer, resultString.c_str(), 2000);
return resultPrintfBuffer;
}
diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index 4f6c62c48a..cc443f2f50 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -126,14 +126,14 @@ const byte *AGOSEngine::getStringPtrByID(uint16 stringId, bool upperCase) {
_awaitTwoByteToken = 0;
uncompressText(ptr);
_textBuffer[_textCount] = 0;
- strcpy((char *)dst, (const char *)_textBuffer);
+ Common::strlcpy((char *)dst, (const char *)_textBuffer, 180);
} else {
if (stringId < 0x8000) {
stringPtr = _stringTabPtr[stringId];
} else {
stringPtr = getLocalStringByID(stringId);
}
- strcpy((char *)dst, (const char *)stringPtr);
+ Common::strlcpy((char *)dst, (const char *)stringPtr, 180);
}
// WORKAROUND bug #1538873: The French version of Simon 1 and the
@@ -796,7 +796,7 @@ void AGOSEngine_Feeble::printInteractText(uint16 num, const char *string) {
if (*string2 == 0x00) {
if (w == 0xFFFF)
w = pixels;
- strcpy(convertedString2, string);
+ Common::strlcpy(convertedString2, string, 320);
break;
}
while (*string2 != ' ') {
diff --git a/engines/agos/string_pn.cpp b/engines/agos/string_pn.cpp
index 7a364f3ea9..06c8bbd98e 100644
--- a/engines/agos/string_pn.cpp
+++ b/engines/agos/string_pn.cpp
@@ -114,7 +114,7 @@ void AGOSEngine_PN::getObjectName(char *v, uint16 x) {
}
void AGOSEngine_PN::pcl(const char *s) {
- strcat(_sb, s);
+ Common::strlcat(_sb, s, 80);
if (strchr(s, '\n') == 0) {
for (char *str = _sb; *str; str++)
windowPutChar(_windowArray[_curWindow], *str);
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 54f5c00d93..8b0d8b6c77 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -952,8 +952,9 @@ uint8 Vga::closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 col
}
uint8 Vga::closest(Dac *pal, Dac x) {
- int exp = (sizeof(long) * 8 - 1);
- long D = (1 << exp) - 1; // Maximum value of long.
+ long D = 0;
+ D = ~D;
+ D = (unsigned long)D >> 1; // Maximum value of long.
long R = x._r;
long G = x._g;
long B = x._b;
diff --git a/engines/cruise/ctp.cpp b/engines/cruise/ctp.cpp
index 9515b552e1..4458e39e91 100644
--- a/engines/cruise/ctp.cpp
+++ b/engines/cruise/ctp.cpp
@@ -307,7 +307,7 @@ int initCt(const char *ctpName) {
MemFree(ptr);
if (ctpName != currentCtpName)
- strcpy(currentCtpName, ctpName);
+ Common::strlcpy(currentCtpName, ctpName, 40);
numberOfWalkboxes = segementSizeTable[6] / 2; // get the number of walkboxes
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
index 7a1258dbde..2eff82bc61 100644
--- a/engines/cruise/dataLoader.cpp
+++ b/engines/cruise/dataLoader.cpp
@@ -249,12 +249,19 @@ int loadFile(const char* name, int idx, int destIdx) {
int numMaxEntriesInSet = getNumMaxEntiresInSet(ptr);
if (destIdx > numMaxEntriesInSet) {
+ MemFree(ptr);
return 0; // exit if limit is reached
}
- return loadSetEntry(name, ptr, destIdx, idx);
+ int res = loadSetEntry(name, ptr, destIdx, idx);
+ MemFree(ptr);
+
+ return res;
}
case type_FNT: {
- return loadFNTSub(ptr, idx);
+ int res = loadFNTSub(ptr, idx);
+ MemFree(ptr);
+
+ return res;
}
case type_SPL: {
// Sound file
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 8ee3b14d0c..36fbb73037 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1576,6 +1576,9 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
_m2x = 0;
_m2y = 0;
+ _counter = 0;
+ _counterMax = 0;
+
_field_78 = 0;
_framePosOffsets = 0;
_field_84 = 0;
diff --git a/engines/lastexpress/entities/gendarmes.cpp b/engines/lastexpress/entities/gendarmes.cpp
index b628b8dfe7..1b51dd2006 100644
--- a/engines/lastexpress/entities/gendarmes.cpp
+++ b/engines/lastexpress/entities/gendarmes.cpp
@@ -174,7 +174,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
strcat((char *)&parameters1->seq1, (char *)&params->seq1);
strcat((char *)&parameters1->seq2, (char *)&params->seq1);
- strcat((char *)&parameters1->seq3, (char *)&params->seq1);
+ Common::strlcat((char *)&parameters1->seq3, (char *)&params->seq1, 9); // Beware, seq3 is smaller than seq1
if ((getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params->param1, (EntityPosition)params->param2)
|| getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params->param1, (EntityPosition)parameters2->param7)
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 697e6e1269..7308214551 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -366,7 +366,7 @@ void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
assert(_name1.size() <= 16);
assert(_name2.size() <= 16);
- if (_name2.matchString("NISSND?") && (_status.status & kFlagType9) != kFlag3) {
+ if (_name2.matchString("NISSND?") && ((_status.status & kFlagType9) != kFlag3)) {
s.syncAsUint32LE(_status.status);
s.syncAsUint32LE(_type);
s.syncAsUint32LE(_blockCount); // field_8;
diff --git a/engines/lure/game.cpp b/engines/lure/game.cpp
index 38ca0ba54f..371bcd6ed6 100644
--- a/engines/lure/game.cpp
+++ b/engines/lure/game.cpp
@@ -538,7 +538,7 @@ void Game::handleRightClickMenu() {
hotspot = res.getHotspot(room.hotspotId());
assert(hotspot);
strings.getString(hotspot->nameId, statusLine);
- strcat(statusLine, stringList.getString(S_FOR));
+ Common::strlcat(statusLine, stringList.getString(S_FOR), MAX_DESC_SIZE);
statusLine += strlen(statusLine);
itemId = PopupMenu::ShowItems(GET, player->roomNumber());
@@ -549,7 +549,7 @@ void Game::handleRightClickMenu() {
hotspot = res.getHotspot(room.hotspotId());
assert(hotspot);
strings.getString(hotspot->nameId, statusLine);
- strcat(statusLine, stringList.getString(S_TO));
+ Common::strlcat(statusLine, stringList.getString(S_TO), MAX_DESC_SIZE);
breakFlag = GetTellActions();
break;
@@ -559,7 +559,7 @@ void Game::handleRightClickMenu() {
case DRINK:
hasItems = (res.numInventoryItems() != 0);
if (!hasItems)
- strcat(statusLine, stringList.getString(S_ACTION_NOTHING));
+ Common::strlcat(statusLine, stringList.getString(S_ACTION_NOTHING), MAX_DESC_SIZE);
statusLine += strlen(statusLine);
room.update();
@@ -579,9 +579,9 @@ void Game::handleRightClickMenu() {
assert(useHotspot);
strings.getString(useHotspot->nameId, statusLine);
if (action == GIVE)
- strcat(statusLine, stringList.getString(S_TO));
+ Common::strlcat(statusLine, stringList.getString(S_TO), MAX_DESC_SIZE);
else
- strcat(statusLine, stringList.getString(S_ON));
+ Common::strlcat(statusLine, stringList.getString(S_ON), MAX_DESC_SIZE);
statusLine += strlen(statusLine);
}
else if ((action == DRINK) || (action == EXAMINE))
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index fbf93e1e14..a972909b8b 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -1898,8 +1898,8 @@ void Hotspot::doStatus(HotspotData *hotspot) {
endAction();
strings.getString(room.roomNumber(), buffer);
- strcat(buffer, "\n\n");
- strcat(buffer, stringList.getString(S_YOU_ARE_CARRYING));
+ Common::strlcat(buffer, "\n\n", MAX_DESC_SIZE);
+ Common::strlcat(buffer, stringList.getString(S_YOU_ARE_CARRYING), MAX_DESC_SIZE);
// Scan through the list and add in any items assigned to the player
HotspotDataList &list = res.hotspotData();
@@ -1909,25 +1909,25 @@ void Hotspot::doStatus(HotspotData *hotspot) {
if (rec.roomNumber == PLAYER_ID) {
if (numItems++ == 0)
- strcat(buffer, ": ");
+ Common::strlcat(buffer, ": ", MAX_DESC_SIZE);
else
- strcat(buffer, ", ");
+ Common::strlcat(buffer, ", ", MAX_DESC_SIZE);
strings.getString(rec.nameId, buffer + strlen(buffer));
}
}
// If there were no items, add in the word 'nothing'
if (numItems == 0)
- strcat(buffer, stringList.getString(S_INV_NOTHING));
+ Common::strlcat(buffer, stringList.getString(S_INV_NOTHING), MAX_DESC_SIZE);
// If the player has money, add it in
uint16 numGroats = res.fieldList().numGroats();
if (numGroats > 0) {
- strcat(buffer, "\n\n");
- strcat(buffer, stringList.getString(S_YOU_HAVE));
- sprintf(buffer + strlen(buffer), "%d", numGroats);
- strcat(buffer, " ");
- strcat(buffer, stringList.getString((numGroats == 1) ? S_GROAT : S_GROATS));
+ Common::strlcat(buffer, "\n\n", MAX_DESC_SIZE);
+ Common::strlcat(buffer, stringList.getString(S_YOU_HAVE), MAX_DESC_SIZE);
+ snprintf(buffer + strlen(buffer), MAX_DESC_SIZE, "%d", numGroats);
+ Common::strlcat(buffer, " ", MAX_DESC_SIZE);
+ Common::strlcat(buffer, stringList.getString((numGroats == 1) ? S_GROAT : S_GROATS), MAX_DESC_SIZE); // Make sure we're not overrunning
}
// Display the dialog
diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
index 3df119a9da..f7dc06033a 100644
--- a/engines/lure/scripts.cpp
+++ b/engines/lure/scripts.cpp
@@ -926,8 +926,8 @@ uint16 Script::execute(uint16 startOffset) {
opcode >>= 1;
if (gDebugLevel >= ERROR_DETAILED)
- strcat(debugInfo, (opcode > S_OPCODE_RANDOM) ? "INVALID" :
- scriptOpcodes[opcode]);
+ Common::strlcat(debugInfo, (opcode > S_OPCODE_RANDOM) ? "INVALID" :
+ scriptOpcodes[opcode], MAX_DESC_SIZE);
if (hasParam) {
// Flag to read next two bytes as active parameter
@@ -1087,7 +1087,7 @@ uint16 Script::execute(uint16 startOffset) {
else if (scriptMethodNames[param] == NULL) strcat(debugInfo, " UNKNOWN METHOD");
else {
strcat(debugInfo, " ");
- strcat(debugInfo, scriptMethodNames[param]);
+ Common::strlcat(debugInfo, scriptMethodNames[param], MAX_DESC_SIZE);
}
// Any params
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index 3eab31acc2..0020cb398c 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -40,6 +40,7 @@ namespace Made {
*/
Object::Object() : _objData(NULL), _freeData(false) {
+ _objSize = 0;
}
Object::~Object() {
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index f1539297ee..a29aa2512f 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -58,11 +58,24 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
const GameSettings *g;
+ _eventNum = 0;
+ _eventMouseX = _eventMouseY = 0;
+ _eventKey = 0;
+ _autoStopSound = false;
+ _soundEnergyIndex = 0;
+ _soundEnergyArray = 0;
+ _musicBeatStart = 0;
+ _cdTimeStart = 0;
+
+ _gameId = -1;
+
const char *gameid = ConfMan.get("gameid").c_str();
for (g = madeSettings; g->gameid; ++g)
if (!scumm_stricmp(g->gameid, gameid))
_gameId = g->id;
+ assert(_gameId != -1);
+
_rnd = new Common::RandomSource("made");
_console = new MadeConsole(this);
@@ -85,6 +98,8 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_music = nullptr;
+ _soundRate = 0;
+
// Set default sound frequency
switch (getGameID()) {
case GID_RODNEY:
diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp
index 453e2a4872..0beb132b93 100644
--- a/engines/made/pmvplayer.cpp
+++ b/engines/made/pmvplayer.cpp
@@ -223,7 +223,10 @@ bool PmvPlayer::play(const char *filename) {
//delete _audioStream;
delete _fd;
- _surface->free();
+
+ if(_surface)
+ _surface->free();
+
delete _surface;
return !_aborted;
diff --git a/engines/made/redreader.cpp b/engines/made/redreader.cpp
index f92ffd8dd8..a0aaf7be43 100644
--- a/engines/made/redreader.cpp
+++ b/engines/made/redreader.cpp
@@ -102,7 +102,7 @@ int LzhDecompressor::decompress(Common::SeekableReadStream &source, byte *dest,
int bufsize;
byte* buffer;
- buffer = (byte *) malloc(DICSIZ);
+ buffer = (byte *)calloc(DICSIZ, 1);
_source = &source;
_compSize = sourceLen;
diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp
index f8e763e74e..a9734ed47d 100644
--- a/engines/made/resource.cpp
+++ b/engines/made/resource.cpp
@@ -43,6 +43,7 @@ Resource::~Resource() {
PictureResource::PictureResource() : _picture(NULL), _picturePalette(NULL) {
_hasPalette = false;
+ _paletteColorCount = 0;
}
PictureResource::~PictureResource() {
@@ -182,6 +183,9 @@ void PictureResource::loadChunked(byte *source, int size) {
/* AnimationResource */
AnimationResource::AnimationResource() {
+ _flags = 0;
+ _width = 0;
+ _height = 0;
}
AnimationResource::~AnimationResource() {
diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp
index edccb68953..33edb3834c 100644
--- a/engines/made/screen.cpp
+++ b/engines/made/screen.cpp
@@ -91,6 +91,8 @@ Screen::Screen(MadeEngine *vm) : _vm(vm) {
_currentFontNum = 0;
_fontDrawCtx.clipRect = Common::Rect(320, 200);
_fontDrawCtx.destSurface = _backgroundScreen;
+ _outlineColor = 0;
+ _dropShadowColor = 0;
clearChannels();
}
diff --git a/engines/made/sound.cpp b/engines/made/sound.cpp
index ad49031e7b..62559efa84 100644
--- a/engines/made/sound.cpp
+++ b/engines/made/sound.cpp
@@ -155,6 +155,7 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
};
soundEnergyItem.position = 0;
+ memset(deltaSoundBuffer, 0, 1024);
if (soundEnergyArray)
soundEnergyArray->clear();
@@ -237,6 +238,7 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
break;
default:
+ delete[] soundBuffer;
return;
}
@@ -247,6 +249,9 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
// soundBuffer.
soundBuffer[workChunkSize] = soundBuffer[workChunkSize - 1];
+ for (i = 0; i < chunkSize; i++)
+ soundBuffer[i] = 0;
+
if (deltaType == 1) {
for (i = 0; i < chunkSize - 1; i += 2) {
l = i / 2;
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index 29bcd10094..5776d813cf 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -58,6 +58,7 @@ MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
_resources = nullptr;
_sound = nullptr;
_audio = nullptr;
+ _screen = nullptr;
}
MADSEngine::~MADSEngine() {
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
index 90d366ed7e..81b2edb57d 100644
--- a/engines/mortevielle/mortevielle.cpp
+++ b/engines/mortevielle/mortevielle.cpp
@@ -145,6 +145,7 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescr
_endGame = false;
_loseGame = false;
_txxFileFl = false;
+ _is = 0;
}
MortevielleEngine::~MortevielleEngine() {
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index 50a5b38d8d..8f895f1532 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -163,7 +163,7 @@ int16 Program::findLocal(const char* name) {
int16 Program::addLocal(const char *name, int16 value, int16 min, int16 max) {
assert(_numLocals < NUM_LOCALS);
- strcpy(_localNames[_numLocals], name);
+ Common::strlcpy(_localNames[_numLocals], name, 10);
_locals[_numLocals].setRange(min, max);
_locals[_numLocals].setValue(value);
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 2b75e78582..bbe759dffe 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -60,6 +60,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
DebugMan.addDebugChannel(kDebugMenu, "menu", "Menu debug level");
DebugMan.addDebugChannel(kDebugInventory, "inventory", "Inventory debug level");
+ _screenWidth = 0;
_screenHeight = 0;
_screenSize = 0;
_gameType = 0;
@@ -86,6 +87,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
_inventory = 0;
_currentLocationIndex = 0;
_numLocations = 0;
+ _language = 0;
}
Parallaction::~Parallaction() {
@@ -208,7 +210,7 @@ void Parallaction::allocateLocationSlot(const char *name) {
error("No more location slots available. Please report this immediately to ScummVM team");
if (_currentLocationIndex == -1) {
- strcpy(_locationNames[_numLocations], name);
+ Common::strlcpy(_locationNames[_numLocations], name, 10);
_currentLocationIndex = _numLocations;
_numLocations++;
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index 1e1c0b0a3d..9f045cb397 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -320,7 +320,7 @@ void Parallaction_br::changeLocation() {
freeLocation(false);
// load new location
- strcpy(_location._name, _newLocationName.c_str());
+ Common::strlcpy(_location._name, _newLocationName.c_str(), 100);
parseLocation(_location._name);
if (_location._startPosition.x != -1000) {
diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp
index 77680178c1..e50378b9c0 100644
--- a/engines/saga/isomap.cpp
+++ b/engines/saga/isomap.cpp
@@ -97,6 +97,23 @@ IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) {
_viewScroll.x = (128 - 8) * 16;
_viewScroll.y = (128 - 8) * 16 - 64;
_viewDiff = 1;
+ _platformHeight = 0;
+ _queueCount = _readCount = 0;
+
+ for (int i = 0; i < SAGA_DRAGON_SEARCH_DIAMETER; i++)
+ for (int j = 0; j < SAGA_DRAGON_SEARCH_DIAMETER; j++)
+ _dragonSearchArray.cell[i][j].visited = _dragonSearchArray.cell[i][j].direction = 0;
+
+ for (int i = 0; i < SAGA_SEARCH_DIAMETER; i++)
+ for (int j = 0; j < SAGA_SEARCH_DIAMETER; j++)
+ _searchArray.cell[i][j].visited = _searchArray.cell[i][j].direction = 0;
+
+ for (int i = 0; i < SAGA_SEARCH_QUEUE_SIZE; i++) {
+ memset(&_dragonSearchArray.queue[i], 0, sizeof(DragonTilePoint));
+ memset(&_searchArray.queue[i], 0, sizeof(TilePoint));
+ }
+
+ memset(&_tileMap, 0, sizeof(TileMapData));
}
void IsoMap::loadImages(const ByteArray &resourceData) {
diff --git a/engines/saga/puzzle.cpp b/engines/saga/puzzle.cpp
index 099bf79e6b..2c9a02beec 100644
--- a/engines/saga/puzzle.cpp
+++ b/engines/saga/puzzle.cpp
@@ -86,6 +86,11 @@ Puzzle::Puzzle(SagaEngine *vm) : _vm(vm), _solved(false), _active(false) {
_hintBox.setWidth(240);
_hintBox.setHeight(30);
+ _hintNextRqState = kRQNoHint;
+ _hintGiver = 0;
+ _hintSpeaker = 0;
+ _slidePointX = _slidePointY = 0;
+
initPieceInfo( 0, 268, 18, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3,
Point(0, 1), Point(0, 62), Point(15, 31), Point(0, 0), Point(0, 0), Point(0,0));
initPieceInfo( 1, 270, 52, 0, 0, 0 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4,
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index e659e09ce8..2d798bb0d6 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -56,7 +56,7 @@ SaveFileData *SagaEngine::getSaveFile(uint idx) {
return &_saveFiles[_saveFilesCount - idx - 1];
} else {
if (!emptySlot.name[0])
- strcpy(emptySlot.name, getTextString(kTextNewSave));
+ Common::strlcpy(emptySlot.name, getTextString(kTextNewSave), SAVE_TITLE_SIZE);
return (idx == 0) ? &emptySlot : &_saveFiles[_saveFilesCount - idx];
}
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 5f087ebd1a..c01613268a 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -349,6 +349,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Conquests of Camelot - English Atari ST
+ // Game version 1.019.000
+ // Floppy: INT#10.12.90
+ // Executable reports "1.002.038"
+ {"camelot", "", {
+ {"resource.map", 0, "0f80a11867be91a158823887a49cf443", 7290},
+ {"resource.001", 0, "162f66c42e4146ee63f78fba6f1a6757", 596773},
+ {"resource.002", 0, "162f66c42e4146ee63f78fba6f1a6757", 724615},
+ {"resource.003", 0, "162f66c42e4146ee63f78fba6f1a6757", 713351},
+ {"resource.004", 0, "162f66c42e4146ee63f78fba6f1a6757", 718766},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Conquests of Camelot - English DOS
// SCI interpreter version 0.000.685
{"camelot", "", {
@@ -939,6 +952,22 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Hoyle 1 - English Atari ST
+ // Game version 1.000.104, SCI interpreter version 1.002.024
+ {"hoyle1", "", {
+ {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518127},
+ {"resource.map", 0, "0af9a3dcd72a091960de070432e1f524", 4386},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Hoyle 1 - English Atari ST
+ // Game version 1.000.108, SCI interpreter version 1.002.026
+ {"hoyle1", "", {
+ {"resource.map", 0, "ed8355f84752e49ffa1f0cf9eca4b28e", 4140},
+ {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 517454},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Hoyle 2 - English DOS
// SCI interpreter version 0.000.572
{"hoyle2", "", {
@@ -982,6 +1011,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Hoyle 2 - English Atari ST
+ // Game version 1.001.017
+ // Executable scanning reports "1.002.034"
+ {"hoyle2", "", {
+ {"resource.map", 0, "13c8cc977598b6ad61d24c6296a090fd", 1356},
+ {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 216280},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Hoyle 2 - English Macintosh
// Executable scanning reports "x.yyy.zzz"
{"hoyle2", "", {
@@ -1977,6 +2015,17 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Larry 2 - English Atari ST
+ // Game version 1.001.006
+ // Executable reports "1.000.159" 1988-12-02 12:22 p.m.
+ {"lsl2", "", {
+ {"resource.map", 0, "2fc3ce7da1346e4dadfee18606d814fc", 4758},
+ {"resource.001", 0, "4a24443a25e2b1492462a52809605dc2", 477342},
+ {"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 406698},
+ {"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 592433},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Larry 2 - English DOS Non-Interactive Demo
// Executable scanning reports "x.yyy.zzz"
// SCI interpreter version 0.000.409
@@ -2034,6 +2083,17 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Larry 2 - English Atari ST (Kixx)
+ // Game version 1.002.000
+ // Executable reports "1.001.008" 1989-01-12 16:30
+ {"lsl2", "", {
+ {"resource.map", 0, "2c9c3b0923e3764f5ab999bcb71c2d47", 4758},
+ {"resource.001", 0, "4a24443a25e2b1492462a52809605dc2", 477625},
+ {"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 406935},
+ {"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 592533},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Larry 3 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
// SCI interpreter version 0.000.685
@@ -2048,6 +2108,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Larry 3 - English Atari ST
+ // Game version 1.021, 1990-01-27
+ // Int#6.26.90
+ // Executable scanning reports "1.002.026"
+ {"lsl3", "", {
+ {"resource.map", 0, "0b6bd3e039682830a51c5755c06591db", 5916},
+ {"resource.001", 0, "f18441027154292836b973c655fa3175", 456722},
+ {"resource.002", 0, "f18441027154292836b973c655fa3175", 578024},
+ {"resource.003", 0, "f18441027154292836b973c655fa3175", 506807},
+ {"resource.004", 0, "f18441027154292836b973c655fa3175", 513651},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Larry 3 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.021 8x5.25" (label: Int#5.15.90)
{"lsl3", "", {
@@ -2916,6 +2989,17 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Police Quest 2 - English Atari ST
+ // Game version 1.002.011 DS 1989-07-21
+ // Executable reports "1.002.003"
+ {"pq2", "", {
+ {"resource.map", 0, "28a6f471c7900c2c92da40eecb615d9d", 4584},
+ {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525},
+ {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000},
+ {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Police Quest 2 - English DOS (from FRG)
// SCI interpreter version 0.000.395
{"pq2", "", {
@@ -2935,6 +3019,17 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Police Quest 2 - English Atari ST
+ // Game version 1.001.006 1989-01-16 13:30
+ // Executable reports "1.001.009"
+ {"pq2", "", {
+ {"resource.map", 0, "8e1161c684b342742d30f938a4839a4b", 4518},
+ {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 506563},
+ {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 541261},
+ {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 587511},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Police Quest 2 - Japanese PC-98 (also includes english language)
// Executable scanning reports "x.yyy.zzz"
// SCI interpreter version unknown
@@ -3204,6 +3299,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Quest for Glory 1 / Hero's Quest - English Atari ST
+ // Game version 1.137
+ // Executable reports "1.002.028"
+ {"qfg1", "", {
+ {"resource.map", 0, "2a794066ad161acbedac8fa14e46905d", 6438},
+ {"resource.000", 0, "40332d3ebfc70a4b6a6a0443c2763287", 79204},
+ {"resource.001", 0, "f7fc269d3db146830d6427d3e02d4187", 473547},
+ {"resource.002", 0, "e64004e020fdf1813be52b639b08be89", 635687},
+ {"resource.003", 0, "f0af87c60ec869946da442833aa5afa8", 640438},
+ {"resource.004", 0, "f0af87c60ec869946da442833aa5afa8", 644452},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Quest for Glory 1 / Hero's Quest - English DOS Demo
// Executable scanning reports "0.000.685"
{"qfg1", "Demo", {
@@ -3283,6 +3391,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English Amiga
+ // Game version 1.109
// Executable scanning reports "1.003.004"
// SCI interpreter version 0.001.010
{"qfg2", "", {
@@ -3705,6 +3814,18 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Space Quest 3 - English Atari ST
+ // Game version 1.0Q 1989-27-03 17:00
+ // Int#1.002.002
+ // Executable reports "1.002.001"
+ {"sq3", "", {
+ {"resource.map", 0, "c36e322805949affd882a75803a6a54e", 5484},
+ {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 485146},
+ {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720227},
+ {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688524},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Space Quest 3 - German Amiga (also includes english language)
// Executable scanning reports "1.004.006"
// SCI interpreter version 0.000.453 (just a guess)
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 0867b20fc3..4c9d1221aa 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -186,6 +186,11 @@ Common::String ScummEngine_v70he::generateFilename(const int room) const {
}
if (_filenamePattern.genMethod == kGenHEPC || _filenamePattern.genMethod == kGenHEIOS) {
+ if (id == '3' && _game.id == GID_MOONBASE) {
+ result = Common::String::format("%s.u32", _filenamePattern.pattern);
+ break;
+ }
+
// For HE >= 98, we already called snprintf above.
if (_game.heversion < 98 || room < 0)
result = Common::String::format("%s.he%c", _filenamePattern.pattern, id);
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 5a994cb699..bb3e7f6ec3 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -245,9 +245,11 @@ static const GameSettings gameVariantsTable[] = {
{"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
{"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
+ {"monkey", "SE Talkie", 0, GID_MONKEY, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_AUDIOTRACKS, UNK, GUIO0()},
{"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
{"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO5(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
+ {"monkey2", "SE Talkie",0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "Steam", "steam", GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index 370f54c1d8..df62c59dd8 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -184,8 +184,11 @@ protected:
};
#ifdef ENABLE_HE
+class Moonbase;
+
class ScummEngine_v71he : public ScummEngine_v70he {
friend class Wiz;
+ friend class Moonbase;
protected:
bool _skipProcessActors;
@@ -244,6 +247,10 @@ public:
void queueAuxEntry(int actorNum, int subIndex);
void remapHEPalette(const uint8 *src, uint8 *dst);
+
+public:
+ /* Moonbase stuff */
+ Moonbase *_moonbase;
};
class ScummEngine_v72he : public ScummEngine_v71he {
diff --git a/engines/scumm/he/logic/moonbase.cpp b/engines/scumm/he/logic/moonbase_logic.cpp
index 3fcf30d6b5..a32356614f 100644
--- a/engines/scumm/he/logic/moonbase.cpp
+++ b/engines/scumm/he/logic/moonbase_logic.cpp
@@ -22,6 +22,7 @@
#include "scumm/he/intern_he.h"
#include "scumm/he/logic_he.h"
+#include "scumm/he/moonbase/moonbase.h"
namespace Scumm {
@@ -42,9 +43,10 @@ private:
void op_load_multi_channel_wiz(int op, int numArgs, int32 *args);
void op_wiz_from_multi_channel_wiz(int op, int numArgs, int32 *args);
void op_dos_command(int op, int numArgs, int32 *args);
- void op_set_fow_sentinel(int op, int numArgs, int32 *args);
+ void op_set_fow_sentinel(int32 *args);
void op_set_fow_information(int op, int numArgs, int32 *args);
- void op_set_fow_image(int op, int numArgs, int32 *args);
+ int op_set_fow_image(int op, int numArgs, int32 *args);
+
void op_ai_test_kludge(int op, int numArgs, int32 *args);
void op_ai_master_control_program(int op, int numArgs, int32 *args);
void op_ai_reset(int op, int numArgs, int32 *args);
@@ -75,6 +77,44 @@ int LogicHEmoonbase::versionID() {
#define OP_AI_SET_TYPE 10003
#define OP_AI_CLEAN_UP 10004
+#define OP_NET_REMOTE_START_SCRIPT 1492
+#define OP_NET_DO_INIT_ALL 1493
+#define OP_NET_DO_INIT_PROVIDER 1494
+#define OP_NET_DO_INIT_SESSION 1495
+#define OP_NET_DO_INIT_USER 1496
+#define OP_NET_QUERY_PROVIDERS 1497
+#define OP_NET_GET_PROVIDER_NAME 1498
+#define OP_NET_SET_PROVIDER 1499
+#define OP_NET_CLOSE_PROVIDER 1500
+#define OP_NET_QUERY_SESSIONS 1501
+#define OP_NET_GET_SESSION_NAME 1502
+#define OP_NET_CREATE_SESSION 1503
+#define OP_NET_JOIN_SESSION 1504
+#define OP_NET_END_SESSION 1505
+#define OP_NET_ADD_USER 1506
+#define OP_NET_REMOVE_USER 1507
+#define OP_NET_WHO_SENT_THIS 1508
+#define OP_NET_REMOTE_SEND_ARRAY 1509
+#define OP_NET_WHO_AM_I 1510
+#define OP_NET_REMOTE_START_FUNCTION 1511
+#define OP_NET_GET_PLAYER_LONG_NAME 1512
+#define OP_NET_GET_PLAYER_SHORT_NAME 1513
+#define OP_NET_SET_PROVIDER_BY_NAME 1516
+#define OP_NET_HOST_TCPIP_GAME 1517
+#define OP_NET_JOIN_TCPIP_GAME 1518
+#define OP_NET_SET_FAKE_LAG 1555
+#define OP_NET_GET_HOST_NAME 1556
+#define OP_NET_GET_IP_FROM_NAME 1557
+#define OP_NET_GET_SESSION_PLAYER_COUNT 1558
+#define OP_NET_DISABLE_SESSION_PLAYER_JOIN 1559
+#define OP_NET_START_QUERY_SESSIONS 1560
+#define OP_NET_UPDATE_QUERY_SESSIONS 1561
+#define OP_NET_STOP_QUERY_SESSIONS 1562
+#define OP_NET_DESTROY_PLAYER 1563
+#define OP_NET_ENABLE_SESSION_PLAYER_JOIN 1564
+#define OP_NET_SET_AI_PLAYER_COUNT 1565
+
+
int32 LogicHEmoonbase::dispatch(int op, int numArgs, int32 *args) {
switch (op) {
case OP_CREATE_MULTI_STATE_WIZ:
@@ -90,13 +130,13 @@ int32 LogicHEmoonbase::dispatch(int op, int numArgs, int32 *args) {
op_dos_command(op, numArgs, args);
break;
case OP_SET_FOW_SENTINEL:
- op_set_fow_sentinel(op, numArgs, args);
+ op_set_fow_sentinel(args);
break;
case OP_SET_FOW_INFORMATION:
op_set_fow_information(op, numArgs, args);
break;
case OP_SET_FOW_IMAGE:
- op_set_fow_image(op, numArgs, args);
+ return op_set_fow_image(op, numArgs, args);
break;
case OP_AI_TEST_KLUDGE:
@@ -142,19 +182,43 @@ void LogicHEmoonbase::op_dos_command(int op, int numArgs, int32 *args) {
LogicHE::dispatch(op, numArgs, args);
}
-void LogicHEmoonbase::op_set_fow_sentinel(int op, int numArgs, int32 *args) {
- warning("STUB: op_set_fow_sentinel()");
- LogicHE::dispatch(op, numArgs, args);
+void LogicHEmoonbase::op_set_fow_sentinel(int32 *args) {
+ debug(2, "op_set_fow_sentinel(%d, %d, %d)", args[0], args[1], args[2]);
+
+ _vm->_moonbase->_fowSentinelImage = args[0];
+ _vm->_moonbase->_fowSentinelState = args[1];
+ _vm->_moonbase->_fowSentinelConditionBits = args[2];
}
void LogicHEmoonbase::op_set_fow_information(int op, int numArgs, int32 *args) {
- warning("STUB: op_set_fow_information()");
- LogicHE::dispatch(op, numArgs, args);
+ Common::String str;
+
+ str = Common::String::format("op_set_fow_information(%d", args[0]);
+ for (int i = 1; i < numArgs; i++) {
+ str += Common::String::format(", %d", args[i]);
+ }
+ str += ")";
+
+ debug(2, "%s", str.c_str());
+
+ _vm->_moonbase->setFOWInfo(
+ args[0], // array
+ args[1], // array down dimension
+ args[2], // array across dimension
+ args[3], // logical view X coordinate
+ args[4], // logical view Y coordinate
+ args[5], // screen draw clip rect x1
+ args[6], // screen draw clip rect y1
+ args[7], // screen draw clip rect x2
+ args[8], // screen draw clip rect y2
+ args[9], // techinque
+ args[10] // frame
+ );
}
-void LogicHEmoonbase::op_set_fow_image(int op, int numArgs, int32 *args) {
- warning("STUB: op_set_fow_image()");
- LogicHE::dispatch(op, numArgs, args);
+int LogicHEmoonbase::op_set_fow_image(int op, int numArgs, int32 *args) {
+ debug(2, "op_set_fow_image(%d)", args[0]);
+ return _vm->_moonbase->setFOWImage(args[0]) ? 1 : 0;
}
void LogicHEmoonbase::op_ai_test_kludge(int op, int numArgs, int32 *args) {
diff --git a/engines/scumm/he/moonbase/moonbase.cpp b/engines/scumm/he/moonbase/moonbase.cpp
new file mode 100644
index 0000000000..34d4368725
--- /dev/null
+++ b/engines/scumm/he/moonbase/moonbase.cpp
@@ -0,0 +1,179 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "scumm/he/intern_he.h"
+#include "scumm/he/moonbase/moonbase.h"
+
+namespace Scumm {
+
+Moonbase::Moonbase(ScummEngine_v71he *vm) : _vm(vm) {
+ initFOW();
+}
+
+Moonbase::~Moonbase() {
+}
+
+void Moonbase::blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox,
+ uint8 *wizd, int x, int y, int rawROP, int paramROP) {
+ bool premulAlpa = false;
+
+ if (rawROP == 1)
+ premulAlpa = true;
+
+ Common::Rect clippedDstRect(dstw, dsth);
+ if (clipBox) {
+ Common::Rect clip(clipBox->left, clipBox->top, clipBox->right, clipBox->bottom);
+ if (clippedDstRect.intersects(clip)) {
+ clippedDstRect.clip(clip);
+ } else {
+ return;
+ }
+ }
+
+ int width = READ_LE_UINT16(wizd + 0x8 + 0);
+ int height = READ_LE_UINT16(wizd + 0x8 + 2);
+
+ Common::Rect srcLimitsRect(width, height);
+ Common::Rect dstOperation(x, y, x + width, y + height);
+ if (!clippedDstRect.intersects(dstOperation))
+ return;
+ Common::Rect clippedRect = clippedDstRect.findIntersectingRect(dstOperation);
+
+ int cx = clippedRect.right - clippedRect.left;
+ int cy = clippedRect.bottom - clippedRect.top;
+
+ int sx = ((clippedRect.left - x) + srcLimitsRect.left);
+ int sy = ((clippedRect.top - y) + srcLimitsRect.top);
+
+ dst += clippedRect.top * dstPitch + clippedRect.left * 2;
+
+ int headerSize = READ_LE_UINT32(wizd + 0x4);
+ uint8 *dataPointer = wizd + 0x8 + headerSize;
+
+ for (int i = 0; i < sy; i++) {
+ uint16 lineSize = READ_LE_UINT16(dataPointer + 0);
+
+ dataPointer += lineSize;
+ }
+
+ for (int i = 0; i < cy; i++) {
+ uint16 lineSize = READ_LE_UINT16(dataPointer + 0);
+ uint8 *singlesOffset = READ_LE_UINT16(dataPointer + 2) + dataPointer;
+ uint8 *quadsOffset = READ_LE_UINT16(dataPointer + 4) + dataPointer;
+
+ int pixels = 0;
+ byte *dst1 = dst;
+ byte *codes = dataPointer + 6;
+
+ while (1) {
+ int code = *codes - 2;
+ codes++;
+
+ if (code <= 0) { // quad or single
+ uint8 *src;
+ int cnt;
+ if (code == 0) { // quad
+ src = quadsOffset;
+ quadsOffset += 8;
+ cnt = 4; // 4 pixels
+ } else { // single
+ src = singlesOffset;
+ singlesOffset += 2;
+ cnt = 1;
+ }
+
+ for (int c = 0; c < cnt; c++) {
+ if (pixels >= sx) {
+ if (rawROP == 1) { // MMX_PREMUL_ALPHA_COPY
+ WRITE_LE_UINT16(dst1, READ_LE_UINT16(src));
+ } else if (rawROP == 2) { // MMX_ADDITIVE
+ uint16 color = READ_LE_UINT16(src);
+ uint16 orig = READ_LE_UINT16(dst1);
+
+ uint32 r = MIN<uint32>(0x7c00, (orig & 0x7c00) + (color & 0x7c00));
+ uint32 g = MIN<uint32>(0x03e0, (orig & 0x03e0) + (color & 0x03e0));
+ uint32 b = MIN<uint32>(0x001f, (orig & 0x001f) + (color & 0x001f));
+ WRITE_LE_UINT16(dst1, (r | g | b));
+ } else if (rawROP == 5) { // MMX_CHEAP_50_50
+ uint16 color = (READ_LE_UINT16(src) >> 1) & 0x3DEF;
+ uint16 orig = (READ_LE_UINT16(dst1) >> 1) & 0x3DEF;
+ WRITE_LE_UINT16(dst1, (color + orig));
+ }
+ dst1 += 2;
+ }
+ src += 2;
+ pixels++;
+ }
+ } else { // skip
+ if ((code & 1) == 0) {
+ code >>= 1;
+
+ for (int j = 0; j < code; j++) {
+ if (pixels >= sx)
+ dst1 += 2;
+ pixels++;
+ }
+ } else { // special case
+ if (pixels >= sx) {
+ int alpha = code >> 1;
+ uint16 color = READ_LE_UINT16(singlesOffset);
+ uint32 orig = READ_LE_UINT16(dst1);
+
+ if (!premulAlpa) {
+ WRITE_LE_UINT16(dst1, color); // ENABLE_PREMUL_ALPHA = 0
+ } else {
+ if (alpha > 32) {
+ alpha -= 32;
+
+ uint32 oR = orig & 0x7c00;
+ uint32 oG = orig & 0x03e0;
+ uint32 oB = orig & 0x1f;
+ uint32 dR = ((((color & 0x7c00) - oR) * alpha) >> 5) + oR;
+ uint32 dG = ((((color & 0x3e0) - oG) * alpha) >> 5) + oG;
+ uint32 dB = ((((color & 0x1f) - oB) * alpha) >> 5) + oB;
+
+ WRITE_LE_UINT16(dst1, (dR & 0x7c00) | (dG & 0x3e0) | (dB & 0x1f));
+ } else {
+ uint32 pix = ((orig << 16) | orig) & 0x3e07c1f;
+ pix = (((pix * alpha) & 0xffffffff) >> 5) & 0x3e07c1f;
+ pix = ((pix >> 16) + pix + color) & 0xffff;
+ WRITE_LE_UINT16(dst1, pix);
+ }
+ }
+
+ dst1 += 2;
+ }
+ singlesOffset += 2;
+ pixels++;
+ }
+ }
+
+ if (pixels >= cx + sx)
+ break;
+ }
+
+ dataPointer += lineSize;
+ dst += dstPitch;
+ }
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/he/moonbase/moonbase.h b/engines/scumm/he/moonbase/moonbase.h
new file mode 100644
index 0000000000..e82ae0164f
--- /dev/null
+++ b/engines/scumm/he/moonbase/moonbase.h
@@ -0,0 +1,99 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCUMM_HE_MOONBASE_H
+#define SCUMM_HE_MOONBASE_H
+
+#ifdef ENABLE_HE
+
+#include "common/winexe_pe.h"
+
+namespace Scumm {
+
+class Moonbase {
+public:
+ Moonbase(ScummEngine_v71he *vm);
+ ~Moonbase();
+
+ void blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox,
+ uint8 *wizd, int srcx, int srcy, int rawROP, int paramROP);
+
+ // FOW Stuff
+ void initFOW();
+ void releaseFOWResources();
+
+ bool setFOWImage(int id);
+
+ void setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int viewX, int viewY, int clipX1,
+ int clipY1, int clipX2, int clipY2, int technique, int nFrame);
+
+
+ void renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int flags);
+
+private:
+ int readFOWVisibilityArray(int array, int y, int x);
+ void renderFOWState(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int x, int y, int srcw, int srch, int state, int flags);
+
+public:
+ int _fowSentinelImage;
+ int _fowSentinelState;
+ uint32 _fowSentinelConditionBits;
+
+private:
+ ScummEngine_v71he *_vm;
+
+ int _fowFrameBaseNumber;
+ int _fowAnimationFrames;
+ int _fowCurrentFOWFrame;
+
+ int32 _fowTileW;
+ int32 _fowTileH;
+
+ uint8 *_fowImage;
+ int _fowClipX1;
+ int _fowClipY1;
+ int _fowClipX2;
+ int _fowClipY2;
+
+ int _fowDrawX;
+ int _fowDrawY;
+
+ int _fowVtx1;
+ int _fowVty1;
+ int _fowMvx;
+ int _fowMvy;
+ int _fowVw;
+ int _fowVh;
+
+ bool _fowBlackMode;
+
+ int _fowRenderTable[32768];
+
+ Common::PEResources _exe;
+ Common::String _fileName;
+};
+
+} // End of namespace Scumm
+
+#endif // ENABLE_HE
+
+#endif // SCUMM_HE_MOONBASE_H
diff --git a/engines/scumm/he/moonbase/moonbase_fow.cpp b/engines/scumm/he/moonbase/moonbase_fow.cpp
new file mode 100644
index 0000000000..8be83a57f0
--- /dev/null
+++ b/engines/scumm/he/moonbase/moonbase_fow.cpp
@@ -0,0 +1,410 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+
+#include "scumm/he/intern_he.h"
+#include "scumm/he/moonbase/moonbase.h"
+
+namespace Scumm {
+
+#define FOW_ANIM_FRAME_COUNT 38
+
+void Moonbase::initFOW() {
+ _fowSentinelImage = -1;
+ _fowSentinelState = -1;
+ _fowSentinelConditionBits = 0;
+
+ _fowFrameBaseNumber = 0;
+ _fowAnimationFrames = 1;
+ _fowCurrentFOWFrame = 0;
+
+ _fowTileW = 0;
+ _fowTileH = 0;
+
+ _fowImage = nullptr;
+ _fowClipX1 = 0;
+ _fowClipY1 = 0;
+ _fowClipX2 = 0;
+ _fowClipY2 = 0;
+
+ _fowDrawX = 0;
+ _fowDrawY = 0;
+
+ _fowVtx1 = 0;
+ _fowVty1 = 0;
+ _fowMvx = 0;
+ _fowMvy = 0;
+ _fowVw = 0;
+ _fowVh = 0;
+
+ _fowBlackMode = true;
+
+ memset(_fowRenderTable, 0, 32768);
+}
+
+void Moonbase::releaseFOWResources() {
+ if (_fowImage) {
+ free(_fowImage);
+ _fowImage = 0;
+ }
+}
+
+bool Moonbase::setFOWImage(int image) {
+ releaseFOWResources();
+
+ if (!_fowImage) {
+ Common::String fowImageFilename(ConfMan.get("MOONX_FOWImageFilename").c_str());
+
+#if 0 // TODO
+ if (!fowImageFilename.empty()) {
+ void *wiz = loadWizFromFilename(fowImageFilename);
+
+ if (wiz) {
+ captureFOWImageFromLocation(wiz, file.size());
+ free(wiz);
+ }
+ }
+#endif
+
+ if (!_fowImage && image < 0) {
+ int resId;
+
+ // PIECES BUBBLES CIRCLES SIMPLE* WEDGEY BUBBLE2
+ // WEDGE2 SPIKEY ANGLES SMOOTHED WUZZY SYS7-BEVELED
+ if (image >= -12 && image <= -1)
+ resId = 210 - image; // 211-222 range
+ else
+ resId = 214; // default, SIMPLE
+
+ if (_fileName.empty()) { // We are running for the first time
+ _fileName = _vm->generateFilename(-3);
+
+ if (!_exe.loadFromEXE(_fileName))
+ error("Cannot open file %s", _fileName.c_str());
+ }
+
+ Common::SeekableReadStream *stream = _exe.getResource(Common::kPERCData, resId);
+
+ if (stream->size()) {
+ _fowImage = (uint8 *)malloc(stream->size());
+
+ stream->read(_fowImage, stream->size());
+ }
+
+ delete stream;
+ }
+
+ if (!_fowImage && image > 0)
+ _fowImage = _vm->getResourceAddress(rtImage, image);
+
+ if (!_fowImage)
+ return false;
+ }
+
+ int nStates = _vm->_wiz->getWizImageStates(_fowImage);
+
+ if (nStates > FOW_ANIM_FRAME_COUNT) {
+ releaseFOWResources();
+ return false;
+ }
+
+ _fowAnimationFrames = (nStates + FOW_ANIM_FRAME_COUNT - 1) / FOW_ANIM_FRAME_COUNT;
+
+ _vm->_wiz->getWizImageDim(_fowImage, (nStates - 1), _fowTileW, _fowTileH);
+ _fowBlackMode = !_vm->_wiz->isWizPixelNonTransparent(_fowImage, nStates - 1, 0, 0, 0);
+
+ if (ConfMan.hasKey("EnableFOWRects"))
+ _fowBlackMode = (ConfMan.getInt("EnableFOWRects") == 1);
+
+ return true;
+}
+
+enum FOWElement {
+ FOW_EMPTY = 0,
+ FOW_SOLID = 1,
+
+ FF_L = 0x01,
+ FF_R = 0x02,
+ FF_T = 0x04,
+ FF_B = 0x08,
+ FF_T_L = 0x10,
+ FF_T_R = 0x20,
+ FF_B_L = 0x40,
+ FF_B_R = 0x80,
+ FF_Q_A = (FF_L | FF_T | FF_T_L),
+ FF_Q_B = (FF_R | FF_T | FF_T_R),
+ FF_Q_C = (FF_L | FF_B | FF_B_L),
+ FF_Q_D = (FF_R | FF_B | FF_B_R)
+};
+
+int Moonbase::readFOWVisibilityArray(int array, int y, int x) {
+ _vm->VAR(116) = array;
+
+ if (_vm->readArray(116, y, x) > 0)
+ return FOW_EMPTY;
+
+ return FOW_SOLID;
+}
+
+void Moonbase::setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int viewX, int viewY, int clipX1,
+ int clipY1, int clipX2, int clipY2, int technique, int nFrame) {
+ if (!_fowImage)
+ return;
+
+ _fowDrawX = clipX1;
+ _fowDrawY = clipY1;
+
+ _fowClipX1 = clipX1;
+ _fowClipY1 = clipY1;
+ _fowClipX2 = clipX2;
+ _fowClipY2 = clipY2;
+
+ // Figure out the number of tiles are involved
+ int view_W = (clipX2 - clipX1) + 1;
+ int view_H = (clipY2 - clipY1) + 1;
+
+ int tw = _fowTileW;
+ int th = _fowTileH;
+
+ int dw = acrossDim;
+ int dh = downDim;
+
+ int dlw = dw * tw;
+ int dlh = dh * th;
+
+ _fowMvx = (0 <= viewX) ? (viewX % dlw) : (dlw - (-viewX % dlw));
+ _fowMvy = (0 <= viewY) ? (viewY % dlh) : (dlh - (-viewY % dlh));
+
+ _fowVtx1 = _fowMvx / tw;
+ _fowVty1 = _fowMvy / th;
+
+ _fowVw = (((_fowMvx + view_W + tw - 1) / tw) - _fowVtx1) + 1;
+ _fowVh = (((_fowMvy + view_H + th - 1) / th) - _fowVty1) + 1;
+
+ // Build the connectivity table
+ int t = (_fowVty1 - 1); if (t >= dh) { t = 0; } else if (t < 0) { t = (dh - 1); }
+ int m = (_fowVty1 + 0); if (m >= dh) { m = 0; } else if (m < 0) { m = (dh - 1); }
+ int b = (_fowVty1 + 1); if (b >= dh) { b = 0; } else if (b < 0) { b = (dh - 1); }
+
+ int il = (_fowVtx1 - 1); if (il >= dh) { il = 0; } else if (il < 0) { il = (dw - 1); }
+ int ic = (_fowVtx1 + 0); if (ic >= dh) { ic = 0; } else if (ic < 0) { ic = (dw - 1); }
+ int ir = (_fowVtx1 + 1); if (ir >= dh) { ir = 0; } else if (ir < 0) { ir = (dw - 1); }
+
+ int dataOffset = (_fowVw * 3);
+ int dataOffset2 = (dataOffset * 2);
+ int *pOutterRenderTableA = _fowRenderTable;
+ int *pOutterRenderTableB = pOutterRenderTableA + dataOffset;
+
+ for (int ay = 0; ay < _fowVh; ay++) {
+ int l = il;
+ int c = ic;
+ int r = ir;
+
+ int *pRenderTableA = pOutterRenderTableA;
+ int *pRenderTableB = pOutterRenderTableB;
+
+ pOutterRenderTableA += dataOffset2;
+ pOutterRenderTableB += dataOffset2;
+
+ for (int ax = 0; ax < _fowVw; ax++) {
+ int visibility = readFOWVisibilityArray(fowInfoArray, m, c);
+
+ if (visibility == FOW_EMPTY) {
+ int bits = 0;
+
+ if (readFOWVisibilityArray(fowInfoArray, t, l) != 0) bits |= FF_T_L;
+ if (readFOWVisibilityArray(fowInfoArray, t, c) != 0) bits |= FF_T;
+ if (readFOWVisibilityArray(fowInfoArray, t, r) != 0) bits |= FF_T_R;
+ if (readFOWVisibilityArray(fowInfoArray, m, l) != 0) bits |= FF_L;
+ if (readFOWVisibilityArray(fowInfoArray, m, r) != 0) bits |= FF_R;
+ if (readFOWVisibilityArray(fowInfoArray, b, l) != 0) bits |= FF_B_L;
+ if (readFOWVisibilityArray(fowInfoArray, b, c) != 0) bits |= FF_B;
+ if (readFOWVisibilityArray(fowInfoArray, b, r) != 0) bits |= FF_B_R;
+
+ if (bits) {
+ *pRenderTableA++ = 1;
+ *pRenderTableB++ = 1;
+
+ // Quadrant (A)
+ if (bits & FF_Q_A) {
+ *pRenderTableA++ = (
+ ((FF_L & bits) ? 1 : 0) |
+ ((FF_T & bits) ? 2 : 0) |
+ ((FF_T_L & bits) ? 4 : 0)
+ ) + 0;
+ } else {
+ *pRenderTableA++ = 0;
+ }
+
+ // Quadrant (B)
+ if (bits & FF_Q_B) {
+ *pRenderTableA++ = (
+ ((FF_R & bits) ? 1 : 0) |
+ ((FF_T & bits) ? 2 : 0) |
+ ((FF_T_R & bits) ? 4 : 0)
+ ) + 8;
+ } else {
+ *pRenderTableA++ = 0;
+ }
+
+ // Quadrant (C)
+ if (bits & FF_Q_C) {
+ *pRenderTableB++ = (
+ ((FF_L & bits) ? 1 : 0) |
+ ((FF_B & bits) ? 2 : 0) |
+ ((FF_B_L & bits) ? 4 : 0)
+ ) + 16;
+ } else {
+ *pRenderTableB++ = 0;
+ }
+
+ // Quadrant (D)
+ if (bits & FF_Q_D) {
+ *pRenderTableB++ = (
+ ((FF_R & bits) ? 1 : 0) |
+ ((FF_B & bits) ? 2 : 0) |
+ ((FF_B_R & bits) ? 4 : 0)
+ ) + 24;
+ } else {
+ *pRenderTableB++ = 0;
+ }
+ } else {
+ *pRenderTableA++ = 0;
+ *pRenderTableB++ = 0;
+ }
+ } else {
+ if (_fowBlackMode) {
+ *pRenderTableA++ = 2;
+ *pRenderTableB++ = 2;
+ } else {
+ *pRenderTableA++ = 1;
+ *pRenderTableA++ = 33;
+ *pRenderTableA++ = 34;
+
+ *pRenderTableB++ = 1;
+ *pRenderTableB++ = 35;
+ *pRenderTableB++ = 36;
+ }
+ }
+
+ if (++l >= dw) { l = 0; }
+ if (++c >= dw) { c = 0; }
+ if (++r >= dw) { r = 0; }
+ }
+
+ if (++t >= dh) { t = 0; }
+ if (++m >= dh) { m = 0; }
+ if (++b >= dh) { b = 0; }
+ }
+
+ _fowCurrentFOWFrame = (nFrame >= 0) ? (nFrame % _fowAnimationFrames) : ((-nFrame) % _fowAnimationFrames);
+ _fowFrameBaseNumber = (_fowCurrentFOWFrame * FOW_ANIM_FRAME_COUNT);
+}
+
+void Moonbase::renderFOWState(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int x, int y, int srcw, int srch, int state, int flags) {
+ int32 spotx, spoty;
+
+ _vm->_wiz->getWizImageSpot(_fowImage, state, spotx, spoty);
+ Common::Rect r(_fowClipX1, _fowClipY1, _fowClipX2, _fowClipY2);
+
+ _vm->_wiz->drawWizImageEx(destSurface, _fowImage, 0, dstPitch, dstType, dstw, dsth, x - spotx, y - spoty, srcw, srch, state, &r, flags, 0, 0, 16, 0, 0);
+}
+
+static void blackRect_16bpp(uint8 *destSurface, int x1, int y1, int x2, int y2) {
+ // TODO
+}
+
+void Moonbase::renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int flags) {
+ if (!_fowImage)
+ return;
+
+ const int *pOutterRenderTable = _fowRenderTable;
+ int ixPos = ((_fowVtx1 * _fowTileW) - _fowMvx) + _fowDrawX;
+ int yPos = ((_fowVty1 * _fowTileH) - _fowMvy) + _fowDrawY;
+ int dataOffset = _fowVw * 3;
+ int halfTileHeight = _fowTileH / 2;
+ int cx2 = MIN(_fowClipX2, (dstw - 1));
+ int cy2 = MIN(_fowClipY2, (dsth - 1));
+
+ for (int ry = 0; ry < _fowVh; ry++) {
+ int real_yPos = yPos;
+
+ for (int i = 0; i < 2; i++) {
+ const int *pRenderTable = pOutterRenderTable;
+ pOutterRenderTable += dataOffset;
+
+ int xPos = ixPos;
+
+ for (int rx = 0; rx < _fowVw; rx++) {
+ int nState = *pRenderTable++;
+
+ if (nState != 0) {
+ if (nState == 2) {
+ int countLeft = (_fowVw - rx);
+ int count = 0;
+
+ for (; count < countLeft; count++) {
+ if (*(pRenderTable + count) != 2)
+ break;
+
+ pRenderTable++;
+ rx++;
+ }
+ count++;
+
+ int x1 = xPos;
+ int y1 = real_yPos;
+
+ xPos += _fowTileW * count;
+ int x2 = (xPos - 1);
+ int y2 = ((y1 + halfTileHeight) - 1);
+
+ x1 = MAX(0, x1);
+ y1 = MAX(0, y1);
+ x2 = MIN(x2, cx2);
+ y2 = MIN(y2, cy2);
+
+ if ((x2 >= x1) && (y2 >= y1) && (x1 <= _fowClipX2) && (y1 <= _fowClipY2))
+ blackRect_16bpp(destSurface, x1, y1, x2, y2);
+ } else {
+ int subState;
+
+ if ((subState = *pRenderTable++) != 0)
+ renderFOWState(destSurface, dstPitch, dstType, dstw, dsth, xPos, yPos, _fowTileW, _fowTileH, (subState + _fowFrameBaseNumber), flags);
+
+ if ((subState = *pRenderTable++) != 0)
+ renderFOWState(destSurface, dstPitch, dstType, dstw, dsth, xPos, yPos, _fowTileW, _fowTileH, (subState + _fowFrameBaseNumber), flags);
+
+ xPos += _fowTileW;
+ }
+ } else {
+ xPos += _fowTileW;
+ }
+ }
+ real_yPos += halfTileHeight;
+ }
+ yPos += _fowTileH;
+ }
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index e69308c067..7d56138247 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -1997,6 +1997,7 @@ void ScummEngine_v100he::o100_setSpriteInfo() {
_sprite->setSpriteFlagRemapPalette(spriteId, args[0]);
break;
default:
+ warning("Unknown sprite property %d for sprite %d", args[0], spriteId);
break;
}
break;
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index 9a456b86c0..2e0a03af7f 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -470,6 +470,10 @@ void SoundHE::processSoundOpcodes(int sound, byte *codePtr, int *soundVars) {
if (arg == 2) {
val = getSoundVar(sound, val);
}
+ if (!val) {
+ val = 1; // Safeguard for division by zero
+ warning("Incorrect value 0 for processSoundOpcodes() kludge DIV");
+ }
val = getSoundVar(sound, var) / val;
setSoundVar(sound, var, val);
break;
diff --git a/engines/scumm/he/sprite_he.cpp b/engines/scumm/he/sprite_he.cpp
index 245a986531..b192fab233 100644
--- a/engines/scumm/he/sprite_he.cpp
+++ b/engines/scumm/he/sprite_he.cpp
@@ -386,7 +386,7 @@ int Sprite::getSpriteGeneralProperty(int spriteId, int type) {
case 0x7B:
return _spriteTable[spriteId].imgFlags;
case 0x7D:
- return _spriteTable[spriteId].field_90;
+ return _spriteTable[spriteId].conditionBits;
case 0x7E:
return _spriteTable[spriteId].animProgress;
default:
@@ -746,7 +746,7 @@ void Sprite::setSpriteField84(int spriteId, int value) {
}
void Sprite::setSpriteGeneralProperty(int spriteId, int type, int value) {
- debug(0, "setSpriteGeneralProperty: spriteId %d type 0x%x", spriteId, type);
+ debug(0, "setSpriteGeneralProperty: spriteId %d type 0x%x value 0x%x", spriteId, type, value);
assertRange(1, spriteId, _varNumSprites, "sprite");
int32 delay;
@@ -758,7 +758,7 @@ void Sprite::setSpriteGeneralProperty(int spriteId, int type, int value) {
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
break;
case 0x7D:
- _spriteTable[spriteId].field_90 = value;
+ _spriteTable[spriteId].conditionBits = value;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
break;
case 0x7E:
@@ -799,7 +799,7 @@ void Sprite::resetSprite(int spriteId) {
_spriteTable[spriteId].priority = 0;
_spriteTable[spriteId].field_84 = 0;
_spriteTable[spriteId].imgFlags = 0;
- _spriteTable[spriteId].field_90 = 0;
+ _spriteTable[spriteId].conditionBits = 0;
if (_vm->_game.heversion >= 100) {
_spriteTable[spriteId].flags &= ~kSFMarkDirty;
@@ -1292,7 +1292,7 @@ void Sprite::processImages(bool arg) {
wiz.spriteId = spi->id;
wiz.spriteGroup = spi->group;
- wiz.field_23EA = spi->field_90;
+ wiz.conditionBits = spi->conditionBits;
spi->curImageState = wiz.img.state = imageState;
spi->curImage = wiz.img.resNum = image;
wiz.processFlags = kWPFNewState | kWPFSetPos;
@@ -1341,7 +1341,7 @@ void Sprite::processImages(bool arg) {
wiz.img.flags |= kWIFRemapPalette;
if (spi->field_84) {
wiz.processFlags |= 0x200000;
- wiz.img.field_390 = spi->field_84;
+ wiz.img.zbuffer = spi->field_84;
wiz.img.zorder = spi->priority;
}
if (spi->sourceImage) {
@@ -1426,7 +1426,7 @@ void Sprite::saveOrLoadSpriteData(Serializer *s) {
MKLINE(SpriteInfo, field_84, sleInt32, VER(48)),
MKLINE(SpriteInfo, classFlags, sleInt32, VER(48)),
MKLINE(SpriteInfo, imgFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, field_90, sleInt32, VER(48)),
+ MKLINE(SpriteInfo, conditionBits, sleInt32, VER(48)),
MKEND()
};
diff --git a/engines/scumm/he/sprite_he.h b/engines/scumm/he/sprite_he.h
index e31ccbf790..b1a7641fcc 100644
--- a/engines/scumm/he/sprite_he.h
+++ b/engines/scumm/he/sprite_he.h
@@ -79,7 +79,7 @@ struct SpriteInfo {
int32 field_84;
int32 classFlags;
int32 imgFlags;
- int32 field_90;
+ int32 conditionBits;
};
struct SpriteGroup {
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index 9a59609651..43994c33d6 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -31,6 +31,7 @@
#include "scumm/scumm.h"
#include "scumm/util.h"
#include "scumm/he/wiz_he.h"
+#include "scumm/he/moonbase/moonbase.h"
namespace Scumm {
@@ -976,7 +977,7 @@ void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, int dstType, const uin
}
}
-int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth) {
+int Wiz::isPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth) {
if (x < 0 || x >= w || y < 0 || y >= h) {
return 0;
}
@@ -1422,19 +1423,19 @@ void Wiz::displayWizImage(WizImage *pwi) {
wi->state = pwi->state;
wi->flags = pwi->flags;
wi->shadow = 0;
- wi->field_390 = 0;
+ wi->zbuffer = 0;
wi->palette = 0;
++_imagesNum;
} else if (pwi->flags & kWIFIsPolygon) {
drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, 0, 0, 0);
} else {
const Common::Rect *r = NULL;
- drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, _vm->getHEPaletteSlot(0));
+ drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, _vm->getHEPaletteSlot(0), 0);
}
}
-uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr) {
- debug(3, "drawWizImage(resNum %d, state %d maskNum %d maskState %d x1 %d y1 %d flags 0x%X zorder %d shadow %d field_390 %d dstResNum %d)", resNum, state, maskNum, maskState, x1, y1, flags, zorder, shadow, field_390, dstResNum);
+uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int zbuffer, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr, uint32 conditionBits) {
+ debug(3, "drawWizImage(resNum %d, state %d maskNum %d maskState %d x1 %d y1 %d flags 0x%X zorder %d shadow %d zbuffer %d dstResNum %d conditionBits: 0x%x)", resNum, state, maskNum, maskState, x1, y1, flags, zorder, shadow, zbuffer, dstResNum, conditionBits);
uint8 *dataPtr;
uint8 *dst = NULL;
@@ -1456,9 +1457,6 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
uint32 height = READ_LE_UINT32(wizh + 0x8);
debug(3, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d", comp, width, height);
- uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
- assert(wizd);
-
uint8 *mask = NULL;
if (maskNum) {
uint8 *maskPtr = _vm->getResourceAddress(rtImage, maskNum);
@@ -1574,58 +1572,261 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
transColor = (trns == NULL) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : -1;
}
+ if (_vm->_game.id == GID_MOONBASE &&
+ resNum == _vm->_moonbase->_fowSentinelImage &&
+ state == _vm->_moonbase->_fowSentinelState &&
+ conditionBits == _vm->_moonbase->_fowSentinelConditionBits) {
+ _vm->_moonbase->renderFOW(dst, dstPitch, dstType, cw, ch, flags);
+ x1 = 0;
+ y1 = 0;
+ width = rScreen.width();
+ height = rScreen.height();
+ } else {
+ drawWizImageEx(dst, dataPtr, mask, dstPitch, dstType, cw, ch, x1, y1, width, height,
+ state, &rScreen, flags, palPtr, transColor, _vm->_bytesPerPixel, xmapPtr, conditionBits);
+ }
+
+ if (!(flags & kWIFBlitToMemBuffer) && dstResNum == 0) {
+ Common::Rect rImage(x1, y1, x1 + width, y1 + height);
+ if (rImage.intersects(rScreen)) {
+ rImage.clip(rScreen);
+ if (!(flags & kWIFBlitToFrontVideoBuffer) && (flags & (kWIFBlitToFrontVideoBuffer | kWIFMarkBufferDirty))) {
+ ++rImage.bottom;
+ _vm->markRectAsDirty(kMainVirtScreen, rImage);
+ } else {
+ _vm->restoreBackgroundHE(rImage);
+ }
+ }
+ }
+
+ return dst;
+}
+
+void Wiz::drawWizImageEx(uint8 *dst, uint8 *dataPtr, uint8 *maskPtr, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *rect,
+ int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits) {
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
+ assert(wizh);
+ uint32 comp = READ_LE_UINT32(wizh + 0x0);
+ uint32 width = READ_LE_UINT32(wizh + 0x4);
+ uint32 height = READ_LE_UINT32(wizh + 0x8);
+ debug(3, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d", comp, width, height);
+
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
+ assert(wizd);
+
switch (comp) {
case 0:
- copyRawWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor, _vm->_bytesPerPixel);
+ copyRawWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, palPtr, transColor, bitDepth);
break;
case 1:
- if (flags & 0x80) {
+ if (flags & kWIFZPlaneOn) {
dst = _vm->getMaskBuffer(0, 0, 1);
dstPitch /= _vm->_bytesPerPixel;
- copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 2);
- } else if (flags & 0x100) {
+ copyWizImageWithMask(dst, wizd, dstPitch, dstw, dsth, srcx, srcy, srcw, srch, rect, 0, 2);
+ } else if (flags & kWIFZPlaneOff) {
dst = _vm->getMaskBuffer(0, 0, 1);
dstPitch /= _vm->_bytesPerPixel;
- copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 1);
+ copyWizImageWithMask(dst, wizd, dstPitch, dstw, dsth, srcx, srcy, srcw, srch, rect, 0, 1);
} else {
- copyWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr, _vm->_bytesPerPixel);
+ copyWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, palPtr, xmapPtr, bitDepth);
}
break;
#ifdef USE_RGB_COLOR
case 2:
- if (maskNum) {
- copyMaskWizImage(dst, wizd, mask, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr);
+ if (maskPtr) {
+ copyMaskWizImage(dst, wizd, maskPtr, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, palPtr);
} else {
- copyRaw16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, transColor);
+ copyRaw16BitWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, transColor);
}
break;
case 4:
- // TODO: Unknown image type
+ copyCompositeWizImage(dst, dataPtr, wizd, maskPtr, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, state, rect, flags, palPtr, transColor, bitDepth, xmapPtr, conditionBits);
break;
case 5:
- copy16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, xmapPtr);
+ copy16BitWizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, srcw, srch, rect, flags, xmapPtr);
+ break;
+ case 9:
+ copy555WizImage(dst, wizd, dstPitch, dstType, dstw, dsth, srcx, srcy, rect, conditionBits);
break;
#endif
default:
- error("drawWizImage: Unhandled wiz compression type %d", comp);
+ error("drawWizImageEx: Unhandled wiz compression type %d", comp);
}
+}
- if (!(flags & kWIFBlitToMemBuffer) && dstResNum == 0) {
- Common::Rect rImage(x1, y1, x1 + width, y1 + height);
- if (rImage.intersects(rScreen)) {
- rImage.clip(rScreen);
- if (!(flags & kWIFBlitToFrontVideoBuffer) && (flags & (kWIFBlitToFrontVideoBuffer | kWIFMarkBufferDirty))) {
- ++rImage.bottom;
- _vm->markRectAsDirty(kMainVirtScreen, rImage);
- } else {
- _vm->restoreBackgroundHE(rImage);
+#ifdef USE_RGB_COLOR
+
+void Wiz::copyCompositeWizImage(uint8 *dst, uint8 *wizPtr, uint8 *compositeInfoBlockPtr, uint8 *maskPtr, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *clipBox,
+ int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits) {
+
+ uint8 *nestedBlockHeader = _vm->heFindResource(MKTAG('N','E','S','T'), wizPtr);
+ assert(nestedBlockHeader);
+
+ uint8 *nestedWizHeader = _vm->heFindResource(MKTAG('M','U','L','T'), nestedBlockHeader);
+ assert(nestedWizHeader);
+
+ uint16 layerCount = READ_LE_UINT16(compositeInfoBlockPtr);
+ compositeInfoBlockPtr += 2;
+
+ uint16 defaultSubConditionBits = (conditionBits & kWMSBReservedBits);
+
+ conditionBits &= ~kWMSBReservedBits;
+
+ for (uint layerCounter = 0; layerCounter < layerCount; layerCounter++) {
+ int cmdSize = READ_LE_UINT16(compositeInfoBlockPtr);
+ uint8 *cmdPtr = compositeInfoBlockPtr + 2;
+
+ compositeInfoBlockPtr += (cmdSize + 2);
+ uint32 layerCmdDataBits = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+
+ uint32 subConditionBits;
+
+ if (layerCmdDataBits & kWCFConditionBits) {
+ uint32 layerConditionBits = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+
+ subConditionBits = (layerConditionBits & kWMSBReservedBits);
+ layerConditionBits &= ~kWMSBReservedBits;
+
+ if (subConditionBits == 0)
+ subConditionBits = defaultSubConditionBits;
+
+ uint32 conditionType = (layerConditionBits & kWSPCCTBits);
+ layerConditionBits &= ~kWSPCCTBits;
+
+ switch (conditionType) {
+ case kWSPCCTAnd:
+ if (layerConditionBits != (layerConditionBits & conditionBits))
+ continue;
+ break;
+
+ case kWSPCCTNot:
+ if (layerConditionBits & conditionBits)
+ continue;
+ break;
+
+ case kWSPCCTOr:
+ default:
+ if (!(layerConditionBits & conditionBits))
+ continue;
+ break;
}
+ } else {
+ subConditionBits = defaultSubConditionBits;
}
+
+ uint16 subState;
+ if (layerCmdDataBits & kWCFSubState) {
+ subState = READ_LE_UINT16(cmdPtr);
+ cmdPtr += 2;
+ } else {
+ subState = 0;
+ }
+
+ int16 xPos;
+ if (layerCmdDataBits & kWCFXDelta) {
+ xPos = (int16)READ_LE_UINT16(cmdPtr);
+ cmdPtr += 2;
+ } else {
+ xPos = 0;
+ }
+
+ int16 yPos;
+ if (layerCmdDataBits & kWCFYDelta) {
+ yPos = (int16)READ_LE_UINT16(cmdPtr);
+ cmdPtr += 2;
+ } else {
+ yPos = 0;
+ }
+
+ uint32 drawFlags;
+ if (layerCmdDataBits & kWCFDrawFlags) {
+ drawFlags = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+ } else {
+ drawFlags = flags;
+ }
+
+ uint srcw1, srch1;
+ if (drawFlags & (kWIFFlipX | kWIFFlipY)) {
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), wizPtr, subState, 0);
+ assert(wizh);
+ srcw1 = READ_LE_UINT32(wizh + 0x4);
+ srch1 = READ_LE_UINT32(wizh + 0x8);
+ }
+
+ if (drawFlags & kWIFFlipX)
+ xPos = (srcw - (xPos + srcw1));
+
+ if (drawFlags & kWIFFlipY)
+ yPos = (srch - (yPos + srch1));
+
+ if (layerCmdDataBits & kWCFSubConditionBits) {
+ subConditionBits = READ_LE_UINT32(cmdPtr);
+ cmdPtr += 4;
+ }
+
+ drawWizImageEx(dst, nestedWizHeader, maskPtr, dstPitch, dstType, dstw, dsth, srcx + xPos, srcy + yPos, srcw, srch,
+ subState, clipBox, drawFlags, palPtr, transColor, bitDepth, xmapPtr, subConditionBits);
+ }
+}
+
+void Wiz::copy555WizImage(uint8 *dst, uint8 *wizd, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, const Common::Rect *clipBox, uint32 conditionBits) {
+
+ int rawROP = conditionBits & kWMSBRopMask;
+ int paramROP = (conditionBits & kWMSBReservedBits) >> kWMSBRopParamRShift;
+
+ switch (rawROP) {
+ default:
+ case 1:
+ rawROP = 1;
+ // MMX_PREMUL_ALPHA_COPY
+ break;
+
+ case 2:
+ //warning("T14: MMX_ADDITIVE");
+ break;
+
+ case 3:
+ warning("T14: MMX_SUBTRACTIVE");
+ break;
+
+ case 4:
+ warning("T14: MMX_CONSTANT_ALPHA");
+ break;
+
+ case 5:
+ //warning("T14: MMX_CHEAP_50_50");
+ break;
+
+ case 6:
+ warning("T14: COPY");
+ break;
+
+ case 7:
+ warning("T14: CHEAP_50_50");
+ break;
+ }
+
+
+ uint32 compID = READ_LE_UINT32(wizd);
+
+ if (compID == 0x12340102) {
+ _vm->_moonbase->blitT14WizImage(dst, dstw, dsth, dstPitch, clipBox, wizd, srcx, srcy, rawROP, paramROP);
+ } else if (compID == 0x12340802) {
+ warning("Distorion codec");
+ } else if (compID == 0x12340902) {
+ error("Unsupported Distortion");
}
- return dst;
}
+#endif
+
struct PolygonDrawData {
struct PolygonArea {
int32 xmin;
@@ -1747,7 +1948,7 @@ void Wiz::captureWizPolygon(int resNum, int maskNum, int maskState, int id1, int
assert(maskNum);
const Common::Rect *r = NULL;
- const uint8 *src = drawWizImage(maskNum, maskState, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0);
+ const uint8 *src = drawWizImage(maskNum, maskState, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0, 0);
getWizImageDim(maskNum, maskState, srcw, srch);
dstw = wp->bound.width();
@@ -1815,7 +2016,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
debug(0, "drawWizPolygonTransform() unhandled flag 0x800000");
}
- srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, flags, 0, _vm->getHEPaletteSlot(palette));
+ srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, flags, 0, _vm->getHEPaletteSlot(palette), 0);
} else {
assert(_vm->_bytesPerPixel == 1);
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
@@ -1826,7 +2027,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
}
} else {
if (getWizImageData(resNum, state, 0) != 0) {
- srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette));
+ srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette), 0);
} else {
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
@@ -2001,7 +2202,7 @@ void Wiz::flushWizBuffer() {
drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, pwi->shadow, 0, pwi->palette);
} else {
const Common::Rect *r = NULL;
- drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->field_390, r, pwi->flags, 0, _vm->getHEPaletteSlot(pwi->palette));
+ drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->zbuffer, r, pwi->flags, 0, _vm->getHEPaletteSlot(pwi->palette), 0);
}
}
_imagesNum = 0;
@@ -2023,7 +2224,7 @@ void Wiz::loadWizCursor(int resId, int palette) {
const Common::Rect *r = NULL;
_cursorImage = true;
- uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette));
+ uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette), 0);
_cursorImage = false;
int32 cw, ch;
@@ -2073,10 +2274,10 @@ void Wiz::displayWizComplexImage(const WizParameters *params) {
if (params->processFlags & kWPFShadow) {
shadow = params->img.shadow;
}
- int field_390 = 0;
- if (params->processFlags & 0x200000) {
- field_390 = params->img.field_390;
- debug(0, "displayWizComplexImage() unhandled flag 0x200000");
+ int zbuffer = 0;
+ if (params->processFlags & kWPFZBuffer) {
+ zbuffer = params->img.zbuffer;
+ debug(0, "displayWizComplexImage() unhandled flag kWPFZBuffer");
}
const Common::Rect *r = NULL;
if (params->processFlags & kWPFClipBox) {
@@ -2104,19 +2305,19 @@ void Wiz::displayWizComplexImage(const WizParameters *params) {
pwi->state = state;
pwi->flags = flags;
pwi->shadow = shadow;
- pwi->field_390 = field_390;
+ pwi->zbuffer = zbuffer;
pwi->palette = palette;
++_imagesNum;
} else {
if (sourceImage != 0) {
- drawWizImage(params->sourceImage, 0, params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette));
+ drawWizImage(params->sourceImage, 0, params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, zbuffer, r, flags, dstResNum, _vm->getHEPaletteSlot(palette), 0);
} else if (params->processFlags & (kWPFScaled | kWPFRotate)) {
drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, shadow, rotationAngle, scale, r, flags, dstResNum, palette);
} else {
if (flags & kWIFIsPolygon) {
drawWizPolygon(params->img.resNum, state, po_x, flags, shadow, dstResNum, palette);
} else {
- drawWizImage(params->img.resNum, state, 0, 0, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette));
+ drawWizImage(params->img.resNum, state, 0, 0, po_x, po_y, params->img.zorder, shadow, zbuffer, r, flags, dstResNum, _vm->getHEPaletteSlot(palette), params->conditionBits);
}
}
}
@@ -2501,6 +2702,10 @@ void Wiz::processWizImage(const WizParameters *params) {
void Wiz::getWizImageDim(int resNum, int state, int32 &w, int32 &h) {
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
+ getWizImageDim(dataPtr, state, w, h);
+}
+
+void Wiz::getWizImageDim(uint8 *dataPtr, int state, int32 &w, int32 &h) {
uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
w = READ_LE_UINT32(wizh + 0x4);
@@ -2510,6 +2715,10 @@ void Wiz::getWizImageDim(int resNum, int state, int32 &w, int32 &h) {
void Wiz::getWizImageSpot(int resId, int state, int32 &x, int32 &y) {
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resId);
assert(dataPtr);
+ getWizImageSpot(dataPtr, state, x, y);
+}
+
+void Wiz::getWizImageSpot(uint8 *dataPtr, int state, int32 &x, int32 &y) {
uint8 *spotPtr = _vm->findWrappedBlock(MKTAG('S','P','O','T'), dataPtr, state, 0);
if (spotPtr) {
x = READ_LE_UINT32(spotPtr + 0);
@@ -2547,6 +2756,11 @@ int Wiz::getWizImageData(int resNum, int state, int type) {
int Wiz::getWizImageStates(int resNum) {
const uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
+
+ return getWizImageStates(dataPtr);
+}
+
+int Wiz::getWizImageStates(const uint8 *dataPtr) {
if (READ_BE_UINT32(dataPtr) == MKTAG('M','U','L','T')) {
const byte *offs, *wrap;
@@ -2565,9 +2779,14 @@ int Wiz::getWizImageStates(int resNum) {
}
int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags) {
- int ret = 0;
uint8 *data = _vm->getResourceAddress(rtImage, resNum);
assert(data);
+
+ return isWizPixelNonTransparent(data, state, x, y, flags);
+}
+
+int Wiz::isWizPixelNonTransparent(uint8 *data, int state, int x, int y, int flags) {
+ int ret = 0;
uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), data, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
@@ -2591,19 +2810,20 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags
}
break;
case 1:
- ret = isWizPixelNonTransparent(wizd, x, y, w, h, 1);
+ ret = isPixelNonTransparent(wizd, x, y, w, h, 1);
break;
#ifdef USE_RGB_COLOR
case 2:
ret = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
break;
- case 4:
- // TODO: Unknown image type
- ret = 1;
- debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
+ case 4: {
+ uint16 color = 0xffff;
+ copyCompositeWizImage((byte *)&color, data, wizd, 0, 2, kDstMemory, 1, 1, -x, -y, w, h, state, 0, 0, 0, 0, 2, 0, 0);
+ ret = color != 0xffff;
break;
+ }
case 5:
- ret = isWizPixelNonTransparent(wizd, x, y, w, h, 2);
+ ret = isPixelNonTransparent(wizd, x, y, w, h, 2);
break;
#endif
default:
@@ -2641,8 +2861,7 @@ uint16 Wiz::getWizPixelColor(int resNum, int state, int x, int y) {
color = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
break;
case 4:
- // TODO: Unknown image type
- debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c);
+ copyCompositeWizImage((byte *)&color, data, wizd, 0, 2, kDstMemory, 1, 1, -x, -y, w, h, state, 0, 0, 0, 0, 2, 0, 0);
break;
case 5:
color = getWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
diff --git a/engines/scumm/he/wiz_he.h b/engines/scumm/he/wiz_he.h
index 974b394d61..692ad76db5 100644
--- a/engines/scumm/he/wiz_he.h
+++ b/engines/scumm/he/wiz_he.h
@@ -43,7 +43,7 @@ struct WizImage {
int state;
int flags;
int shadow;
- int field_390;
+ int zbuffer;
int palette;
};
@@ -102,10 +102,10 @@ struct WizParameters {
FontProperties fontProperties;
EllipseProperties ellipseProperties;
Common::Rect box2;
- int field_23DE;
+ int blendFlags;
int spriteId;
int spriteGroup;
- int field_23EA;
+ int conditionBits;
WizImage img;
};
@@ -117,6 +117,9 @@ enum WizImageFlags {
kWIFMarkBufferDirty = 0x10,
kWIFBlitToMemBuffer = 0x20,
kWIFIsPolygon = 0x40,
+ kWIFZPlaneOn = 0x80,
+ kWIFZPlaneOff = 0x100,
+ kWIFUseShadow = 0x200,
kWIFFlipX = 0x400,
kWIFFlipY = 0x800
};
@@ -138,7 +141,31 @@ enum WizProcessFlags {
kWPFFillColor = 0x20000,
kWPFClipBox2 = 0x40000,
kWPFMaskImg = 0x80000,
- kWPFParams = 0x100000
+ kWPFParams = 0x100000,
+ kWPFZBuffer = 0x200000
+};
+
+enum WizCompositeFlags {
+ kWCFConditionBits = 0x01,
+ kWCFSubState = 0x02,
+ kWCFXDelta = 0x04,
+ kWCFYDelta = 0x08,
+ kWCFDrawFlags = 0x10,
+ kWCFSubConditionBits = 0x20
+};
+
+enum WizSpcConditionTypes {
+ kWSPCCTBits = 0xc0000000,
+ kWSPCCTOr = 0x00000000,
+ kWSPCCTAnd = 0x40000000,
+ kWSPCCTNot = 0x80000000
+};
+
+enum WizMoonSystemBits {
+ kWMSBRopMask = 0xff,
+ kWMSBRopParamMask = 0xff00,
+ kWMSBReservedBits = (kWMSBRopMask | kWMSBRopParamMask),
+ kWMSBRopParamRShift = 8
};
enum {
@@ -193,14 +220,19 @@ public:
void remapWizImagePal(const WizParameters *params);
void getWizImageDim(int resNum, int state, int32 &w, int32 &h);
+ void getWizImageDim(uint8 *dataPtr, int state, int32 &w, int32 &h);
int getWizImageStates(int resnum);
+ int getWizImageStates(const uint8 *ptr);
int isWizPixelNonTransparent(int resnum, int state, int x, int y, int flags);
+ int isWizPixelNonTransparent(uint8 *data, int state, int x, int y, int flags);
+ int isPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint8 bitdepth);
uint16 getWizPixelColor(int resnum, int state, int x, int y);
int getWizImageData(int resNum, int state, int type);
void flushWizBuffer();
void getWizImageSpot(int resId, int state, int32 &x, int32 &y);
+ void getWizImageSpot(uint8 *data, int state, int32 &x, int32 &y);
void loadWizCursor(int resId, int palette);
void captureWizImage(int resNum, const Common::Rect& r, bool frontBuffer, int compType);
@@ -210,7 +242,8 @@ public:
void displayWizImage(WizImage *pwi);
void processWizImage(const WizParameters *params);
- uint8 *drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr);
+ uint8 *drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int zbuffer, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr, uint32 conditionBits);
+ void drawWizImageEx(uint8 *dst, uint8 *src, uint8 *mask, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits);
void drawWizPolygon(int resNum, int state, int id, int flags, int shadow, int dstResNum, int palette);
void drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int zoom, const Common::Rect *r, int flags, int dstResNum, int palette);
void drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette);
@@ -218,6 +251,12 @@ public:
#ifdef USE_RGB_COLOR
static void copyMaskWizImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr);
+
+ void copyCompositeWizImage(uint8 *dst, uint8 *wizPtr, uint8 *wizd, uint8 *maskPtr, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, int srcw, int srch, int state, const Common::Rect *clipBox,
+ int flags, const uint8 *palPtr, int transColor, uint8 bitDepth, const uint8 *xmapPtr, uint32 conditionBits);
+ void copy555WizImage(uint8 *dst, uint8 *wizd, int dstPitch, int dstType,
+ int dstw, int dsth, int srcx, int srcy, const Common::Rect *clipBox, uint32 conditionBits);
#endif
static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, uint8 bitdepth);
@@ -238,7 +277,6 @@ public:
template<int type> static void write8BitColor(uint8 *dst, const uint8 *src, int dstType, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth);
static void writeColor(uint8 *dstPtr, int dstType, uint16 color);
- int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint8 bitdepth);
uint16 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color);
uint16 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color);
void computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect& rCapt);
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 416a8f7ef9..c56ef7e5f4 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -136,9 +136,11 @@ MODULE_OBJS += \
he/logic/basketball.o \
he/logic/football.o \
he/logic/funshop.o \
- he/logic/moonbase.o \
+ he/logic/moonbase_logic.o \
he/logic/puttrace.o \
- he/logic/soccer.o
+ he/logic/soccer.o \
+ he/moonbase/moonbase.o \
+ he/moonbase/moonbase_fow.o
endif
# This module can be built as a plugin
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index e986ae4b47..68e4887b00 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Mon Mar 28 09:52:54 2016
+ This file was generated by the md5table tool on Sat Apr 30 14:24:41 2016
DO NOT EDIT MANUALLY!
*/
@@ -532,6 +532,7 @@ static const MD5Table md5table[] = {
{ "bf8b52fdd9a69c67f34e8e9fec72661c", "farm", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "bfdf584b01503f0762baded581f6a0a2", "SoccerMLS", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", 26159, Common::NL_NLD, Common::kPlatformWindows },
+ { "c0c9de81fb965e6cbe77f6e5631ca705", "monkey", "SE Talkie", "Unofficial SE Talkie v1.02", 9135, Common::EN_ANY, Common::kPlatformDOS },
{ "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD },
{ "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii },
@@ -672,6 +673,7 @@ static const MD5Table md5table[] = {
{ "f3c5d9bf3f091bd1f18dc1013fba5396", "atlantis", "Steam", "Steam", 638976, Common::EN_ANY, Common::kPlatformWindows },
{ "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", "", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows },
{ "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "HE 60", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "f4d20ab4ce19743a646cb48bd93aee72", "monkey2", "SE Talkie", "Unofficial SE Talkie v0.2", 10835, Common::EN_ANY, Common::kPlatformDOS },
{ "f5228b0cc1c19e6ea8268ba2eeb61f60", "freddi", "HE 73", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "f73883f13b5a302749a5bad31d909780", "tentacle", "", "CD", -1, Common::DE_DEU, Common::kPlatformMacintosh },
{ "f7635a0e2ab82c9a0f9ace5f232a488f", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index e7118616ba..40f636c18f 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -66,6 +66,7 @@
#include "scumm/players/player_v5m.h"
#include "scumm/resource.h"
#include "scumm/he/resource_he.h"
+#include "scumm/he/moonbase/moonbase.h"
#include "scumm/scumm_v0.h"
#include "scumm/scumm_v8.h"
#include "scumm/sound.h"
@@ -733,7 +734,7 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
VAR_ACTIVE_VERB = 0xFF;
if (strcmp(dr.fp.pattern, "maniacdemo.d64") == 0 )
- _game.features |= GF_DEMO;
+ _game.features |= GF_DEMO;
}
ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr)
@@ -832,9 +833,16 @@ ScummEngine_v71he::ScummEngine_v71he(OSystem *syst, const DetectorResult &dr)
_skipProcessActors = 0;
VAR_WIZ_TCOLOR = 0xFF;
+
+ /* Moonbase stuff */
+ _moonbase = 0;
+
+ if (_game.id == GID_MOONBASE)
+ _moonbase = new Moonbase(this);
}
ScummEngine_v71he::~ScummEngine_v71he() {
+ delete _moonbase;
delete _wiz;
}
diff --git a/engines/sherlock/tattoo/tattoo_fixed_text.h b/engines/sherlock/tattoo/tattoo_fixed_text.h
index 7dbe13bbb3..eb636cdada 100644
--- a/engines/sherlock/tattoo/tattoo_fixed_text.h
+++ b/engines/sherlock/tattoo/tattoo_fixed_text.h
@@ -233,7 +233,7 @@ public:
virtual const Common::String getActionMessage(FixedTextActionId actionId, int messageIndex);
};
-} // End of namespace Scalpel
+} // End of namespace Tattoo
} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_journal.cpp b/engines/sherlock/tattoo/tattoo_journal.cpp
index 8e1a61d36e..4d4f37f8d5 100644
--- a/engines/sherlock/tattoo/tattoo_journal.cpp
+++ b/engines/sherlock/tattoo/tattoo_journal.cpp
@@ -50,7 +50,7 @@ void TattooJournal::show() {
Screen &screen = *_vm->_screen;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
byte palette[PALETTE_SIZE];
-
+
Common::Point oldScroll = screen._currentScroll;
screen._currentScroll = Common::Point(0, 0);
@@ -66,7 +66,7 @@ void TattooJournal::show() {
// Set screen to black, and set background
screen._backBuffer1.SHblitFrom((*_journalImages)[0], Common::Point(0, 0));
- screen.empty();
+ screen.clear();
screen.setPalette(palette);
if (_journal.empty()) {
@@ -87,12 +87,12 @@ void TattooJournal::show() {
handleKeyboardEvents();
highlightJournalControls(true);
-
+
handleButtons();
if (_wait)
events.wait(2);
-
+
} while (!_vm->shouldQuit() && !_exitJournal);
// Clear events
@@ -275,7 +275,7 @@ void TattooJournal::handleButtons() {
if (frameCounter >= _scrollingTimer) {
// Set next scrolling time
_scrollingTimer = frameCounter + 6;
-
+
// Handle different scrolling actions
switch (_selector) {
case JH_SCROLL_LEFT:
@@ -355,13 +355,13 @@ void TattooJournal::handleButtons() {
_savedIndex = _index;
_savedSub = _sub;
_savedPage = _page;
-
+
bool drawResult = drawJournal(dir + 2, 1000 * LINES_PER_PAGE);
if (!drawResult) {
_index = _savedIndex;
_sub = _savedSub;
_page = _savedPage;
-
+
drawFrame();
drawJournal(0, 0);
notFound = true;
@@ -539,7 +539,7 @@ void TattooJournal::drawControls(int mode) {
_oldSelector = 100;
switch (mode) {
- case 0:
+ case 0:
highlightJournalControls(false);
break;
case 1:
@@ -548,7 +548,7 @@ void TattooJournal::drawControls(int mode) {
default:
break;
}
-
+
_oldSelector = savedSelector;
}
@@ -558,7 +558,7 @@ void TattooJournal::highlightJournalControls(bool slamIt) {
Common::Point mousePos = events.mousePos();
Common::Rect r(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, SHERLOCK_SCREEN_HEIGHT - r.height());
-
+
if ((events._pressed || events._released) && _selector == JH_THUMBNAIL) {
if (events._released)
_selector = JH_NONE;
@@ -576,7 +576,7 @@ void TattooJournal::highlightJournalControls(bool slamIt) {
_selector = JH_NONE;
if (bounds.contains(mousePos))
_selector = (mousePos.x - r.left) / (r.width() / 3);
-
+
else if (events._pressed && mousePos.y >= (r.top + screen.fontHeight() + 10)
&& mousePos.y < (r.top + screen.fontHeight() + 10 + BUTTON_SIZE)) {
if (mousePos.x >= r.left && mousePos.x < (r.left + BUTTON_SIZE))
@@ -628,7 +628,7 @@ void TattooJournal::highlightJournalControls(bool slamIt) {
color = (_selector == JH_SAVE) ? COMMAND_HIGHLIGHTED : INFO_TOP;
else
color = INFO_BOTTOM;
- screen.gPrint(Common::Point(xp - screen.stringWidth(FIXED(SaveJournal)) / 2, r.top + 5),
+ screen.gPrint(Common::Point(xp - screen.stringWidth(FIXED(SaveJournal)) / 2, r.top + 5),
color, "%s", FIXED(SaveJournal));
// Draw the horizontal scrollbar
@@ -701,7 +701,7 @@ void TattooJournal::drawScrollBar() {
raised = _selector != JH_SCROLL_LEFT;
screen._backBuffer1.fillRect(Common::Rect(r.left, r.top + screen.fontHeight() + 12, r.left + BUTTON_SIZE,
r.top + screen.fontHeight() + BUTTON_SIZE + 9), INFO_MIDDLE);
- ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.left + 3, r.top + screen.fontHeight() + 10, r.left + 3 + BUTTON_SIZE,
+ ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.left + 3, r.top + screen.fontHeight() + 10, r.left + 3 + BUTTON_SIZE,
r.top + screen.fontHeight() + 10 + BUTTON_SIZE), raised);
color = (_page > 1) ? INFO_BOTTOM + 2 : INFO_BOTTOM;
@@ -716,15 +716,15 @@ void TattooJournal::drawScrollBar() {
// Draw the Scroll Right button
raised = _selector != JH_SCROLL_RIGHT;
- screen._backBuffer1.fillRect(Common::Rect(r.right - BUTTON_SIZE - 1, r.top + screen.fontHeight() + 12,
+ screen._backBuffer1.fillRect(Common::Rect(r.right - BUTTON_SIZE - 1, r.top + screen.fontHeight() + 12,
r.right - 5, r.top + screen.fontHeight() + BUTTON_SIZE + 9), INFO_MIDDLE);
ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.right - BUTTON_SIZE - 3, r.top + screen.fontHeight() + 10, r.right - 3,
r.top + screen.fontHeight() + BUTTON_SIZE + 9), raised);
color = _down ? INFO_BOTTOM + 2 : INFO_BOTTOM;
- screen._backBuffer1.vLine(r.right - 1 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2,
+ screen._backBuffer1.vLine(r.right - 1 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2,
r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2, color);
- screen._backBuffer1.vLine(r.right - 2 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 9 + BUTTON_SIZE / 2,
+ screen._backBuffer1.vLine(r.right - 2 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 9 + BUTTON_SIZE / 2,
r.top + screen.fontHeight() + 11 + BUTTON_SIZE / 2, color);
screen._backBuffer1.vLine(r.right - 3 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 8 + BUTTON_SIZE / 2,
r.top + screen.fontHeight() + 12 + BUTTON_SIZE / 2, color);
@@ -776,14 +776,14 @@ int TattooJournal::getFindName(bool printError) {
drawControls(1);
disableControls();
-
+
// Backup the area under the text entry
Surface bgSurface(r.width() - 6, screen.fontHeight());
- bgSurface.SHblitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(r.left + 3, cursorY,
+ bgSurface.SHblitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(r.left + 3, cursorY,
r.right - 3, cursorY + screen.fontHeight()));
if (printError) {
- screen.gPrint(Common::Point(r.left + (r.width() - screen.stringWidth(FIXED(TextNotFound))) / 2, cursorY),
+ screen.gPrint(Common::Point(r.left + (r.width() - screen.stringWidth(FIXED(TextNotFound))) / 2, cursorY),
INFO_TOP, "%s", FIXED(TextNotFound));
} else {
// If there was a name already entered, copy it to name and display it
@@ -977,7 +977,7 @@ void TattooJournal::saveJournal() {
int line = 0;
// Copy all of the talk files entries into one big string
- do {
+ do {
if (_lines[line].hasPrefix("@")) {
text += Common::String(_lines[line].c_str() + 1);
if ((line + 1) < (int)_lines.size() && _lines[line + 1].hasPrefix("@"))
@@ -992,7 +992,7 @@ void TattooJournal::saveJournal() {
// which show up as a blank line with the next line starting
// with a '@'. We have to add a line break here because the '@' handler
// previously assumes that they're always following a blank line
-
+
if ((_lines[line].empty() || _lines[line] == " ")
&& (line + 1) < (int)_lines.size() && _lines[line + 1].hasPrefix("@"))
text += "\n";
@@ -1005,7 +1005,7 @@ void TattooJournal::saveJournal() {
do {
if (text.size() > 80) {
const char *msgP = text.c_str() + 80;
-
+
if (Common::String(text.c_str(), msgP).contains("\n")) {
// The 80 characters contain a carriage return,
// so we can print out that line
@@ -1013,7 +1013,7 @@ void TattooJournal::saveJournal() {
file->writeString(Common::String(text.c_str(), cr));
text = Common::String(cr + 1);
} else {
- // Move backwards to find a word break
+ // Move backwards to find a word break
while (*msgP != ' ')
--msgP;
diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h
index e0d53c67dd..c844d86e19 100644
--- a/engines/sherlock/tattoo/tattoo_people.h
+++ b/engines/sherlock/tattoo/tattoo_people.h
@@ -273,9 +273,8 @@ public:
virtual void setListenSequence(int speaker, int sequenceNum = 1);
};
-} // End of namespace Scalpel
+} // End of namespace Tattoo
} // End of namespace Sherlock
-
#endif
diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index 9f78234aba..99e6daa756 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -167,7 +167,7 @@ ControlStatus::~ControlStatus() {
void ControlStatus::setToText(const char *newText) {
char tmpLine[256];
- strcpy(tmpLine, newText);
+ Common::strlcpy(tmpLine, newText, 256);
if (_textData) {
_statusText->flushForRedraw();
free(_textData);
diff --git a/engines/sword2/screen.cpp b/engines/sword2/screen.cpp
index 0cb951fdfc..40baf67e46 100644
--- a/engines/sword2/screen.cpp
+++ b/engines/sword2/screen.cpp
@@ -1296,7 +1296,7 @@ void Screen::setPsxScrCache(byte *psxScrCache, uint8 level) {
}
byte *Screen::getPsxScrCache(uint8 level) {
- if (level > 3) {
+ if (level > 2) {
level = 0;
}
@@ -1307,7 +1307,7 @@ byte *Screen::getPsxScrCache(uint8 level) {
}
bool Screen::getPsxScrCacheStatus(uint8 level) {
- if (level > 3) {
+ if (level > 2) {
level = 0;
}
diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp
index a678fdccad..5d35a4f47e 100644
--- a/engines/sword25/gfx/image/vectorimage.cpp
+++ b/engines/sword25/gfx/image/vectorimage.cpp
@@ -217,6 +217,7 @@ Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement)
VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, const Common::String &fname) : _pixelData(0), _fname(fname) {
success = false;
+ _bgColor = 0;
// Create bitstream object
// In the following the file data will be readout of the bitstream object.
diff --git a/engines/sword25/gfx/renderobject.cpp b/engines/sword25/gfx/renderobject.cpp
index c109e49aa8..92d39c252d 100644
--- a/engines/sword25/gfx/renderobject.cpp
+++ b/engines/sword25/gfx/renderobject.cpp
@@ -71,19 +71,18 @@ RenderObject::RenderObject(RenderObjectPtr<RenderObject> parentPtr, TYPES type,
_version(++_nextGlobalVersion),
_isSolid(false) {
- // Renderobject registrieren, abhängig vom Handle-Parameter entweder mit beliebigem oder vorgegebenen Handle.
if (handle == 0)
_handle = RenderObjectRegistry::instance().registerObject(this);
else
_handle = RenderObjectRegistry::instance().registerObject(this, handle);
if (_handle == 0)
- return;
+ error("Failed to initialize RenderObject()");
updateAbsolutePos();
- // Dieses Objekt zu den Kindern der Elternobjektes hinzufügen, falls nicht Wurzel (ParentPtr ungültig) und dem
- // selben RenderObjektManager zuweisen.
+ // Add this item to the children of the parent object, if not root (ParentPtr is invalid),
+ // assign to the same RenderObjectManager.
if (_parentPtr.isValid()) {
_managerPtr = _parentPtr->getManager();
_parentPtr->addObject(this->getHandle());
@@ -100,24 +99,22 @@ RenderObject::RenderObject(RenderObjectPtr<RenderObject> parentPtr, TYPES type,
}
RenderObject::~RenderObject() {
- // Objekt aus dem Elternobjekt entfernen.
+ // Remove object from its parent.
if (_parentPtr.isValid())
_parentPtr->detatchChildren(this->getHandle());
deleteAllChildren();
- // Objekt deregistrieren.
RenderObjectRegistry::instance().deregisterObject(this);
}
void RenderObject::preRender(RenderObjectQueue *renderQueue) {
- // Objektänderungen validieren
validateObject();
if (!_visible)
return;
- // Falls notwendig, wird die Renderreihenfolge der Kinderobjekte aktualisiert.
+ // If necessary, update the children rendering order of the updated objects.
if (_childChanged) {
sortRenderObjects();
_childChanged = false;
@@ -149,7 +146,7 @@ bool RenderObject::render(RectangleList *updateRects, const Common::Array<int> &
if (needRender)
doRender(updateRects);
- // Dann müssen die Kinder gezeichnet werden
+ // Draw all children
RENDEROBJECT_ITER it = _children.begin();
for (; it != _children.end(); ++it)
if (!(*it)->render(updateRects, updateRectsMinZ))
@@ -159,7 +156,6 @@ bool RenderObject::render(RectangleList *updateRects, const Common::Array<int> &
}
void RenderObject::validateObject() {
- // Die Veränderungen in den Objektvariablen aufheben
_oldBbox = _bbox;
_oldVisible = _visible;
_oldX = _x;
@@ -169,15 +165,14 @@ void RenderObject::validateObject() {
}
bool RenderObject::updateObjectState() {
- // Falls sich das Objekt verändert hat, muss der interne Zustand neu berechnet werden und evtl. Update-Regions für den nächsten Frame
- // registriert werden.
+ // If the object has changed, the internal state must be recalculated and possibly
+ // update Regions be registered for the next frame.
if ((calcBoundingBox() != _oldBbox) ||
(_visible != _oldVisible) ||
(_x != _oldX) ||
(_y != _oldY) ||
(_z != _oldZ) ||
_refreshForced) {
- // Renderrang des Objektes neu bestimmen, da sich dieser verändert haben könnte
if (_parentPtr.isValid())
_parentPtr->signalChildChange();
@@ -200,12 +195,10 @@ bool RenderObject::updateObjectState() {
}
void RenderObject::updateBoxes() {
- // Bounding-Box aktualisieren
_bbox = calcBoundingBox();
}
Common::Rect RenderObject::calcBoundingBox() const {
- // Die Bounding-Box mit der Objektgröße initialisieren.
Common::Rect bbox(0, 0, _width, _height);
// Die absolute Position der Bounding-Box berechnen.
@@ -247,8 +240,6 @@ int32 RenderObject::calcAbsoluteZ() const {
}
void RenderObject::deleteAllChildren() {
- // Es ist nicht notwendig die Liste zu iterieren, da jedes Kind für sich DetatchChildren an diesem Objekt aufruft und sich somit
- // selber entfernt. Daher muss immer nur ein beliebiges Element (hier das letzte) gelöscht werden, bis die Liste leer ist.
while (!_children.empty()) {
RenderObjectPtr<RenderObject> curPtr = _children.back();
curPtr.erase();
@@ -261,10 +252,10 @@ bool RenderObject::addObject(RenderObjectPtr<RenderObject> pObject) {
return false;
}
- // Objekt in die Kinderliste einfügen.
+ // Insert Object in the children list.
_children.push_back(pObject);
- // Sicherstellen, dass vor dem nächsten Rendern die Renderreihenfolge aktualisiert wird.
+ // Make sure that before the next render the channel order is updated.
if (_parentPtr.isValid())
_parentPtr->signalChildChange();
diff --git a/engines/teenagent/music.cpp b/engines/teenagent/music.cpp
index 5d66c3c90c..795b8f7312 100644
--- a/engines/teenagent/music.cpp
+++ b/engines/teenagent/music.cpp
@@ -36,7 +36,7 @@ static const uint32 noteToPeriod[3][12] = {
{214, 201, 189, 179, 170, 160, 151, 143, 135, 127, 120, 113}
};
-MusicPlayer::MusicPlayer(TeenAgentEngine *vm) : Paula(false, 44100, 5000), _vm(vm), _id(0) {
+MusicPlayer::MusicPlayer(TeenAgentEngine *vm) : Paula(false, 44100, 5000), _vm(vm), _id(0), _currRow(0) {
}
MusicPlayer::~MusicPlayer() {
@@ -55,7 +55,7 @@ bool MusicPlayer::load(int id) {
Common::StackLock lock(_mutex);
// Load the samples
- sampleCount = stream->readByte();
+ byte sampleCount = stream->readByte();
debugC(0, kDebugMusic, "sampleCount = %d", sampleCount);
diff --git a/engines/teenagent/music.h b/engines/teenagent/music.h
index e1630cc845..4b1b683a30 100644
--- a/engines/teenagent/music.h
+++ b/engines/teenagent/music.h
@@ -74,7 +74,6 @@ private:
size = 0;
}
} _samples[256];
- byte sampleCount;
Common::Array<Row> _rows;
uint _currRow;
diff --git a/engines/teenagent/objects.h b/engines/teenagent/objects.h
index f923ae52ab..1f8a82a66e 100644
--- a/engines/teenagent/objects.h
+++ b/engines/teenagent/objects.h
@@ -165,7 +165,7 @@ struct Object {
//19
Common::String name, description;
- Object(): _base(NULL) {}
+ Object(): _base(NULL) { id = 0; actorOrientation = 0; enabled = 0; }
void dump(int level = 0) const;
void setName(const Common::String &newName);
void load(byte *addr);
@@ -205,7 +205,7 @@ struct Walkbox {
Rect rect;
byte sideHint[4];
- Walkbox() : _base(NULL) {}
+ Walkbox() : _base(NULL) { memset(this, 0, sizeof(Walkbox)); }
void dump(int level = 0) const;
void load(byte *src);
void save() const;
diff --git a/engines/teenagent/scene.cpp b/engines/teenagent/scene.cpp
index 6e1cef31bc..c250269844 100644
--- a/engines/teenagent/scene.cpp
+++ b/engines/teenagent/scene.cpp
@@ -71,6 +71,9 @@ Scene::Scene(TeenAgentEngine *vm) : _vm(vm), intro(false), _id(0), ons(0),
varia.close();
loadObjectData();
+
+ _onsCount = 0;
+ _messageColor = 0;
}
Scene::~Scene() {
@@ -314,7 +317,7 @@ void Scene::loadOns() {
uint16 addr = _vm->res->dseg.get_word(dsAddr_onsAnimationTablePtr + (_id - 1) * 2);
debugC(0, kDebugScene, "ons index: %04x", addr);
- onsCount = 0;
+ _onsCount = 0;
byte b;
byte onId[16];
while ((b = _vm->res->dseg.get_byte(addr)) != 0xff) {
@@ -323,15 +326,15 @@ void Scene::loadOns() {
if (b == 0)
continue;
- onId[onsCount++] = b;
+ onId[_onsCount++] = b;
}
delete[] ons;
ons = NULL;
- if (onsCount > 0) {
- ons = new Surface[onsCount];
- for (uint32 i = 0; i < onsCount; ++i) {
+ if (_onsCount > 0) {
+ ons = new Surface[_onsCount];
+ for (uint32 i = 0; i < _onsCount; ++i) {
Common::ScopedPtr<Common::SeekableReadStream> s(_vm->res->ons.getStream(onId[i]));
if (s) {
ons[i].load(*s, Surface::kTypeOns);
@@ -498,7 +501,7 @@ bool Scene::processEvent(const Common::Event &event) {
events.clear();
sounds.clear();
currentEvent.clear();
- messageColor = textColorMark;
+ _messageColor = textColorMark;
for (int i = 0; i < 4; ++i)
customAnimation[i].free();
_vm->playMusic(4);
@@ -651,7 +654,7 @@ bool Scene::render(bool tickGame, bool tickMark, uint32 messageDelta) {
bool gotAnyAnimation = false;
if (ons != NULL && debugFeatures.feature[DebugFeatures::kShowOns]) {
- for (uint32 i = 0; i < onsCount; ++i) {
+ for (uint32 i = 0; i < _onsCount; ++i) {
Surface *s = ons + i;
if (s != NULL)
s->render(surface);
@@ -821,7 +824,7 @@ bool Scene::render(bool tickGame, bool tickMark, uint32 messageDelta) {
}
if (visible) {
- _vm->res->font7.render(surface, messagePos.x, messagePos.y, message, messageColor);
+ _vm->res->font7.render(surface, messagePos.x, messagePos.y, message, _messageColor);
busy = true;
}
}
@@ -1005,7 +1008,7 @@ bool Scene::processEventQueue() {
warning("no animation in slot %u", messageSlot);
}
messagePos = messagePosition(message, p);
- messageColor = currentEvent.color;
+ _messageColor = currentEvent.color;
if (messageFirstFrame)
currentEvent.clear(); // async message, clearing event
@@ -1153,7 +1156,7 @@ bool Scene::processEventQueue() {
}
if (events.empty()) {
- messageColor = textColorMark;
+ _messageColor = textColorMark;
hideActor = false;
}
@@ -1232,7 +1235,7 @@ void Scene::displayMessage(const Common::String &str, byte color, const Common::
debugC(0, kDebugScene, "displayMessage: %s", str.c_str());
message = str;
messagePos = (pos.x | pos.y) ? pos : messagePosition(str, position);
- messageColor = color;
+ _messageColor = color;
messageTimer = messageDuration(message);
}
@@ -1251,7 +1254,7 @@ void Scene::clear() {
void Scene::clearMessage() {
message.clear();
messageTimer = 0;
- messageColor = textColorMark;
+ _messageColor = textColorMark;
messageFirstFrame = 0;
messageLastFrame = 0;
messageAnimation = NULL;
diff --git a/engines/teenagent/scene.h b/engines/teenagent/scene.h
index 07b304ed97..40f910a3aa 100644
--- a/engines/teenagent/scene.h
+++ b/engines/teenagent/scene.h
@@ -194,7 +194,7 @@ private:
SurfaceList on;
bool onEnabled;
Surface *ons;
- uint32 onsCount;
+ uint32 _onsCount;
Animation actorAnimation, animation[4], customAnimation[4];
Common::Rect actorAnimationPosition, animationPosition[4];
@@ -214,7 +214,7 @@ private:
Common::String message;
Common::Point messagePos;
- byte messageColor;
+ byte _messageColor;
uint messageTimer;
byte messageFirstFrame;
byte messageLastFrame;
diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp
index 4dc785754c..2d10b82f51 100644
--- a/engines/teenagent/teenagent.cpp
+++ b/engines/teenagent/teenagent.cpp
@@ -71,6 +71,13 @@ TeenAgentEngine::TeenAgentEngine(OSystem *system, const ADGameDescription *gd)
res = new Resources();
console = 0;
+ scene = 0;
+ inventory = 0;
+ _sceneBusy = false;
+ _dstObject = 0;
+ _musicStream = 0;
+ _markDelay = 0;
+ _gameDelay = 0;
}
TeenAgentEngine::~TeenAgentEngine() {
diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp
index 22c3798fc6..cfe97e6ec1 100644
--- a/engines/tinsel/bmv.cpp
+++ b/engines/tinsel/bmv.cpp
@@ -567,8 +567,8 @@ void BMVPlayer::PlayBMV(CORO_PARAM, SCNHANDLE hFileStem, int myEscape) {
assert(!bMovieOn);
- strcpy(szMovieFile, (char *)LockMem(hFileStem));
- strcat(szMovieFile, BMOVIE_EXTENSION);
+ Common::strlcpy(szMovieFile, (char *)LockMem(hFileStem), 14);
+ Common::strlcat(szMovieFile, BMOVIE_EXTENSION, 14);
assert(strlen(szMovieFile) <= 12);
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index 2fde6e788a..c44f1f4ef3 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -235,7 +235,7 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const FileMap &allFile
for (fileDesc = g->desc.filesDescriptions; fileDesc->fileName; fileDesc++) {
// Get the next filename, stripping off any '1' suffix character
char tempFilename[50];
- strcpy(tempFilename, fileDesc->fileName);
+ Common::strlcpy(tempFilename, fileDesc->fileName, 50);
char *pOne = strchr(tempFilename, '1');
if (pOne) {
do {
@@ -275,7 +275,7 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const FileMap &allFile
for (fileDesc = g->desc.filesDescriptions; fileDesc->fileName; fileDesc++) {
// Get the next filename, stripping off any '1' suffix character
char tempFilename[50];
- strcpy(tempFilename, fileDesc->fileName);
+ Common::strlcpy(tempFilename, fileDesc->fileName, 50);
char *pOne = strchr(tempFilename, '1');
if (pOne) {
do {
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index a84dad942c..ad20253b9c 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -1671,10 +1671,10 @@ static void Select(int i, bool force) {
#else
// Current description with cursor appended
if (cd.box[i].boxText != NULL) {
- strcpy(g_sedit, cd.box[i].boxText);
- strcat(g_sedit, sCursor);
+ Common::strlcpy(g_sedit, cd.box[i].boxText, SG_DESC_LEN+2);
+ Common::strlcat(g_sedit, sCursor, SG_DESC_LEN+2);
} else {
- strcpy(g_sedit, sCursor);
+ Common::strlcpy(g_sedit, sCursor, SG_DESC_LEN+2);
}
#endif
@@ -3676,13 +3676,13 @@ extern void HideConversation(bool bHide) {
ConstructInventory(FULL);
else {
// Move it all back on-screen
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiAdjustXY(g_objArray[i], -2 * SCREEN_WIDTH, 0);
}
// Don't flash if items changed. If they have, will be redrawn anyway.
if (TinselV2 || !g_ItemsChanged) {
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiAdjustXY(g_iconArray[i], -2*SCREEN_WIDTH, 0);
}
}
@@ -3739,10 +3739,10 @@ extern void HideConversation(bool bHide) {
deltay = g_InvD[INV_CONV].inventoryY - deltay;
// Move it all
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiMoveRelXY(g_objArray[i], x - center, deltay);
}
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiMoveRelXY(g_iconArray[i], x - center, deltay);
}
g_InvD[INV_CONV].inventoryX += x - center;
@@ -3771,10 +3771,10 @@ extern void HideConversation(bool bHide) {
y = 0;
if (x || y) {
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiMoveRelXY(g_objArray[i], x, y);
}
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiMoveRelXY(g_iconArray[i], x, y);
}
g_InvD[INV_CONV].inventoryX += x;
@@ -3786,10 +3786,10 @@ extern void HideConversation(bool bHide) {
*/
if (MultiLowest(g_RectObject) > SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) {
y = (SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) - MultiLowest(g_RectObject);
- for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ for (i = 0; i < MAX_WCOMP && g_objArray[i]; i++) {
MultiMoveRelXY(g_objArray[i], 0, y);
}
- for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ for (i = 0; i < MAX_ICONS && g_iconArray[i]; i++) {
MultiMoveRelXY(g_iconArray[i], 0, y);
}
g_InvD[INV_CONV].inventoryY += y;
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 62d244e449..9ffd477c4a 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -258,7 +258,7 @@ void LoadExtraGraphData(SCNHANDLE start, SCNHANDLE next) {
}
void SetCdPlaySceneDetails(int fileNum, const char *fileName) {
- strcpy(g_szCdPlayFile, fileName);
+ Common::strlcpy(g_szCdPlayFile, fileName, 100);
}
void SetCdPlayHandle(int fileNum) {
diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp
index 88cd80b78a..226cbb51c0 100644
--- a/engines/tinsel/saveload.cpp
+++ b/engines/tinsel/saveload.cpp
@@ -563,7 +563,7 @@ static void DoSave() {
while (1) {
Common::String fname = _vm->getSavegameFilename(ano);
- strcpy(tmpName, fname.c_str());
+ Common::strlcpy(tmpName, fname.c_str(), FNAMELEN);
for (i = 0; i < g_numSfiles; i++)
if (!strcmp(g_savedFiles[i].name, tmpName))
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index b64903ec6d..b26408fadc 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -45,7 +45,7 @@ enum ChunkTypes {
kChunkStopSubtitles = 8
};
-MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm), _isPlaying(false), _lastPrefetchOfs(0), _framesPerSoundChunk(0), _endPos(0) {
+MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm), _isPlaying(false), _lastPrefetchOfs(0), _framesPerSoundChunk(0), _endPos(0), _audioStream(0) {
}
MoviePlayer::~MoviePlayer() {
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index 468ae0272f..6dbb9c2843 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -31,6 +31,7 @@ namespace Toltecs {
/* ArchiveReader */
ArchiveReader::ArchiveReader() {
+ _offsets = 0;
}
ArchiveReader::~ArchiveReader() {
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index f29f64dcfe..be4be5d9e3 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -84,6 +84,7 @@ public:
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
_scalerStatus = 0;
+ _xerror = 0;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
SpriteReaderStatus status = kSrsPixelsLeft;
@@ -135,6 +136,8 @@ public:
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
_scalerStatus = 0;
+ _sourcep = 0;
+ _xerror = 0;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
SpriteReaderStatus status;
diff --git a/engines/tony/gfxcore.cpp b/engines/tony/gfxcore.cpp
index 2a32926c53..27145d7c4b 100644
--- a/engines/tony/gfxcore.cpp
+++ b/engines/tony/gfxcore.cpp
@@ -1733,13 +1733,6 @@ void RMGfxSourceBuffer8AA::drawAA(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *pri
g /= 5;
b /= 5;
- if (r > 0x1f)
- r = 0x1f;
- if (g > 0x3f)
- g = 0x3f;
- if (b > 0x1f)
- b = 0x1f;
-
mybuf[0] = (r << 11) | (g << 5) | b;
}
}
@@ -1774,13 +1767,6 @@ void RMGfxSourceBuffer8AA::drawAA(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *pri
g /= 6;
b /= 6;
- if (r > 0x1f)
- r = 0x1f;
- if (g > 0x3f)
- g = 0x3f;
- if (b > 0x1f)
- b = 0x1f;
-
mybuf[0] = (r << 11) | (g << 5) | b;
}
}
diff --git a/engines/tony/mpal/loadmpc.cpp b/engines/tony/mpal/loadmpc.cpp
index 8d030f1e52..01892a40e6 100644
--- a/engines/tony/mpal/loadmpc.cpp
+++ b/engines/tony/mpal/loadmpc.cpp
@@ -331,7 +331,7 @@ static const byte *parseItem(const byte *lpBuf, LpMpalItem lpmiItem) {
byte len = *lpBuf;
lpBuf++;
- memcpy(lpmiItem->_lpszDescribe, lpBuf, MIN((byte)127, len));
+ memcpy(lpmiItem->_lpszDescribe, lpBuf, MIN((byte)MAX_DESCRIBE_SIZE, len));
lpBuf += len;
if (len >= MAX_DESCRIBE_SIZE)
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 89cc28130d..9172843781 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -367,12 +367,18 @@ MpalHandle resLoad(uint32 dwId) {
temp = (byte *)globalAlloc(GMEM_FIXED | GMEM_ZEROINIT, nSizeComp);
nBytesRead = GLOBALS._hMpr.read(temp, nSizeComp);
- if (nBytesRead != nSizeComp)
+ if (nBytesRead != nSizeComp) {
+ globalDestroy(temp);
+ globalDestroy(h);
return NULL;
+ }
lzo1x_decompress(temp, nSizeComp, buf, &nBytesRead);
- if (nBytesRead != nSizeDecomp)
+ if (nBytesRead != nSizeDecomp) {
+ globalDestroy(temp);
+ globalDestroy(h);
return NULL;
+ }
globalDestroy(temp);
globalUnlock(h);
@@ -526,8 +532,10 @@ static LpItem getItemData(uint32 nOrdItem) {
globalFree(hDat);
// Check if we've got to the end of the file
- if (i != 0xABCD)
+ if (i != 0xABCD) {
+ globalDestroy(ret);
return NULL;
+ }
return ret;
}
@@ -1413,36 +1421,51 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
if (bCompress) {
// Get the compressed size and read the data in
uint32 dwSizeComp = hMpc.readUint32LE();
- if (hMpc.err())
+ if (hMpc.err()) {
+ globalDestroy(lpMpcImage);
return false;
+ }
cmpbuf = (byte *)globalAlloc(GMEM_FIXED, dwSizeComp);
- if (cmpbuf == NULL)
+ if (cmpbuf == NULL) {
+ globalDestroy(lpMpcImage);
return false;
+ }
nBytesRead = hMpc.read(cmpbuf, dwSizeComp);
- if (nBytesRead != dwSizeComp)
+ if (nBytesRead != dwSizeComp) {
+ globalDestroy(cmpbuf);
+ globalDestroy(lpMpcImage);
return false;
+ }
// Decompress the data
lzo1x_decompress(cmpbuf, dwSizeComp, lpMpcImage, &nBytesRead);
- if (nBytesRead != dwSizeDecomp)
+ if (nBytesRead != dwSizeDecomp) {
+ globalDestroy(cmpbuf);
+ globalDestroy(lpMpcImage);
return false;
+ }
globalDestroy(cmpbuf);
} else {
// If the file is not compressed, we directly read in the data
nBytesRead = hMpc.read(lpMpcImage, dwSizeDecomp);
- if (nBytesRead != dwSizeDecomp)
+ if (nBytesRead != dwSizeDecomp) {
+ globalDestroy(lpMpcImage);
return false;
+ }
}
// Close the file
hMpc.close();
// Process the data
- if (parseMpc(lpMpcImage) == false)
+ if (parseMpc(lpMpcImage) == false) {
+ globalDestroy(lpMpcImage);
+
return false;
+ }
globalDestroy(lpMpcImage);
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
index bd8a0cdd0d..6b44ecc514 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -1440,7 +1440,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
case 2425:
_sceneMode = 10;
R2_GLOBALS._player.setPosition(Common::Point(280, 150));
- _action->signal();
+ signal();
break;
case 2455:
_sceneMode = 2428;
diff --git a/engines/wage/macmenu.cpp b/engines/wage/macmenu.cpp
index a97e442c83..ed5f5070ff 100644
--- a/engines/wage/macmenu.cpp
+++ b/engines/wage/macmenu.cpp
@@ -104,6 +104,9 @@ Menu::Menu(int id, const Common::Rect &bounds, MacWindowManager *wm)
_activeItem = -1;
_activeSubItem = -1;
+ _ccallback = NULL;
+ _cdata = NULL;
+
_tempSurface.create(_screen.w, _font->getFontHeight(), Graphics::PixelFormat::createFormatCLUT8());
}
diff --git a/engines/wage/macwindow.cpp b/engines/wage/macwindow.cpp
index 7ff0f57ccb..8903936061 100644
--- a/engines/wage/macwindow.cpp
+++ b/engines/wage/macwindow.cpp
@@ -76,6 +76,8 @@ MacWindow::MacWindow(int id, bool scrollable, bool resizable, bool editable, Mac
_beingDragged = false;
_beingResized = false;
+ _draggedX = _draggedY = 0;
+
_type = kWindowWindow;
}
diff --git a/engines/wintermute/base/base_engine.cpp b/engines/wintermute/base/base_engine.cpp
index 2166a3e070..4ce334aceb 100644
--- a/engines/wintermute/base/base_engine.cpp
+++ b/engines/wintermute/base/base_engine.cpp
@@ -84,7 +84,7 @@ void BaseEngine::LOG(bool res, const char *fmt, ...) {
va_end(va);
if (instance()._gameRef) {
- instance()._gameRef->LOG("%s", buff);
+ instance()._gameRef->LOG(res, "%s", buff);
} else {
debugCN(kWintermuteDebugLog, "%02d:%02d:%02d: %s\n", hours, mins, secs, buff);
}
diff --git a/gui/widgets/popup.cpp b/gui/widgets/popup.cpp
index b10b4fb5fe..0b2ea9fd4e 100644
--- a/gui/widgets/popup.cpp
+++ b/gui/widgets/popup.cpp
@@ -388,6 +388,8 @@ PopUpWidget::PopUpWidget(GuiObject *boss, int x, int y, int w, int h, const char
_type = kPopUpWidget;
_selectedItem = -1;
+
+ _leftPadding = _rightPadding = 0;
}
void PopUpWidget::handleMouseDown(int x, int y, int button, int clickCount) {
diff --git a/po/de_DE.po b/po/de_DE.po
index 2943f18bfa..65765ecca0 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.9.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2016-04-07 08:55+0100\n"
-"PO-Revision-Date: 2016-04-15 11:00+0100\n"
+"POT-Creation-Date: 2016-04-07 08:55+0200\n"
+"PO-Revision-Date: 2016-05-01 15:45+0200\n"
"Last-Translator: Lothar Serra Mari <rootfather@scummvm.org>\n"
"Language-Team: Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari "
"<rootfather@scummvm.org>\n"
@@ -978,7 +978,7 @@ msgstr "Musiklautstärke:"
#: gui/options.cpp:970
msgid "Mute All"
-msgstr "Alles aus"
+msgstr "Stumm"
#: gui/options.cpp:973
msgid "SFX volume:"