aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorNorbert Lange2009-08-11 22:35:56 +0000
committerNorbert Lange2009-08-11 22:35:56 +0000
commit0836cf6d9b9222255273a9c6f9d91203b13c3bd9 (patch)
tree714c59161aaf7dbc36d7cb6b4e8fcaa9c467e8f9 /engines
parent8cb42dd6896925106282abd23ce23812d6031989 (diff)
parent65e9ae163ff757ca15af78da4a753a7ee1d25a16 (diff)
downloadscummvm-rg350-0836cf6d9b9222255273a9c6f9d91203b13c3bd9.tar.gz
scummvm-rg350-0836cf6d9b9222255273a9c6f9d91203b13c3bd9.tar.bz2
scummvm-rg350-0836cf6d9b9222255273a9c6f9d91203b13c3bd9.zip
merged from trunk (Amiga LoK supposedly completeable!)
fixed a bug I introduced in one of the last cleanups svn-id: r43291
Diffstat (limited to 'engines')
-rw-r--r--engines/agos/agos.cpp4
-rw-r--r--engines/agos/agos.h22
-rw-r--r--engines/agos/animation.cpp1
-rw-r--r--engines/agos/animation.h3
-rw-r--r--engines/agos/charset.cpp4
-rw-r--r--engines/agos/cursor.cpp75
-rw-r--r--engines/agos/debug.cpp4
-rw-r--r--engines/agos/detection.cpp6
-rw-r--r--engines/agos/detection_tables.h16
-rw-r--r--engines/agos/draw.cpp2
-rw-r--r--engines/agos/event.cpp4
-rw-r--r--engines/agos/gfx.cpp2
-rw-r--r--engines/agos/icons.cpp29
-rw-r--r--engines/agos/module.mk26
-rw-r--r--engines/agos/res.cpp18
-rw-r--r--engines/agos/rooms.cpp2
-rw-r--r--engines/agos/saveload.cpp7
-rw-r--r--engines/agos/string.cpp4
-rw-r--r--engines/agos/subroutine.cpp2
-rw-r--r--engines/agos/verb.cpp10
-rw-r--r--engines/agos/vga.cpp13
-rw-r--r--engines/agos/vga_e2.cpp2
-rw-r--r--engines/agos/vga_ff.cpp51
-rw-r--r--engines/agos/vga_pn.cpp4
-rw-r--r--engines/agos/vga_s1.cpp85
-rw-r--r--engines/agos/window.cpp2
-rw-r--r--engines/cruise/cruise.cpp12
-rw-r--r--engines/cruise/cruise.h4
-rw-r--r--engines/cruise/staticres.cpp4
-rw-r--r--engines/engines.mk4
-rw-r--r--engines/gob/draw_v2.cpp2
-rw-r--r--engines/gob/game.cpp39
-rw-r--r--engines/gob/game.h10
-rw-r--r--engines/gob/hotspots.cpp5
-rw-r--r--engines/gob/inter_v2.cpp15
-rw-r--r--engines/gob/inter_v4.cpp5
-rw-r--r--engines/gob/inter_v6.cpp5
-rw-r--r--engines/gob/mult_v2.cpp11
-rw-r--r--engines/gob/save/saveload_playtoons.cpp2
-rw-r--r--engines/gob/util.cpp3
-rw-r--r--engines/kyra/gui.cpp26
-rw-r--r--engines/kyra/gui_lok.cpp62
-rw-r--r--engines/kyra/items_lok.cpp67
-rw-r--r--engines/kyra/kyra_lok.cpp5
-rw-r--r--engines/kyra/kyra_lok.h65
-rw-r--r--engines/kyra/lol.cpp7
-rw-r--r--engines/kyra/lol.h4
-rw-r--r--engines/kyra/saveload_lok.cpp27
-rw-r--r--engines/kyra/scene_lok.cpp64
-rw-r--r--engines/kyra/screen.cpp655
-rw-r--r--engines/kyra/screen.h131
-rw-r--r--engines/kyra/screen_lok.cpp19
-rw-r--r--engines/kyra/screen_lok.h3
-rw-r--r--engines/kyra/script_lok.cpp127
-rw-r--r--engines/kyra/seqplayer.cpp3
-rw-r--r--engines/kyra/sequences_lok.cpp269
-rw-r--r--engines/kyra/sound_amiga.cpp4
-rw-r--r--engines/kyra/sprites_lol.cpp29
-rw-r--r--engines/kyra/staticres.cpp27
-rw-r--r--engines/kyra/text.cpp122
-rw-r--r--engines/kyra/text.h6
-rw-r--r--engines/kyra/text_lok.cpp32
-rw-r--r--engines/kyra/wsamovie.cpp13
-rw-r--r--engines/kyra/wsamovie.h1
-rw-r--r--engines/sci/console.cpp27
-rw-r--r--engines/sci/detection.cpp25
-rw-r--r--engines/sci/engine/game.cpp3
-rw-r--r--engines/sci/engine/kernel.cpp2
-rw-r--r--engines/sci/engine/kernel.h7
-rw-r--r--engines/sci/engine/kevent.cpp15
-rw-r--r--engines/sci/engine/kgraphics.cpp7
-rw-r--r--engines/sci/engine/kmisc.cpp2
-rw-r--r--engines/sci/engine/kstring.cpp17
-rw-r--r--engines/sci/engine/message.cpp18
-rw-r--r--engines/sci/engine/scriptdebug.cpp6
-rw-r--r--engines/sci/engine/state.cpp60
-rw-r--r--engines/sci/engine/state.h43
-rw-r--r--engines/sci/engine/vm.cpp6
-rw-r--r--engines/scumm/detection_tables.h1
-rw-r--r--engines/scumm/file_nes.cpp113
-rw-r--r--engines/scumm/file_nes.h1
-rw-r--r--engines/scumm/gfx.cpp10
-rw-r--r--engines/scumm/scumm-md5.h6
-rw-r--r--engines/scumm/sound.cpp8
-rw-r--r--engines/tinsel/tinlib.cpp12
85 files changed, 1953 insertions, 723 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 0e53698b59..a786882630 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -59,6 +59,7 @@ static const GameSpecificSettings puzzlepack_settings = {
"MUSIC", // speech_filename
};
+#ifdef ENABLE_AGOS2
AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system)
: AGOSEngine_Feeble(system) {
@@ -72,6 +73,7 @@ AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system)
_startSecondCount = 0;
_tSecondCount = 0;
}
+#endif
AGOSEngine_Simon2::AGOSEngine_Simon2(OSystem *system)
: AGOSEngine_Simon1(system) {
@@ -696,6 +698,7 @@ static const uint16 initialVideoWindows_PN[20] = {
3, 2, 14, 129,
};
+#ifdef ENABLE_AGOS2
void AGOSEngine_PuzzlePack::setupGame() {
gss = &puzzlepack_settings;
_numVideoOpcodes = 85;
@@ -712,6 +715,7 @@ void AGOSEngine_PuzzlePack::setupGame() {
AGOSEngine::setupGame();
}
+#endif
void AGOSEngine_Simon2::setupGame() {
gss = &simon2_settings;
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index ac1f33428b..a0730deaea 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -34,14 +34,13 @@
#include "common/stack.h"
#include "common/util.h"
+#ifdef ENABLE_AGOS2
#include "agos/animation.h"
+#endif
#include "agos/midi.h"
#include "agos/sound.h"
#include "agos/vga.h"
-// TODO: Replace with more portable code
-#include <setjmp.h>
-
namespace AGOS {
uint fileReadItemID(Common::SeekableReadStream *in);
@@ -892,6 +891,7 @@ public:
void vc19_loop();
void vc20_setRepeat();
void vc21_endRepeat();
+ virtual void vc22_setPalette();
void vc23_setPriority();
void vc24_setSpriteXY();
void vc25_halt_sprite();
@@ -904,7 +904,7 @@ public:
void vc33_setMouseOn();
void vc34_setMouseOff();
void vc35_clearWindow();
- void vc36_setWindowImage();
+ virtual void vc36_setWindowImage();
void vc38_ifVarNotZero();
void vc39_setVar();
void vc40_scrollRight();
@@ -924,7 +924,6 @@ public:
// Video Script Opcodes, Elvira 1
void vc17_waitEnd();
- void vc22_setPaletteOld();
void vc32_saveScreen();
void vc37_pokePalette();
@@ -962,10 +961,9 @@ public:
void vc45_setSpriteX();
void vc46_setSpriteY();
void vc47_addToVar();
- void vc48_setPathFinder();
+ virtual void vc48_setPathFinder();
void vc59_ifSpeech();
void vc61_setMaskImage();
- void vc22_setPaletteNew();
// Video Script Opcodes, Simon 2
void vc56_delayLong();
@@ -1366,9 +1364,6 @@ protected:
int _tagOfActiveDoline; ///< tag of the active doline "instance"
int _dolineReturnVal;
- jmp_buf _loadfail;
-
-
byte *_dataBase, *_textBase;
uint32 _dataBaseSize, _textBaseSize;
@@ -1771,6 +1766,8 @@ public:
virtual void executeOpcode(int opcode);
+ virtual void vc22_setPalette();
+
// Opcodes, Simon 1
void os1_animate();
void os1_pauseGame();
@@ -1875,6 +1872,7 @@ protected:
virtual char *genSaveName(int slot);
};
+#ifdef ENABLE_AGOS2
class AGOSEngine_Feeble : public AGOSEngine_Simon2 {
public:
AGOSEngine_Feeble(OSystem *system);
@@ -1886,6 +1884,9 @@ public:
virtual void executeOpcode(int opcode);
+ virtual void vc36_setWindowImage();
+ virtual void vc48_setPathFinder();
+
void off_chance();
void off_jumpOut();
void off_addTextBox();
@@ -2092,6 +2093,7 @@ protected:
virtual char *genSaveName(int slot);
};
+#endif
} // End of namespace AGOS
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 36399a7b2f..2e7eb9cb5e 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -27,6 +27,7 @@
#include "common/endian.h"
#include "common/events.h"
+#include "common/file.h"
#include "common/system.h"
#include "graphics/cursorman.h"
diff --git a/engines/agos/animation.h b/engines/agos/animation.h
index 4ebcb3d4b3..3ce6aa9ab2 100644
--- a/engines/agos/animation.h
+++ b/engines/agos/animation.h
@@ -26,9 +26,6 @@
#ifndef AGOS_ANIMATION_H
#define AGOS_ANIMATION_H
-#include "common/file.h"
-#include "common/stream.h"
-
#include "graphics/video/dxa_decoder.h"
#include "graphics/video/smk_decoder.h"
#include "sound/mixer.h"
diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp
index 5b0a694312..fb012a89dd 100644
--- a/engines/agos/charset.cpp
+++ b/engines/agos/charset.cpp
@@ -34,6 +34,7 @@
namespace AGOS {
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::doOutput(const byte *src, uint len) {
if (_textWindow == NULL)
return;
@@ -64,6 +65,7 @@ void AGOSEngine_Feeble::doOutput(const byte *src, uint len) {
}
}
}
+#endif
void AGOSEngine::doOutput(const byte *src, uint len) {
uint idx;
@@ -573,6 +575,7 @@ void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) {
}
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) {
if (_noOracleScroll == 0) {
if (window->height < window->textRow + 30) {
@@ -603,6 +606,7 @@ void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) {
window->textColumnOffset = 0;
window->textLength = 0;
}
+#endif
void AGOSEngine::windowNewLine(WindowBlock *window) {
window->textColumn = 0;
diff --git a/engines/agos/cursor.cpp b/engines/agos/cursor.cpp
index c279fbd335..1304ca7ca4 100644
--- a/engines/agos/cursor.cpp
+++ b/engines/agos/cursor.cpp
@@ -348,6 +348,7 @@ static const byte _mouseOffs[29 * 32] = {
0,0,10,7,10,6,10,5,10,4,10,3,10,4,10,5,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
+#ifdef ENABLE_AGOS2
void AGOSEngine_PuzzlePack::handleMouseMoved() {
uint x;
@@ -379,6 +380,7 @@ void AGOSEngine_PuzzlePack::handleMouseMoved() {
drawMousePointer();
}
+#endif
void AGOSEngine_Simon1::handleMouseMoved() {
uint x;
@@ -638,6 +640,7 @@ void AGOSEngine::mouseOn() {
_videoLockOut &= ~1;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_PuzzlePack::initMouse() {
if (getGameId() == GID_DIMP) {
AGOSEngine_Simon1::initMouse();
@@ -652,48 +655,12 @@ void AGOSEngine_FeebleDemo::initMouse() {
// TODO: Add larger cursor
AGOSEngine_Simon1::initMouse();
}
-
-static const byte mouseCursorPalette[] = {
- 0x00, 0x00, 0x00, 0x00, // Black
- 0xFF, 0xFF, 0xFF, 0x00, // White
-};
-
void AGOSEngine_Feeble::initMouse() {
_maxCursorWidth = 40;
_maxCursorHeight = 40;
_mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1);
}
-void AGOSEngine_Simon1::initMouse() {
- AGOSEngine::initMouse();
-
- const uint16 *src = _common_mouseInfo;
- for (int i = 0; i < 16; i++) {
- for (int j = 0; j < 16; j++) {
- if (src[0] & (1 << (15 - (j % 16)))) {
- if (src[1] & (1 << (15 - (j % 16)))) {
- _mouseData[16 * i + j] = 1;
- } else {
- _mouseData[16 * i + j] = 0;
- }
- }
- }
- src += 2;
- }
-
- CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF);
-}
-
-void AGOSEngine::initMouse() {
- _maxCursorWidth = 16;
- _maxCursorHeight = 16;
- _mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1);
-
- memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight);
-
- CursorMan.replaceCursorPalette(mouseCursorPalette, 0, ARRAYSIZE(mouseCursorPalette) / 4);
-}
-
void AGOSEngine_PuzzlePack::loadMouseImage() {
loadZone(_variableArray[500]);
VgaPointersEntry *vpe = &_vgaBufferPointers[_variableArray[500]];
@@ -793,6 +760,42 @@ void AGOSEngine_Feeble::drawMousePointer() {
CursorMan.replaceCursor(_mouseData, _maxCursorWidth, _maxCursorHeight, hotspotX, hotspotY, 0);
}
}
+#endif
+
+void AGOSEngine_Simon1::initMouse() {
+ AGOSEngine::initMouse();
+
+ const uint16 *src = _common_mouseInfo;
+ for (int i = 0; i < 16; i++) {
+ for (int j = 0; j < 16; j++) {
+ if (src[0] & (1 << (15 - (j % 16)))) {
+ if (src[1] & (1 << (15 - (j % 16)))) {
+ _mouseData[16 * i + j] = 1;
+ } else {
+ _mouseData[16 * i + j] = 0;
+ }
+ }
+ }
+ src += 2;
+ }
+
+ CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF);
+}
+
+static const byte mouseCursorPalette[] = {
+ 0x00, 0x00, 0x00, 0x00, // Black
+ 0xFF, 0xFF, 0xFF, 0x00, // White
+};
+
+void AGOSEngine::initMouse() {
+ _maxCursorWidth = 16;
+ _maxCursorHeight = 16;
+ _mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1);
+
+ memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight);
+
+ CursorMan.replaceCursorPalette(mouseCursorPalette, 0, ARRAYSIZE(mouseCursorPalette) / 4);
+}
void AGOSEngine::drawMousePointer() {
if (getGameType() == GType_SIMON2) {
diff --git a/engines/agos/debug.cpp b/engines/agos/debug.cpp
index 8bdb35d3ae..519dfc344c 100644
--- a/engines/agos/debug.cpp
+++ b/engines/agos/debug.cpp
@@ -26,6 +26,8 @@
// AGOS debug functions
+#include "common/file.h"
+
#include "agos/debug.h"
#include "agos/agos.h"
#include "agos/intern.h"
@@ -323,6 +325,7 @@ void AGOSEngine::dumpAllVgaScriptFiles() {
}
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::dumpVgaFile(const byte *vga) {
const byte *pp;
const byte *p;
@@ -352,6 +355,7 @@ void AGOSEngine_Feeble::dumpVgaFile(const byte *vga) {
p += sizeof(ImageHeader_Feeble);
}
}
+#endif
void AGOSEngine_Simon1::dumpVgaFile(const byte *vga) {
const byte *pp;
diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp
index 7877e19646..a7b5b91602 100644
--- a/engines/agos/detection.cpp
+++ b/engines/agos/detection.cpp
@@ -66,17 +66,21 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
};
static const PlainGameDescriptor simonGames[] = {
+#ifdef ENABLE_PN
{"pn", "Personal Nightmare"},
+#endif
{"elvira1", "Elvira - Mistress of the Dark"},
{"elvira2", "Elvira II - The Jaws of Cerberus"},
{"waxworks", "Waxworks"},
{"simon1", "Simon the Sorcerer 1"},
{"simon2", "Simon the Sorcerer 2"},
+#ifdef ENABLE_AGOS2
{"feeble", "The Feeble Files"},
{"dimp", "Demon in my Pocket"},
{"jumble", "Jumble"},
{"puzzle", "NoPatience"},
{"swampy", "Swampy Adventures"},
+#endif
{0, 0}
};
@@ -158,6 +162,7 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
case AGOS::GType_SIMON2:
*engine = new AGOS::AGOSEngine_Simon2(syst);
break;
+#ifdef ENABLE_AGOS2
case AGOS::GType_FF:
if (gd->features & GF_DEMO)
*engine = new AGOS::AGOSEngine_FeebleDemo(syst);
@@ -167,6 +172,7 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
case AGOS::GType_PP:
*engine = new AGOS::AGOSEngine_PuzzlePack(syst);
break;
+#endif
default:
res = false;
error("AGOS engine: unknown gameType");
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index 0c672aef52..2a6cf4f752 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -32,6 +32,7 @@ using Common::GUIO_NOSPEECH;
using Common::GUIO_NOSUBTITLES;
static const AGOSGameDescription gameDescriptions[] = {
+#ifdef ENABLE_PN
// Personal Nightmare 1.1 - English Amiga
{
{
@@ -123,6 +124,7 @@ static const AGOSGameDescription gameDescriptions[] = {
GID_PN,
GF_OLD_BUNDLE | GF_CRUNCHED | GF_EGA | GF_PLANAR
},
+#endif
// Elvira 1 - English Amiga Floppy Demo
{
@@ -1600,7 +1602,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1625,7 +1627,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1675,7 +1677,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::HB_ISR,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1700,7 +1702,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1726,7 +1728,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1751,7 +1753,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -2335,6 +2337,7 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_TALKIE
},
+#ifdef ENABLE_AGOS2
// The Feeble Files - English DOS Demo
{
{
@@ -2807,6 +2810,7 @@ static const AGOSGameDescription gameDescriptions[] = {
GID_SWAMPY,
GF_OLD_BUNDLE | GF_TALKIE
},
+#endif
{ AD_TABLE_END_MARKER, 0, 0, 0 }
};
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index 368da5db83..35023885cc 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -46,6 +46,7 @@ byte *AGOSEngine::getScaleBuf() {
return (byte *)_scaleBuf->pixels;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::animateSpritesByY() {
VgaSprite *vsp;
VgaPointersEntry *vpe;
@@ -147,6 +148,7 @@ void AGOSEngine_Feeble::animateSprites() {
_displayScreen = true;
}
+#endif
void AGOSEngine::animateSprites() {
VgaSprite *vsp;
diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp
index cbb09e1ec7..0c7c1feb51 100644
--- a/engines/agos/event.cpp
+++ b/engines/agos/event.cpp
@@ -552,6 +552,7 @@ void AGOSEngine::delay(uint amount) {
} while (cur < start + amount && !shouldQuit());
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_PuzzlePack::timerProc() {
_lastTickCount = _system->getMillis();
@@ -609,6 +610,7 @@ void AGOSEngine_Feeble::timerProc() {
_videoLockOut &= ~2;
}
+#endif
#ifdef ENABLE_PN
void AGOSEngine_PN::timerProc() {
@@ -677,6 +679,7 @@ void AGOSEngine::timerProc() {
_videoLockOut &= ~2;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_PuzzlePack::dimpIdle() {
int z, n;
@@ -758,5 +761,6 @@ void AGOSEngine_PuzzlePack::dimpIdle() {
}
}
}
+#endif
} // End of namespace AGOS
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 1b5a820260..a7bd1895c5 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -226,6 +226,7 @@ bool AGOSEngine::drawImage_clip(VC10_state *state) {
return (state->draw_width != 0 && state->draw_height != 0);
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
Common::Rect srcRect, dstRect;
float factor, xscale;
@@ -461,6 +462,7 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) {
} while (--state->draw_height);
}
}
+#endif
void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) {
if (getGameType() == GType_SIMON1 && (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10)) {
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
index 2fd93e64f2..cb37cf3841 100644
--- a/engines/agos/icons.cpp
+++ b/engines/agos/icons.cpp
@@ -374,6 +374,7 @@ void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) {
_videoLockOut &= ~0x8000;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::drawIconArray(uint num, Item *itemRef, int line, int classMask) {
Item *item_ptr_org = itemRef;
WindowBlock *window;
@@ -477,6 +478,7 @@ l1:; itemRef = derefItem(itemRef->next);
window->iconPtr->upArrow = _scrollUpHitArea;
window->iconPtr->downArrow = _scrollDownHitArea;
}
+#endif
void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) {
Item *item_ptr_org = itemRef;
@@ -581,6 +583,7 @@ void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask)
}
}
+#ifdef ENABLE_AGOS2
uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *itemPtr) {
HitArea *ha = findEmptyHitArea();
@@ -596,6 +599,7 @@ uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x,
return ha - _hitAreas;
}
+#endif
uint AGOSEngine_Simon2::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *itemPtr) {
HitArea *ha = findEmptyHitArea();
@@ -683,6 +687,7 @@ uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y,
return ha - _hitAreas;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
@@ -712,6 +717,7 @@ void AGOSEngine_Feeble::addArrows(WindowBlock *window, uint8 num) {
ha->window = window;
ha->verb = 1;
}
+#endif
void AGOSEngine_Simon2::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
@@ -860,16 +866,16 @@ void AGOSEngine::addArrows(WindowBlock *window, uint8 num) {
x = 30;
y = 151;
if (num != 2) {
- y = window->height * 4 + window->y - 19;
- x = window->width + window->x;
+ y = window->y + window->height * 4 - 19;
+ x = window->x + window->width;
}
drawArrow(x, y, 16);
ha = findEmptyHitArea();
_scrollUpHitArea = ha - _hitAreas;
- ha->x = 30 * 8;
- ha->y = 151;
+ ha->x = x * 8;
+ ha->y = y;
ha->width = 16;
ha->height = 19;
ha->flags = kBFBoxInUse;
@@ -881,16 +887,16 @@ void AGOSEngine::addArrows(WindowBlock *window, uint8 num) {
x = 30;
y = 170;
if (num != 2) {
- y = window->height * 4;
- x = window->width + window->x;
+ y = window->y + window->height * 4;
+ x = window->x + window->width;
}
drawArrow(x, y, -16);
ha = findEmptyHitArea();
_scrollDownHitArea = ha - _hitAreas;
- ha->x = 30 * 8;
- ha->y = 170;
+ ha->x = x * 8;
+ ha->y = y;
ha->width = 16;
ha->height = 19;
ha->flags = kBFBoxInUse;
@@ -956,7 +962,8 @@ void AGOSEngine::drawArrow(uint16 x, uint16 y, int8 dir) {
for (h = 0; h < 19; h++) {
for (w = 0; w < 16; w++) {
- dst[w] = src[w] + 16;
+ if (src[w])
+ dst[w] = src[w] + 16;
}
src += dir;
@@ -984,8 +991,8 @@ void AGOSEngine_Elvira2::removeArrows(WindowBlock *window, uint num) {
void AGOSEngine::removeArrows(WindowBlock *window, uint num) {
if (num != 2) {
- uint y = window->height * 4 + window->y - 19;
- uint x = window->width + window->x;
+ uint y = window->y + window->height * 4 - 19;
+ uint x = (window->x + window->width) * 8;
restoreBlock(x, y, x + 16, y + 38);
} else {
colorBlock(window, 240, 151, 16, 38);
diff --git a/engines/agos/module.mk b/engines/agos/module.mk
index a7042fa2ad..41305620f8 100644
--- a/engines/agos/module.mk
+++ b/engines/agos/module.mk
@@ -2,7 +2,6 @@ MODULE := engines/agos
MODULE_OBJS := \
agos.o \
- animation.o \
charset.o \
charset-fontdata.o \
contain.o \
@@ -12,7 +11,6 @@ MODULE_OBJS := \
detection.o \
draw.o \
event.o \
- feeble.o \
gfx.o \
icons.o \
input.o \
@@ -20,8 +18,6 @@ MODULE_OBJS := \
menus.o \
midi.o \
midiparser_s1d.o \
- oracle.o \
- pn.o \
res.o \
res_ami.o \
res_snd.o \
@@ -30,26 +26,38 @@ MODULE_OBJS := \
script.o \
script_e1.o \
script_e2.o \
- script_pn.o \
script_ww.o \
script_s1.o \
script_s2.o \
- script_ff.o \
- script_pp.o \
sound.o \
string.o \
subroutine.o \
verb.o \
vga.o \
vga_e2.o \
- vga_pn.o \
vga_ww.o \
vga_s1.o \
vga_s2.o \
- vga_ff.o \
window.o \
zones.o
+ifdef ENABLE_PN
+MODULE_OBJS += \
+ pn.o \
+ script_pn.o \
+ vga_pn.o
+endif
+
+ifdef ENABLE_AGOS2
+MODULE_OBJS += \
+ animation.o \
+ feeble.o \
+ oracle.o \
+ script_ff.o \
+ script_pp.o \
+ vga_ff.o
+endif
+
# This module can be built as a plugin
ifeq ($(ENABLE_AGOS), DYNAMIC_PLUGIN)
PLUGIN := 1
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index 4278ed11e6..e7e9920ced 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -39,25 +39,27 @@ using Common::File;
namespace AGOS {
+#ifdef ENABLE_AGOS2
uint16 AGOSEngine_Feeble::to16Wrapper(uint value) {
return TO_LE_16(value);
}
-uint16 AGOSEngine::to16Wrapper(uint value) {
- return TO_BE_16(value);
-}
-
uint16 AGOSEngine_Feeble::readUint16Wrapper(const void *src) {
return READ_LE_UINT16(src);
}
-uint16 AGOSEngine::readUint16Wrapper(const void *src) {
- return READ_BE_UINT16(src);
-}
-
uint32 AGOSEngine_Feeble::readUint32Wrapper(const void *src) {
return READ_LE_UINT32(src);
}
+#endif
+
+uint16 AGOSEngine::to16Wrapper(uint value) {
+ return TO_BE_16(value);
+}
+
+uint16 AGOSEngine::readUint16Wrapper(const void *src) {
+ return READ_BE_UINT16(src);
+}
uint32 AGOSEngine::readUint32Wrapper(const void *src) {
return READ_BE_UINT32(src);
diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp
index e3052e7d2f..d5146ae408 100644
--- a/engines/agos/rooms.cpp
+++ b/engines/agos/rooms.cpp
@@ -25,6 +25,8 @@
+#include "common/file.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 3787617be7..0d31c0353d 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -23,6 +23,7 @@
*
*/
+#include "common/file.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -72,6 +73,7 @@ int AGOSEngine::countSaveGames() {
return i;
}
+#ifdef ENABLE_AGOS2
char *AGOSEngine_PuzzlePack::genSaveName(int slot) {
static char buf[20];
@@ -88,6 +90,7 @@ char *AGOSEngine_Feeble::genSaveName(int slot) {
sprintf(buf, "feeble.%.3d", slot);
return buf;
}
+#endif
char *AGOSEngine_Simon2::genSaveName(int slot) {
static char buf[20];
@@ -283,7 +286,7 @@ void AGOSEngine::userGame(bool load) {
const char *message1;
int i = 0, numSaveGames;
char *name;
- char buf[8];
+ char buf[10];
numSaveGames = countSaveGames();
@@ -312,7 +315,7 @@ restart:
for (; *message1; message1++)
windowPutChar(window, *message1);
- memset(buf, 0, 8);
+ memset(buf, 0, 10);
name = buf;
_saveGameNameLen = 0;
diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index 3773b1fa10..6fa0b5d97f 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -25,6 +25,8 @@
+#include "common/file.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
@@ -560,6 +562,7 @@ void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *strin
}
}
+#ifdef ENABLE_AGOS2
// The Feeble Files specific
void AGOSEngine_Feeble::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) {
char convertedString[320];
@@ -693,6 +696,7 @@ void AGOSEngine_Feeble::sendInteractText(uint16 num, const char *fmt, ...) {
printInteractText(num, string);
}
+#endif
// Waxworks specific
uint16 AGOSEngine_Waxworks::getBoxSize() {
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index 70ad3404f5..a4aa81a171 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -25,6 +25,8 @@
+#include "common/file.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp
index 8376ebb28e..8e425e0b64 100644
--- a/engines/agos/verb.cpp
+++ b/engines/agos/verb.cpp
@@ -203,6 +203,7 @@ static const char *const czech_verb_prep_names[] = {
"", "", "", "komu ?"
};
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::clearName() {
stopAnimateSimon2(2, 6);
_lastNameOn = NULL;
@@ -210,6 +211,7 @@ void AGOSEngine_Feeble::clearName() {
_mouseAnim = 1;
return;
}
+#endif
void AGOSEngine_Simon2::clearName() {
if (getBitFlag(79)) {
@@ -530,6 +532,7 @@ void AGOSEngine::defineBox(int id, int x, int y, int width, int height, int flag
_needHitAreaRecalc++;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_PuzzlePack::resetVerbs() {
_verbHitArea = 300;
}
@@ -559,6 +562,7 @@ void AGOSEngine_Feeble::resetVerbs() {
setVerb(NULL);
}
}
+#endif
void AGOSEngine::resetVerbs() {
if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2)
@@ -590,6 +594,7 @@ void AGOSEngine::resetVerbs() {
}
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::setVerb(HitArea *ha) {
int cursor = _mouseCursor;
if (_noRightClick)
@@ -616,6 +621,7 @@ void AGOSEngine_Feeble::setVerb(HitArea *ha) {
_needHitAreaRecalc++;
_verbHitArea = cursor + 300;
}
+#endif
void AGOSEngine::setVerb(HitArea *ha) {
HitArea *tmp = _currentVerbBox;
@@ -654,9 +660,11 @@ void AGOSEngine::setVerb(HitArea *ha) {
_currentVerbBox = ha;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::hitarea_leave(HitArea *ha, bool state) {
invertBox(ha, state);
}
+#endif
void AGOSEngine::hitarea_leave(HitArea *ha, bool state) {
if (getGameType() == GType_SIMON2) {
@@ -917,6 +925,7 @@ void AGOSEngine::displayName(HitArea *ha) {
_lastNameOn = ha;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::invertBox(HitArea *ha, bool state) {
if (getBitFlag(205) || getBitFlag(206)) {
if (state != 0) {
@@ -959,6 +968,7 @@ void AGOSEngine_Feeble::invertBox(HitArea *ha, bool state) {
}
}
}
+#endif
void AGOSEngine::invertBox(HitArea *ha, byte a, byte b, byte c, byte d) {
byte *src, color;
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index d37681508e..1344be6b3a 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -106,7 +106,7 @@ void AGOSEngine_Elvira1::setupVideoOpcodes(VgaOpcodeProc *op) {
op[20] = &AGOSEngine::vc19_loop;
op[21] = &AGOSEngine::vc20_setRepeat;
op[22] = &AGOSEngine::vc21_endRepeat;
- op[23] = &AGOSEngine::vc22_setPaletteOld;
+ op[23] = &AGOSEngine::vc22_setPalette;
op[24] = &AGOSEngine::vc23_setPriority;
op[25] = &AGOSEngine::vc24_setSpriteXY;
op[26] = &AGOSEngine::vc25_halt_sprite;
@@ -918,7 +918,7 @@ static const uint8 iconPalette[64] = {
0x77, 0x55, 0x00,
};
-void AGOSEngine::vc22_setPaletteOld() {
+void AGOSEngine::vc22_setPalette() {
byte *offs, *palptr, *src;
uint16 b, num;
@@ -1258,7 +1258,7 @@ void AGOSEngine::clearVideoWindow(uint16 num, uint16 color) {
dst += screen->pitch;
}
_system->unlockScreen();
- } else if (num == 4) {
+ } else {
const uint16 *vlut = &_videoWindows[num * 4];
uint16 xoffs = (vlut[0] - _videoWindows[16]) * 16;
uint16 yoffs = (vlut[1] - _videoWindows[17]);
@@ -1302,12 +1302,7 @@ void AGOSEngine::vc36_setWindowImage() {
_displayScreen = false;
uint16 vga_res = vcReadNextWord();
uint16 windowNum = vcReadNextWord();
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- fillBackGroundFromFront();
- } else {
- setWindowImage(windowNum, vga_res);
- }
+ setWindowImage(windowNum, vga_res);
}
void AGOSEngine::vc37_pokePalette() {
diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp
index de3cb55963..1bbc7f4849 100644
--- a/engines/agos/vga_e2.cpp
+++ b/engines/agos/vga_e2.cpp
@@ -40,7 +40,7 @@ void AGOSEngine_Elvira2::setupVideoOpcodes(VgaOpcodeProc *op) {
op[17] = &AGOSEngine::vc17_waitEnd;
op[19] = &AGOSEngine::vc19_loop;
- op[22] = &AGOSEngine::vc22_setPaletteOld;
+ op[22] = &AGOSEngine::vc22_setPalette;
op[28] = &AGOSEngine::vc28_playSFX;
op[32] = &AGOSEngine::vc32_saveScreen;
op[37] = &AGOSEngine::vc37_pokePalette;
diff --git a/engines/agos/vga_ff.cpp b/engines/agos/vga_ff.cpp
index 14451a3dbe..694aa3ba28 100644
--- a/engines/agos/vga_ff.cpp
+++ b/engines/agos/vga_ff.cpp
@@ -68,6 +68,57 @@ int AGOSEngine::getScale(int16 y, int16 x) {
}
}
+void AGOSEngine_Feeble::vc36_setWindowImage() {
+ _displayScreen = false;
+ vcReadNextWord();
+ vcReadNextWord();
+ fillBackGroundFromFront();
+}
+
+void AGOSEngine_Feeble::vc48_setPathFinder() {
+ uint16 a = (uint16)_variableArrayPtr[12];
+ const uint16 *p = _pathFindArray[a - 1];
+
+ VgaSprite *vsp = findCurSprite();
+ int16 x, y, ydiff;
+ int16 x1, y1, x2, y2;
+ uint pos = 0;
+
+ x = vsp->x;
+ while (x >= (int16)readUint16Wrapper(p + 2)) {
+ p += 2;
+ pos++;
+ }
+
+ x1 = readUint16Wrapper(p);
+ y1 = readUint16Wrapper(p + 1);
+ x2 = readUint16Wrapper(p + 2);
+ y2 = readUint16Wrapper(p + 3);
+
+ if (x2 != 9999) {
+ ydiff = y2 - y1;
+ if (ydiff < 0) {
+ ydiff = -ydiff;
+ x = vsp->x & 7;
+ ydiff *= x;
+ ydiff /= 8;
+ ydiff = -ydiff;
+ } else {
+ x = vsp->x & 7;
+ ydiff *= x;
+ ydiff /= 8;
+ }
+ y1 += ydiff;
+ }
+
+ y = vsp->y;
+ vsp->y = y1;
+ checkScrollY(y1 - y, y1);
+
+ _variableArrayPtr[11] = x1;
+ _variableArrayPtr[13] = pos;
+}
+
void AGOSEngine::vc75_setScale() {
_baseY = vcReadNextWord();
_scale = vcReadNextWord() / 1000000.0f;
diff --git a/engines/agos/vga_pn.cpp b/engines/agos/vga_pn.cpp
index 12846b08f1..de0b53f2e6 100644
--- a/engines/agos/vga_pn.cpp
+++ b/engines/agos/vga_pn.cpp
@@ -57,7 +57,9 @@ void AGOSEngine_PN::setupVideoOpcodes(VgaOpcodeProc *op) {
op[20] = &AGOSEngine::vc19_loop;
op[21] = &AGOSEngine::vc20_setRepeat;
op[22] = &AGOSEngine::vc21_endRepeat;
- op[23] = &AGOSEngine::vc22_setPaletteOld;
+ // FIXME: This has been "vc22_setPaletteOld" before, but that does not seem to exist.
+ // Please check whether "vc22_setPalette" is fine to be used here.
+ op[23] = &AGOSEngine::vc22_setPalette;
op[24] = &AGOSEngine::vc23_setPriority;
op[25] = &AGOSEngine::vc24_setSpriteXY;
op[26] = &AGOSEngine::vc25_halt_sprite;
diff --git a/engines/agos/vga_s1.cpp b/engines/agos/vga_s1.cpp
index b1ae26437e..bb13d211fe 100644
--- a/engines/agos/vga_s1.cpp
+++ b/engines/agos/vga_s1.cpp
@@ -36,7 +36,7 @@ void AGOSEngine_Simon1::setupVideoOpcodes(VgaOpcodeProc *op) {
op[11] = &AGOSEngine::vc11_clearPathFinder;
op[17] = &AGOSEngine::vc17_setPathfinderItem;
- op[22] = &AGOSEngine::vc22_setPaletteNew;
+ op[22] = &AGOSEngine::vc22_setPalette;
op[32] = &AGOSEngine::vc32_copyVar;
op[37] = &AGOSEngine::vc37_addToSpriteY;
op[48] = &AGOSEngine::vc48_setPathFinder;
@@ -96,7 +96,7 @@ static const uint8 customPalette[96] = {
0xFF, 0xFF, 0x77,
};
-void AGOSEngine::vc22_setPaletteNew() {
+void AGOSEngine_Simon1::vc22_setPalette() {
byte *offs, *palptr = 0, *src;
uint16 a = 0, b, num, palSize = 0;
@@ -186,73 +186,32 @@ void AGOSEngine::vc48_setPathFinder() {
uint16 a = (uint16)_variableArrayPtr[12];
const uint16 *p = _pathFindArray[a - 1];
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- VgaSprite *vsp = findCurSprite();
- int16 x, y, ydiff;
- int16 x1, y1, x2, y2;
- uint pos = 0;
-
- x = vsp->x;
- while (x >= (int16)readUint16Wrapper(p + 2)) {
- p += 2;
- pos++;
- }
-
- x1 = readUint16Wrapper(p);
- y1 = readUint16Wrapper(p + 1);
- x2 = readUint16Wrapper(p + 2);
- y2 = readUint16Wrapper(p + 3);
-
- if (x2 != 9999) {
- ydiff = y2 - y1;
- if (ydiff < 0) {
- ydiff = -ydiff;
- x = vsp->x & 7;
- ydiff *= x;
- ydiff /= 8;
- ydiff = -ydiff;
- } else {
- x = vsp->x & 7;
- ydiff *= x;
- ydiff /= 8;
- }
- y1 += ydiff;
- }
-
- y = vsp->y;
- vsp->y = y1;
- checkScrollY(y1 - y, y1);
-
- _variableArrayPtr[11] = x1;
- _variableArrayPtr[13] = pos;
- } else {
- uint b = (uint16)_variableArray[13];
- p += b * 2 + 1;
- int c = _variableArray[14];
+ uint b = (uint16)_variableArray[13];
+ p += b * 2 + 1;
+ int c = _variableArray[14];
- int step;
- int y1, y2;
- int16 *vp;
+ int step;
+ int y1, y2;
+ int16 *vp;
- step = 2;
- if (c < 0) {
- c = -c;
- step = -2;
- }
+ step = 2;
+ if (c < 0) {
+ c = -c;
+ step = -2;
+ }
- vp = &_variableArray[20];
+ vp = &_variableArray[20];
- do {
- y2 = readUint16Wrapper(p);
- p += step;
- y1 = readUint16Wrapper(p) - y2;
+ do {
+ y2 = readUint16Wrapper(p);
+ p += step;
+ y1 = readUint16Wrapper(p) - y2;
- vp[0] = y1 / 2;
- vp[1] = y1 - (y1 / 2);
+ vp[0] = y1 / 2;
+ vp[1] = y1 - (y1 / 2);
- vp += 2;
- } while (--c);
- }
+ vp += 2;
+ } while (--c);
}
void AGOSEngine::vc59_ifSpeech() {
diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp
index a578568a03..8bf4102067 100644
--- a/engines/agos/window.cpp
+++ b/engines/agos/window.cpp
@@ -122,6 +122,7 @@ void AGOSEngine::clearWindow(WindowBlock *window) {
window->scrollY = 0;
}
+#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::colorWindow(WindowBlock *window) {
byte *dst;
uint16 h, w;
@@ -140,6 +141,7 @@ void AGOSEngine_Feeble::colorWindow(WindowBlock *window) {
_videoLockOut &= ~0x8000;
}
+#endif
void AGOSEngine::colorWindow(WindowBlock *window) {
uint16 y, h;
diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
index 7abf83f054..1286c38ff3 100644
--- a/engines/cruise/cruise.cpp
+++ b/engines/cruise/cruise.cpp
@@ -124,18 +124,6 @@ void CruiseEngine::initialize() {
// another bit of video init
readVolCnf();
-
- // Setup mixer
-// _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
-// _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
-
- int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
- _mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
- _adlib = (midiDriver == MD_ADLIB);
-
- _driver = MidiDriver::createMidi(midiDriver);
- if (_mt32)
- _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
}
void CruiseEngine::deinitialise() {
diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h
index af098b4997..574017dfc7 100644
--- a/engines/cruise/cruise.h
+++ b/engines/cruise/cruise.h
@@ -56,9 +56,7 @@ class CruiseEngine: public Engine {
private:
bool _preLoad;
Debugger *_debugger;
- MidiDriver *_driver;
PCSound *_sound;
- bool _mt32, _adlib;
Common::StringList _langStrings;
CursorType _savedCursor;
uint32 lastTick, lastTickDebug;
@@ -89,8 +87,6 @@ public:
Common::Language getLanguage() const;
Common::Platform getPlatform() const;
PCSound &sound() { return *_sound; }
- bool mt32() const { return _mt32; }
- bool adlib() const { return _adlib; }
virtual GUI::Debugger *getDebugger() { return _debugger; }
virtual void pauseEngine(bool pause);
const char *langString(LangStringId langId) { return _langStrings[(int)langId].c_str(); }
diff --git a/engines/cruise/staticres.cpp b/engines/cruise/staticres.cpp
index 595ac5a38b..fa77555314 100644
--- a/engines/cruise/staticres.cpp
+++ b/engines/cruise/staticres.cpp
@@ -182,7 +182,7 @@ int16 spanish_fontCharacterTable[256] = {
-1, -1, -1,
0x72, 0x80
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0x7f, 0x79, 0x7b, 0x81, 0x82, 0x83,
-1, -1,
0x7d,
@@ -218,7 +218,7 @@ int16 spanish_fontCharacterTable[256] = {
0x67,
-1,
0x68,
- -1, -1, -1, -1
+ -1, -1, -1
};
//
diff --git a/engines/engines.mk b/engines/engines.mk
index 8d7d8de9ff..ff2b7c0a3e 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -24,6 +24,10 @@ MODULES += engines/agos
ifdef ENABLE_PN
DEFINES += -DENABLE_PN
endif
+
+ifdef ENABLE_AGOS2
+DEFINES += -DENABLE_AGOS2
+endif
endif
ifdef ENABLE_CINE
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index a1074d7ecb..486b12b022 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -46,6 +46,8 @@ Draw_v2::Draw_v2(GobEngine *vm) : Draw_v1(vm) {
}
void Draw_v2::initScreen() {
+ _vm->_game->_preventScroll = false;
+
_scrollOffsetX = 0;
_scrollOffsetY = 0;
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index 4e2bd223b7..af9f03ecbf 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -181,10 +181,12 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_handleMouse = 0;
_forceHandleMouse = 0;
- _menuLevel = 0;
_noScroll = true;
_preventScroll = false;
- _scrollHandleMouse = false;
+
+ _wantScroll = false;
+ _wantScrollX = 0;
+ _wantScrollY = 0;
_tempStr[0] = 0;
@@ -360,9 +362,7 @@ void Game::playTot(int16 skipPlay) {
_vm->_scenery->_pCaptureCounter = oldCaptureCounter;
_script->seek(_script->getFunctionOffset(skipPlay + 1));
- _menuLevel++;
_vm->_inter->callSub(2);
- _menuLevel--;
if (_vm->_inter->_terminate != 0)
_vm->_inter->_terminate = 2;
@@ -439,22 +439,27 @@ void Game::freeSoundSlot(int16 slot) {
_vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot));
}
-void Game::evaluateScroll(int16 x, int16 y) {
- if (_preventScroll || !_scrollHandleMouse || (_menuLevel > 0))
+void Game::wantScroll(int16 x, int16 y) {
+ _wantScroll = true;
+ _wantScrollX = x;
+ _wantScrollY = y;
+}
+
+void Game::evaluateScroll() {
+ if (_noScroll || _preventScroll || !_wantScroll)
return;
- if (_noScroll ||
- ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18)))
+ if ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18))
return;
- if ((x == 0) && (_vm->_draw->_scrollOffsetX > 0)) {
+ if ((_wantScrollX == 0) && (_vm->_draw->_scrollOffsetX > 0)) {
uint16 off;
off = MIN(_vm->_draw->_cursorWidth, _vm->_draw->_scrollOffsetX);
off = MAX(off / 2, 1);
_vm->_draw->_scrollOffsetX -= off;
_vm->_video->dirtyRectsAll();
- } else if ((y == 0) && (_vm->_draw->_scrollOffsetY > 0)) {
+ } else if ((_wantScrollY == 0) && (_vm->_draw->_scrollOffsetY > 0)) {
uint16 off;
off = MIN(_vm->_draw->_cursorHeight, _vm->_draw->_scrollOffsetY);
@@ -463,9 +468,9 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_video->dirtyRectsAll();
}
- int16 cursorRight = x + _vm->_draw->_cursorWidth;
- int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width;
- int16 cursorBottom = y + _vm->_draw->_cursorHeight;
+ int16 cursorRight = _wantScrollX + _vm->_draw->_cursorWidth;
+ int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width;
+ int16 cursorBottom = _wantScrollY + _vm->_draw->_cursorHeight;
int16 screenBottom = _vm->_draw->_scrollOffsetY + _vm->_height;
if ((cursorRight >= _vm->_width) &&
@@ -479,7 +484,7 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_draw->_scrollOffsetX += off;
_vm->_video->dirtyRectsAll();
- _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, y);
+ _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, _wantScrollY);
} else if ((cursorBottom >= (_vm->_height - _vm->_video->_splitHeight2)) &&
(screenBottom < _vm->_video->_surfHeight)) {
uint16 off;
@@ -491,11 +496,13 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_draw->_scrollOffsetY += off;
_vm->_video->dirtyRectsAll();
- _vm->_util->setMousePos(x, _vm->_height - _vm->_video->_splitHeight2 -
- _vm->_draw->_cursorHeight);
+ _vm->_util->setMousePos(_wantScrollX,
+ _vm->_height - _vm->_video->_splitHeight2 - _vm->_draw->_cursorHeight);
}
_vm->_util->setScrollOffset();
+
+ _wantScroll = false;
}
int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
diff --git a/engines/gob/game.h b/engines/gob/game.h
index d3a758f014..8b8be90ef4 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -82,7 +82,10 @@ public:
bool _noScroll;
bool _preventScroll;
- bool _scrollHandleMouse;
+
+ bool _wantScroll;
+ int16 _wantScrollX;
+ int16 _wantScrollY;
byte _handleMouse;
char _forceHandleMouse;
@@ -99,7 +102,8 @@ public:
void freeSoundSlot(int16 slot);
- void evaluateScroll(int16 x, int16 y);
+ void wantScroll(int16 x, int16 y);
+ void evaluateScroll();
int16 checkKeys(int16 *pMousex = 0, int16 *pMouseY = 0,
MouseButtons *pButtons = 0, char handleMouse = 0);
@@ -109,8 +113,6 @@ public:
void switchTotSub(int16 index, int16 skipPlay);
protected:
- uint32 _menuLevel;
-
char _tempStr[256];
// Capture
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
index b218634d4e..d21eb906ee 100644
--- a/engines/gob/hotspots.cpp
+++ b/engines/gob/hotspots.cpp
@@ -628,8 +628,6 @@ bool Hotspots::checkHotspotChanged() {
}
uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index) {
- _vm->_game->_scrollHandleMouse = handleMouse != 0;
-
if (delay >= -1) {
_currentKey = 0;
_currentId = 0;
@@ -679,6 +677,9 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index
_vm->_video->waitRetrace();
}
+ if (handleMouse)
+ _vm->_game->evaluateScroll();
+
// Update keyboard and mouse state
key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX,
&_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, handleMouse);
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 19cac86465..b4e5bf7623 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -935,6 +935,8 @@ void Inter_v2::o2_setScrollOffset() {
offsetY = _vm->_game->_script->readValExpr();
if (offsetX == -1) {
+ _vm->_game->_preventScroll = !_vm->_game->_preventScroll;
+
WRITE_VAR(2, _vm->_draw->_scrollOffsetX);
WRITE_VAR(3, _vm->_draw->_scrollOffsetY);
} else {
@@ -996,11 +998,8 @@ void Inter_v2::o2_playImd() {
close = false;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
@@ -1306,8 +1305,14 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
char *file = _vm->_game->_script->getResultStr();
+ // WORKAROUND: In some games (at least all the Playtoons), some files are
+ // read on CD (and only on CD). "@:\" is replaced by the CD drive letter.
+ // As the files are copied on the HDD, those characters are skipped.
+ if (strncmp(file, "@:\\", 3) ==0 )
+ file += 3;
+
// WORKAROUND: For some reason, the variable indicating which TOT to load next
- // is overwritten in the guard house card game in Woodruff
+ // is overwritten in the guard house card game in Woodruff.
if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(file, "6.TOT"))
strcpy(file, "EMAP2011.TOT");
diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp
index 48378a5987..1f6899d85c 100644
--- a/engines/gob/inter_v4.cpp
+++ b/engines/gob/inter_v4.cpp
@@ -233,11 +233,8 @@ void Inter_v4::o4_playVmdOrMusic() {
return;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp
index aa4721ff0a..4e2ec69cf2 100644
--- a/engines/gob/inter_v6.cpp
+++ b/engines/gob/inter_v6.cpp
@@ -164,12 +164,9 @@ void Inter_v6::o6_playVmdOrMusic() {
return;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey,
palCmd, palStart, palEnd, 0, -1, false, -1, true);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp
index 135c50c92c..bad4723159 100644
--- a/engines/gob/mult_v2.cpp
+++ b/engines/gob/mult_v2.cpp
@@ -1105,8 +1105,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
int16 baseFrame, palFrame, lastFrame;
uint16 flags;
- _vm->_game->_preventScroll = true;
-
if (_vm->_draw->_renderFlags & 0x100) {
x = VAR(55);
y = VAR(56);
@@ -1115,7 +1113,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
if (key.imdFile == -1) {
_vm->_vidPlayer->primaryClose();
- _vm->_game->_preventScroll = false;
return;
}
@@ -1131,15 +1128,12 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
if ((palFrame != -1) && (lastFrame != -1))
if ((lastFrame - palFrame) < startFrame)
if (!(key.flags & 0x4000)) {
- _vm->_game->_preventScroll = false;
_vm->_vidPlayer->primaryClose();
return;
}
- if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags)) {
- _vm->_game->_preventScroll = false;
+ if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags))
return;
- }
if (palFrame == -1)
palFrame = 0;
@@ -1265,9 +1259,6 @@ void Mult_v2::advanceObjects(int16 index) {
}
}
- if (!hasImds && (_vm->_draw->_showCursor == 3))
- _vm->_game->_preventScroll = false;
-
doSoundAnim(stop, frame);
WRITE_VAR(22, frame);
diff --git a/engines/gob/save/saveload_playtoons.cpp b/engines/gob/save/saveload_playtoons.cpp
index 97da909e7c..3014e3f2bf 100644
--- a/engines/gob/save/saveload_playtoons.cpp
+++ b/engines/gob/save/saveload_playtoons.cpp
@@ -47,6 +47,8 @@ SaveLoad_Playtoons::SaveFile SaveLoad_Playtoons::_saveFiles[] = {
{ "titre.007", kSaveModeExists, 0, 0}, // Playtoons CK 2 empty title (???)
{ "titre.008", kSaveModeExists, 0, 0}, // Playtoons CK 3 empty title (???)
{ "mdo.def", kSaveModeExists, 0, 0},
+ { "dan.itk", kSaveModeNone, 0, 0},
+ { "did.inf", kSaveModeSave, 0, 0},
};
SaveLoad::SaveMode SaveLoad_Playtoons::getSaveMode(const char *fileName) const {
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 1a8668b1c2..d51cbad6b3 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -141,7 +141,8 @@ void Util::processInput(bool scroll) {
y -= _vm->_video->_screenDeltaY;
_vm->_util->setMousePos(x, y);
- _vm->_game->evaluateScroll(x, y);
+
+ _vm->_game->wantScroll(x, y);
}
}
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index d9924d233b..cc1add9ce7 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -95,7 +95,8 @@ void GUI::initMenu(Menu &menu) {
if (_vm->gameFlags().gameID == GI_LOL) {
printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9);
} else {
- printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
}
@@ -142,7 +143,9 @@ void GUI::initMenu(Menu &menu) {
else
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
} else {
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+
if (i == menu.highlightedItem)
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
else
@@ -158,7 +161,8 @@ void GUI::initMenu(Menu &menu) {
menu.item[i].labelY = menu.item[i].y + 3;
printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10);
} else {
- printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
}
}
@@ -253,7 +257,8 @@ void GUI::redrawText(const Menu &menu) {
textY++;
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
} else {
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
}
}
@@ -278,7 +283,8 @@ void GUI::redrawHighlight(const Menu &menu) {
textY++;
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
} else {
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
}
}
@@ -324,7 +330,10 @@ int GUI::redrawButtonCallback(Button *button) {
return 0;
_screen->hideMouse();
- _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17);
+ else
+ _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
_screen->showMouse();
return 0;
@@ -335,7 +344,10 @@ int GUI::redrawShadedButtonCallback(Button *button) {
return 0;
_screen->hideMouse();
- _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18);
+ else
+ _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
_screen->showMouse();
return 0;
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index 4624aced90..e9c71f511d 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -56,10 +56,10 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
return 0;
} else {
_screen->hideMouse();
- _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
+ _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
snd_playSoundEffect(0x35);
setMouseItem(inventoryItem);
- updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179);
_itemInHand = inventoryItem;
_screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = 0xFF;
@@ -68,10 +68,14 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
if (inventoryItem != 0xFF) {
snd_playSoundEffect(0x35);
_screen->hideMouse();
- _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
+ _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
_screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
setMouseItem(inventoryItem);
- updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179);
+ // TODO: Proper support for both taken strings in Amiga version
+ if (_flags.platform == Common::kPlatformAmiga)
+ updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179);
+ else
+ updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[1], 179);
_screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
_itemInHand = inventoryItem;
@@ -80,7 +84,7 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
_screen->hideMouse();
_screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
_screen->setMouseCursor(1, 1, _shapes[0]);
- updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _placedList[0], 179);
_screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
_itemInHand = -1;
@@ -204,9 +208,29 @@ void GUI_LoK::createScreenThumbnail(Graphics::Surface &dst) {
uint8 *screen = new uint8[Screen::SCREEN_W*Screen::SCREEN_H];
if (screen) {
_screen->queryPageFromDisk("SEENPAGE.TMP", 0, screen);
-
uint8 screenPal[768];
- _screen->getRealPalette(2, screenPal);
+
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ _screen->getRealPalette(0, &screenPal[ 0]);
+ _screen->getRealPalette(1, &screenPal[96]);
+
+ // Set the interface palette text color to white
+ screenPal[96 + 16 * 3 + 0] = 0xFF;
+ screenPal[96 + 16 * 3 + 1] = 0xFF;
+ screenPal[96 + 16 * 3 + 2] = 0xFF;
+
+ if (_screen->isInterfacePaletteEnabled()) {
+ for (int y = 0; y < 64; ++y) {
+ for (int x = 0; x < 320; ++x) {
+ screen[(y + 136) * Screen::SCREEN_W + x] += 32;
+ }
+ }
+ }
+
+ } else {
+ _screen->getRealPalette(2, screenPal);
+ }
+
::createThumbnail(&dst, screen, Screen::SCREEN_W, Screen::SCREEN_H, screenPal);
}
delete[] screen;
@@ -365,6 +389,13 @@ void GUI_LoK::setGUILabels() {
offsetOptions = 10;
offsetOn = 0;
walkspeedGarbageOffset = 0;
+ } else if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ // English Amiga version
+ offset = 23;
+ offsetOn = 23;
+ offsetOptions = 32;
+ walkspeedGarbageOffset = 2;
+ offsetMainMenu = 23;
}
assert(offset + 27 < _vm->_guiStringsSize);
@@ -448,8 +479,14 @@ int GUI_LoK::buttonMenuCallback(Button *caller) {
_vm->snd_playSoundEffect(0x36);
return 0;
}
- // XXX
- _screen->setPaletteIndex(0xFE, 60, 60, 0);
+
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ _screen->setPaletteIndex(0x10, 0x3F, 0x3F, 0x3F);
+ _screen->setInterfacePalette(_screen->getPalette(1), 0x3F, 0x3F, 0x3F);
+ } else {
+ _screen->setPaletteIndex(0xFE, 60, 60, 0);
+ }
+
for (int i = 0; i < 6; i++) {
_menuButtonData[i].data0Val1 = _menuButtonData[i].data1Val1 = _menuButtonData[i].data2Val1 = 4;
_menuButtonData[i].data0Callback = _redrawShadedButtonFunctor;
@@ -639,12 +676,12 @@ int GUI_LoK::loadGameMenu(Button *button) {
}
void GUI_LoK::redrawTextfield() {
- _screen->fillRect(38, 91, 287, 102, 250);
+ _screen->fillRect(38, 91, 287, 102, _vm->gameFlags().platform == Common::kPlatformAmiga ? 18 : 250);
_text->printText(_savegameName, 38, 92, 253, 0, 0);
_screen->_charWidth = -2;
int width = _screen->getTextWidth(_savegameName);
- _screen->fillRect(39 + width, 93, 45 + width, 100, 254);
+ _screen->fillRect(39 + width, 93, 45 + width, 100, _vm->gameFlags().platform == Common::kPlatformAmiga ? 31 : 254);
_screen->_charWidth = 0;
_screen->updateScreen();
@@ -923,6 +960,9 @@ void GUI_LoK::setupControls(Menu &menu) {
menu.item[3].itemString = "ERROR";
}
} else {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ clickableOffset = 5;
+
menu.item[4].enabled = 0;
menu.item[4].labelString = 0;
}
diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp
index aef5ba5f13..bc490d9764 100644
--- a/engines/kyra/items_lok.cpp
+++ b/engines/kyra/items_lok.cpp
@@ -414,7 +414,7 @@ int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, in
if (unk1 == 0 && unk2 != 0) {
assert(_itemList && _droppedList);
- updateSentenceCommand(_itemList[item], _droppedList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(item)], _droppedList[0], 179);
}
return 1;
@@ -434,7 +434,7 @@ void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) {
setMouseItem(_itemInHand);
assert(_itemList && _takenList);
- updateSentenceCommand(_itemList[_itemInHand], _takenList[1], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[1], 179);
_screen->showMouse();
clickEventHandler2();
}
@@ -693,7 +693,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) {
if (itemPos != -1) {
restoreItemRect1(x, y);
- _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
+ _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
backUpItemRect1(x, y);
}
@@ -715,7 +715,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) {
} else {
_characterList[0].inventoryItems[itemPos] = 0xFF;
_screen->hideMouse();
- _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
+ _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
_screen->showMouse();
}
_screen->showMouse();
@@ -879,7 +879,7 @@ void KyraEngine_LoK::redrawInventory(int page) {
_screen->_curPage = page;
_screen->hideMouse();
for (int i = 0; i < 10; ++i) {
- _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page);
+ _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, page);
if (_currentCharacter->inventoryItems[i] != 0xFF) {
uint8 item = _currentCharacter->inventoryItems[i];
_screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0);
@@ -910,5 +910,62 @@ void KyraEngine_LoK::restoreItemRect1(int xpos, int ypos) {
_screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]);
}
+int KyraEngine_LoK::getItemListIndex(uint16 item) {
+ if (_flags.platform != Common::kPlatformAmiga)
+ return item;
+
+ // "Unknown item" is at 81.
+ if (item == 0xFFFF || item == 0xFF)
+ return 81;
+ // The first item names are mapped directly
+ else if (item <= 28)
+ return item;
+ // There's only one string for "Fireberries"
+ else if (item >= 29 && item <= 33)
+ return 29;
+ // Correct offsets
+ else if (item >= 34 && item <= 59)
+ return item - 4;
+ // There's only one string for "Red Potion"
+ else if (item >= 60 && item <= 61)
+ return 56;
+ // There's only one string for "Blue Potion"
+ else if (item >= 62 && item <= 63)
+ return 57;
+ // There's only one string for "Yellow Potion"
+ else if (item >= 64 && item <= 65)
+ return 58;
+ // Correct offsets
+ else if (item >= 66 && item <= 69)
+ return item - 7;
+ // There's only one string for "Fresh Water"
+ else if (item >= 70 && item <= 71)
+ return 63;
+ // There's only one string for "Salt Water"
+ else if (item >= 72 && item <= 73)
+ return 64;
+ // There's only one string for "Mineral Water"
+ else if (item >= 74 && item <= 75)
+ return 65;
+ // There's only one string for "Magical Water"
+ else if (item >= 76 && item <= 77)
+ return 66;
+ // There's only one string for "Empty Flask"
+ else if (item >= 78 && item <= 79)
+ return 67;
+ // There's only one string for "Scroll"
+ else if (item >= 80 && item <= 89)
+ return 68;
+ // There's only one string for "Parchment scrap"
+ else if (item >= 90 && item <= 94)
+ return 69;
+ // Correct offsets
+ else if (item >= 95)
+ return item - 25;
+
+ // This should never happen, but still GCC warns about it.
+ return 81;
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index 3863cad251..fc19b2fb65 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -368,6 +368,9 @@ void KyraEngine_LoK::startup() {
loadMainScreen();
_screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
+ if (_flags.platform == Common::kPlatformAmiga)
+ _screen->loadPaletteTable("PALETTE.DAT", 6);
+
// XXX
_animator->initAnimStateList();
setCharactersInDefaultScene();
@@ -669,7 +672,7 @@ int KyraEngine_LoK::processInputHelper(int xpos, int ypos) {
currentRoom->itemsTable[item] = 0xFF;
setMouseItem(item2);
assert(_itemList && _takenList);
- updateSentenceCommand(_itemList[item2], _takenList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(item2)], _takenList[0], 179);
_itemInHand = item2;
_screen->showMouse();
clickEventHandler2();
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index 4d99ed11af..2783e92aee 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -289,6 +289,8 @@ protected:
void removeHandItem();
void setMouseItem(uint16 item);
+ int getItemListIndex(uint16 item);
+
// -> graphics effects
void wipeDownMouseItem(int xpos, int ypos);
void itemSpecialFX(int x, int y, int item);
@@ -523,35 +525,35 @@ protected:
const uint8 *_seq_Demo4;
const uint8 *_seq_Reunion;
- const char * const*_seq_WSATable;
- const char * const*_seq_CPSTable;
- const char * const*_seq_COLTable;
- const char * const*_seq_textsTable;
+ const char * const *_seq_WSATable;
+ const char * const *_seq_CPSTable;
+ const char * const *_seq_COLTable;
+ const char * const *_seq_textsTable;
int _seq_WSATable_Size;
int _seq_CPSTable_Size;
int _seq_COLTable_Size;
int _seq_textsTable_Size;
- const char * const*_itemList;
- const char * const*_takenList;
- const char * const*_placedList;
- const char * const*_droppedList;
- const char * const*_noDropList;
- const char * const*_putDownFirst;
- const char * const*_waitForAmulet;
- const char * const*_blackJewel;
- const char * const*_poisonGone;
- const char * const*_healingTip;
- const char * const*_thePoison;
- const char * const*_fluteString;
- const char * const*_wispJewelStrings;
- const char * const*_magicJewelString;
- const char * const*_flaskFull;
- const char * const*_fullFlask;
- const char * const*_veryClever;
- const char * const*_homeString;
- const char * const*_newGameString;
+ const char * const *_itemList;
+ const char * const *_takenList;
+ const char * const *_placedList;
+ const char * const *_droppedList;
+ const char * const *_noDropList;
+ const char * const *_putDownFirst;
+ const char * const *_waitForAmulet;
+ const char * const *_blackJewel;
+ const char * const *_poisonGone;
+ const char * const *_healingTip;
+ const char * const *_thePoison;
+ const char * const *_fluteString;
+ const char * const *_wispJewelStrings;
+ const char * const *_magicJewelString;
+ const char * const *_flaskFull;
+ const char * const *_fullFlask;
+ const char * const *_veryClever;
+ const char * const *_homeString;
+ const char * const *_newGameString;
int _itemList_Size;
int _takenList_Size;
@@ -573,13 +575,13 @@ protected:
int _homeString_Size;
int _newGameString_Size;
- const char * const*_characterImageTable;
+ const char * const *_characterImageTable;
int _characterImageTableSize;
- const char * const*_guiStrings;
+ const char * const *_guiStrings;
int _guiStringsSize;
- const char * const*_configStrings;
+ const char * const *_configStrings;
int _configStringsSize;
Shape *_defaultShapeTable;
@@ -617,16 +619,16 @@ protected:
Room *_roomTable;
int _roomTableSize;
- const char * const*_roomFilenameTable;
+ const char * const *_roomFilenameTable;
int _roomFilenameTableSize;
const uint8 *_amuleteAnim;
- const uint8 * const*_specialPalettes;
+ const uint8 * const *_specialPalettes;
- const char *const *_soundFiles;
+ const char * const *_soundFiles;
int _soundFilesSize;
- const char *const *_soundFilesIntro;
+ const char * const *_soundFilesIntro;
int _soundFilesIntroSize;
const int32 *_cdaTrackTable;
int _cdaTrackTableSize;
@@ -649,6 +651,9 @@ protected:
static const uint16 _amuletY[];
static const uint16 _amuletX2[];
static const uint16 _amuletY2[];
+
+ // special palette handling for AMIGA
+ void setupZanthiaPalette(int pal);
protected:
void setupOpcodeTable();
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index d2c8be9556..e3d28163a8 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -160,7 +160,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_flyingObjects = 0;
_monsters = 0;
_lastMouseRegion = 0;
- _objectLastDirection = _monsterCountUnk = _monsterShiftAlt = 0;
+ _objectLastDirection = _monsterStepCounter = _monsterStepMode = 0;
_monsterCurBlock = 0;
_seqWindowX1 = _seqWindowY1 = _seqWindowX2 = _seqWindowY2 = _seqTrigger = 0;
_spsWindowX = _spsWindowY = _spsWindowW = _spsWindowH = 0;
@@ -730,7 +730,7 @@ int LoLEngine::mainMenu() {
// 16 color mode
{
{ 0, 0, 0, 0, 0 },
- { 0x01, 0x04, 0x0C, 0x03, 0x00, 0xC1, 0xE1 },
+ { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xC1, 0xE1 },
{ 0xCC, 0xDD, 0xDD, 0xDD },
Screen::FID_9_FNT, 1
}
@@ -738,6 +738,9 @@ int LoLEngine::mainMenu() {
int dataIndex = _flags.use16ColorMode ? 1 : 0;
+ if (!_flags.isTalkie)
+ --data[dataIndex].menuTable[3];
+
if (hasSave)
++data[dataIndex].menuTable[3];
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index f4ac597b5c..06950779b1 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -1296,8 +1296,8 @@ private:
uint8 _monsterAnimType[3];
uint16 _monsterCurBlock;
int _objectLastDirection;
- int _monsterCountUnk;
- int _monsterShiftAlt;
+ int _monsterStepCounter;
+ int _monsterStepMode;
const uint16 *_monsterModifiers;
int _monsterModifiersSize;
diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp
index c59f2bebf6..13f08715fd 100644
--- a/engines/kyra/saveload_lok.cpp
+++ b/engines/kyra/saveload_lok.cpp
@@ -177,15 +177,32 @@ Common::Error KyraEngine_LoK::loadGameState(int slot) {
seq_createAmuletJewel(i-0x55, 10, 1, 1);
}
}
- _screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 8);
- _screen->copyRegion(0, 0, 0, 0, 320, 200, 8, 0);
+
+ _screen->copyRegion(8, 8, 8, 8, 304, 212, 10, 0);
}
setHandItem(_itemInHand);
- _animator->setBrandonAnimSeqSize(3, 48);
+
+ // Will-O-Wisp uses a different shape size than Brandon's usual
+ // shape, thus we need to setup the correct size depending on
+ // his state over here. This fixes graphics glitches when loading
+ // saves, where Brandon is transformed into the Will-O-Wisp.
+ if (_brandonStatusBit & 2)
+ _animator->setBrandonAnimSeqSize(5, 48);
+ else
+ _animator->setBrandonAnimSeqSize(3, 48);
+
redrawInventory(0);
- _brandonPosX = brandonX;
- _brandonPosY = brandonY;
+
+ _brandonPosX = _brandonPosY = -1;
+
+ // Unlike the original we did restore Brandon's position in the scene screen on load.
+ // This appereantly caused graphics gliches in some scenes. For example bug #2835715
+ // ("KYRA: GFX glitch in Amiga version at the bridge") is caused by this feature.
+ // Thus we disable that for now.
+ //_brandonPosX = brandonX;
+ //_brandonPosY = brandonY;
+
enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1);
_animator->animRefreshNPC(0);
diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp
index fc1ca41189..e7f4ecbae0 100644
--- a/engines/kyra/scene_lok.cpp
+++ b/engines/kyra/scene_lok.cpp
@@ -778,10 +778,10 @@ void KyraEngine_LoK::initSceneScreen(int brandonAlive) {
if (_unkScreenVar2 == 1)
_screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false);
else
- _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+ _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
if (_unkScreenVar1 && !queryGameFlag(0xA0)) {
- if (_currentCharacter->sceneId == 45 && _paletteChanged)
+ if (_currentCharacter->sceneId == 45 && _cauldronState)
_screen->getPalette(0).copy(_screen->getPalette(4), 12, 1);
if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1))
@@ -1203,6 +1203,66 @@ bool KyraEngine_LoK::lineIsPassable(int x, int y) {
#pragma mark -
+void KyraEngine_LoK::setupZanthiaPalette(int pal) {
+ uint8 r, g, b;
+
+ switch (pal - 17) {
+ case 0:
+ // 0x88F
+ r = 33;
+ g = 33;
+ b = 63;
+ break;
+
+ case 1:
+ // 0x00F
+ r = 0;
+ g = 0;
+ b = 63;
+ break;
+
+ case 2:
+ // 0xF88
+ r = 63;
+ g = 33;
+ b = 33;
+ break;
+
+ case 3:
+ // 0xF00
+ r = 63;
+ g = 0;
+ b = 0;
+ break;
+
+ case 4:
+ // 0xFF9
+ r = 63;
+ g = 63;
+ b = 37;
+ break;
+
+ case 5:
+ // 0xFF1
+ r = 63;
+ g = 63;
+ b = 4;
+ break;
+
+ default:
+ // 0xFFF
+ r = 63;
+ g = 63;
+ b = 63;
+ }
+
+ _screen->getPalette(4)[12 * 3 + 0] = r;
+ _screen->getPalette(4)[12 * 3 + 1] = g;
+ _screen->getPalette(4)[12 * 3 + 2] = b;
+}
+
+#pragma mark -
+
void KyraEngine_LoK::setupSceneResource(int sceneId) {
if (!_flags.isTalkie)
return;
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 7a7544a589..8d4ea7e022 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -48,6 +48,7 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system)
_drawShapeVar5 = 0;
_sjisFont = 0;
+ memset(_fonts, 0, sizeof(_fonts));
}
Screen::~Screen() {
@@ -56,10 +57,8 @@ Screen::~Screen() {
delete[] _pagePtrs[0];
- for (int f = 0; f < ARRAYSIZE(_fonts); ++f) {
- delete[] _fonts[f].fontData;
- _fonts[f].fontData = NULL;
- }
+ for (int f = 0; f < ARRAYSIZE(_fonts); ++f)
+ delete _fonts[f];
delete _sjisFont;
delete _screenPalette;
@@ -80,6 +79,7 @@ bool Screen::init() {
_useOverlays = false;
_useSJIS = false;
_use16ColorMode = _vm->gameFlags().use16ColorMode;
+ _isAmiga = (_vm->gameFlags().platform == Common::kPlatformAmiga);
if (_vm->gameFlags().useHiResOverlay) {
_useOverlays = true;
@@ -103,7 +103,6 @@ bool Screen::init() {
}
}
-
_curPage = 0;
uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE * 8];
for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2)
@@ -112,8 +111,10 @@ bool Screen::init() {
memset(_shapePages, 0, sizeof(_shapePages));
- const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 12 : 4;
- const int numColors = _use16ColorMode ? 16 : ((_vm->gameFlags().platform == Common::kPlatformAmiga) ? 32 : 256);
+ const int paletteCount = _isAmiga ? 13 : 4;
+ const int numColors = _use16ColorMode ? 16 : (_isAmiga ? 32 : 256);
+
+ _interfacePaletteEnabled = false;
_screenPalette = new Palette(numColors);
assert(_screenPalette);
@@ -205,6 +206,8 @@ void Screen::setResolution() {
void Screen::updateScreen() {
if (_useOverlays)
updateDirtyRectsOvl();
+ else if (_isAmiga && _interfacePaletteEnabled)
+ updateDirtyRectsAmiga();
else
updateDirtyRects();
@@ -232,6 +235,77 @@ void Screen::updateDirtyRects() {
_dirtyRects.clear();
}
+void Screen::updateDirtyRectsAmiga() {
+ if (_forceFullUpdate) {
+ _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, 136);
+
+ // Page 8 is not used by Kyra 1 AMIGA, thus we can use it to adjust the colors
+ copyRegion(0, 136, 0, 0, 320, 64, 0, 8, CR_NO_P_CHECK);
+
+ uint8 *dst = getPagePtr(8);
+ for (int y = 0; y < 64; ++y)
+ for (int x = 0; x < 320; ++x)
+ *dst++ += 32;
+
+ _system->copyRectToScreen(getCPagePtr(8), SCREEN_W, 0, 136, SCREEN_W, 64);
+ } else {
+ const byte *page0 = getCPagePtr(0);
+ Common::List<Common::Rect>::iterator it;
+
+ for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
+ if (it->bottom <= 136) {
+ _system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height());
+ } else {
+ // Check whether the rectangle is part of both the screen and the interface
+ if (it->top < 136) {
+ // The rectangle covers both screen part and interface part
+
+ const int screenHeight = 136 - it->top;
+ const int interfaceHeight = it->bottom - 136;
+
+ const int width = it->width();
+ const int lineAdd = SCREEN_W - width;
+
+ // Copy the screen part verbatim
+ _system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, width, screenHeight);
+
+ // Adjust the interface part
+ copyRegion(it->left, 136, 0, 0, width, interfaceHeight, 0, 8, Screen::CR_NO_P_CHECK);
+
+ uint8 *dst = getPagePtr(8);
+ for (int y = 0; y < interfaceHeight; ++y) {
+ for (int x = 0; x < width; ++x)
+ *dst++ += 32;
+ dst += lineAdd;
+ }
+
+ _system->copyRectToScreen(getCPagePtr(8), SCREEN_W, it->left, 136, width, interfaceHeight);
+ } else {
+ // The rectangle only covers the interface part
+
+ const int width = it->width();
+ const int height = it->height();
+ const int lineAdd = SCREEN_W - width;
+
+ copyRegion(it->left, it->top, 0, 0, width, height, 0, 8, Screen::CR_NO_P_CHECK);
+
+ uint8 *dst = getPagePtr(8);
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x)
+ *dst++ += 32;
+ dst += lineAdd;
+ }
+
+ _system->copyRectToScreen(getCPagePtr(8), SCREEN_W, it->left, it->top, width, height);
+ }
+ }
+ }
+ }
+
+ _forceFullUpdate = false;
+ _dirtyRects.clear();
+}
+
void Screen::updateDirtyRectsOvl() {
if (_forceFullUpdate) {
const byte *src = getCPagePtr(0);
@@ -591,7 +665,7 @@ void Screen::setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue) {
}
void Screen::getRealPalette(int num, uint8 *dst) {
- const int colors = (_vm->gameFlags().platform == Common::kPlatformAmiga ? 32 : 256);
+ const int colors = _isAmiga ? 32 : 256;
const uint8 *palData = getPalette(num).getData();
if (!palData) {
@@ -622,6 +696,41 @@ void Screen::setScreenPalette(const Palette &pal) {
_system->setPalette(screenPal, 0, pal.getNumColors());
}
+void Screen::enableInterfacePalette(bool e) {
+ _interfacePaletteEnabled = e;
+
+ _forceFullUpdate = true;
+ _dirtyRects.clear();
+
+ // TODO: We might need to reset the mouse cursor
+
+ updateScreen();
+}
+
+void Screen::setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b) {
+ if (!_isAmiga)
+ return;
+
+ uint8 screenPal[32 * 4];
+
+ assert(32 <= pal.getNumColors());
+
+ for (int i = 0; i < pal.getNumColors(); ++i) {
+ if (i != 0x10) {
+ screenPal[4 * i + 0] = (pal[i * 3 + 0] * 0xFF) / 0x3F;
+ screenPal[4 * i + 1] = (pal[i * 3 + 1] * 0xFF) / 0x3F;
+ screenPal[4 * i + 2] = (pal[i * 3 + 2] * 0xFF) / 0x3F;
+ } else {
+ screenPal[4 * i + 0] = (r * 0xFF) / 0x3F;
+ screenPal[4 * i + 1] = (g * 0xFF) / 0x3F;
+ screenPal[4 * i + 2] = (b * 0xFF) / 0x3F;
+ }
+ screenPal[4 * i + 3] = 0;
+ }
+
+ _system->setPalette(screenPal, 32, pal.getNumColors());
+}
+
void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) {
assert(y + h <= SCREEN_H);
const uint8 *src = getPagePtr(page) + y * SCREEN_W;
@@ -948,81 +1057,52 @@ void Screen::setTextColor(const uint8 *cmap, int a, int b) {
}
bool Screen::loadFont(FontId fontId, const char *filename) {
- Font *fnt = &_fonts[fontId];
-
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return true;
-
- if (!fnt)
- error("fontId %d is invalid", fontId);
-
- if (fnt->fontData)
- delete[] fnt->fontData;
-
- uint32 sz = 0;
- uint8 *fontData = fnt->fontData = _vm->resource()->fileData(filename, &sz);
-
- if (!fontData || !sz)
- error("Couldn't load font file '%s'", filename);
+ Font *&fnt = _fonts[fontId];
- uint16 fontSig = READ_LE_UINT16(fontData + 2);
-
- if (fontSig != 0x500)
- error("Invalid font data (file '%s', fontSig: %.04X)", filename, fontSig);
+ if (!fnt) {
+ if (_isAmiga)
+ fnt = new AMIGAFont();
+ else
+ fnt = new DOSFont();
- fnt->charWidthTable = fontData + READ_LE_UINT16(fontData + 8);
- fnt->fontDescOffset = READ_LE_UINT16(fontData + 4);
- fnt->charBitmapOffset = READ_LE_UINT16(fontData + 6);
- fnt->charWidthTableOffset = READ_LE_UINT16(fontData + 8);
- fnt->charHeightTableOffset = READ_LE_UINT16(fontData + 0xC);
+ assert(fnt);
+ }
- fnt->lastGlyph = *(fnt->fontData + fnt->fontDescOffset + 3);
+ Common::SeekableReadStream *file = _vm->resource()->createReadStream(filename);
+ if (!file)
+ error("Font file '%s' is missing", filename);
- return true;
+ bool ret = fnt->load(*file);
+ fnt->setColorMap(_textColorsMap);
+ delete file;
+ return ret;
}
Screen::FontId Screen::setFont(FontId fontId) {
FontId prev = _currentFont;
_currentFont = fontId;
+
+ assert(_fonts[_currentFont]);
+
return prev;
}
int Screen::getFontHeight() const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
- return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 4);
+ return _fonts[_currentFont]->getHeight();
}
int Screen::getFontWidth() const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
- return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 5);
+ return _fonts[_currentFont]->getWidth();
}
int Screen::getCharWidth(uint16 c) const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
if ((c & 0xFF00) && _sjisFont)
return _sjisFont->getFontWidth() >> 1;
- if (_fonts[_currentFont].lastGlyph < c)
- return 0;
- else
- return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth;
+ return _fonts[_currentFont]->getCharWidth(c) + _charWidth;
}
int Screen::getTextWidth(const char *str) const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
int curLineLen = 0;
int maxLineLen = 0;
while (1) {
@@ -1050,9 +1130,6 @@ int Screen::getTextWidth(const char *str) const {
}
void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2) {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return;
uint8 cmap[2];
cmap[0] = color2;
cmap[1] = color1;
@@ -1107,73 +1184,19 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
}
void Screen::drawCharANSI(uint8 c, int x, int y) {
- Font *fnt = &_fonts[_currentFont];
-
- if (c > fnt->lastGlyph)
- return;
+ Font *fnt = _fonts[_currentFont];
+ assert(fnt);
- uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x;
-
- uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2);
- if (bitmapOffset == 0)
- return;
-
- uint8 charWidth = *(fnt->fontData + fnt->charWidthTableOffset + c);
- if (!charWidth || charWidth + x > SCREEN_W)
- return;
+ const int charWidth = fnt->getCharWidth(c);
+ const int charHeight = fnt->getHeight();
- uint8 charH0 = getFontHeight();
- if (!charH0 || charH0 + y > SCREEN_H)
+ if (x + charWidth > SCREEN_W || y + charHeight > SCREEN_H)
return;
- uint8 charH1 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2);
- uint8 charH2 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2 + 1);
-
- charH0 -= charH1 + charH2;
-
- const uint8 *src = fnt->fontData + bitmapOffset;
- const int pitch = SCREEN_W - charWidth;
-
- while (charH1--) {
- uint8 col = _textColorsMap[0];
- for (int i = 0; i < charWidth; ++i) {
- if (col != 0)
- *dst = col;
- ++dst;
- }
- dst += pitch;
- }
-
- while (charH2--) {
- uint8 b = 0;
- for (int i = 0; i < charWidth; ++i) {
- uint8 col;
- if (i & 1) {
- col = _textColorsMap[b >> 4];
- } else {
- b = *src++;
- col = _textColorsMap[b & 0xF];
- }
- if (col != 0) {
- *dst = col;
- }
- ++dst;
- }
- dst += pitch;
- }
-
- while (charH0--) {
- uint8 col = _textColorsMap[0];
- for (int i = 0; i < charWidth; ++i) {
- if (col != 0)
- *dst = col;
- ++dst;
- }
- dst += pitch;
- }
+ fnt->drawChar(c, getPagePtr(_curPage) + y * SCREEN_W + x, SCREEN_W);
if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x, y, charWidth, getFontHeight());
+ addDirtyRect(x, y, charWidth, charHeight);
}
void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) {
@@ -2068,85 +2091,94 @@ void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch, bool
wrapped_decodeFrameDeltaPage<false>(dst, src, pitch);
}
-void Screen::convertAmigaGfx(uint8 *data, int w, int h, bool offscreen) {
- static uint8 tmp[320*200];
-
- if (offscreen) {
- uint8 *curLine = tmp;
- const uint8 *src = data;
- int hC = h;
- while (hC--) {
- uint8 *dst1 = curLine;
- uint8 *dst2 = dst1 + 8000;
- uint8 *dst3 = dst2 + 8000;
- uint8 *dst4 = dst3 + 8000;
- uint8 *dst5 = dst4 + 8000;
-
- int width = w >> 3;
- while (width--) {
- *dst1++ = *src++;
- *dst2++ = *src++;
- *dst3++ = *src++;
- *dst4++ = *src++;
- *dst5++ = *src++;
- }
-
- curLine += 40;
+void Screen::convertAmigaGfx(uint8 *data, int w, int h, int depth, bool wsa, int bytesPerPlane) {
+ const int planeWidth = (bytesPerPlane == -1) ? (w + 7) / 8 : bytesPerPlane;
+ const int planeSize = planeWidth * h;
+ const uint imageSize = planeSize * depth;
+
+ // Our static buffer which holds the plane data. We need this
+ // because the "data" pointer is both source and destination pointer.
+ // The buffer has enough space to fit the AMIGA MSC files, which are
+ // the biggest graphics files found in the AMIGA version.
+ static uint8 temp[40320];
+ assert(imageSize <= sizeof(temp));
+
+ // WSA files store their graphics data in a little different format, than
+ // the usual AMIGA graphics format used in BitMaps. Thus we need to do
+ // some special handling for them here. Means we convert them into
+ // the usual format.
+ //
+ // TODO: We might think of moving this conversion into the WSAMovieAmiga
+ // class.
+ if (wsa) {
+ const byte *src = data;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < planeWidth; ++x)
+ for (int i = 0; i < depth; ++i)
+ temp[y * planeWidth + x + planeSize * i] = *src++;
}
} else {
- memcpy(tmp, data, w*h);
+ memcpy(temp, data, imageSize);
}
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
- int bytePos = x/8+y*40;
- int bitPos = 7-(x&7);
-
- byte colorIndex = 0;
- colorIndex |= (((tmp[bytePos + 8000 * 0] & (1 << bitPos)) >> bitPos) & 0x1) << 0;
- colorIndex |= (((tmp[bytePos + 8000 * 1] & (1 << bitPos)) >> bitPos) & 0x1) << 1;
- colorIndex |= (((tmp[bytePos + 8000 * 2] & (1 << bitPos)) >> bitPos) & 0x1) << 2;
- colorIndex |= (((tmp[bytePos + 8000 * 3] & (1 << bitPos)) >> bitPos) & 0x1) << 3;
- colorIndex |= (((tmp[bytePos + 8000 * 4] & (1 << bitPos)) >> bitPos) & 0x1) << 4;
- *data++ = colorIndex;
+ const int bytePos = x / 8 + y * planeWidth;
+ const int bitPos = 7 - (x & 7); // x & 7 == x % 8
+
+ byte col = 0;
+
+ for (int i = 0; i < depth; ++i)
+ col |= ((temp[bytePos + planeSize * i] >> bitPos) & 1) << i;
+
+ *data++ = col;
}
}
}
void Screen::convertAmigaMsc(uint8 *data) {
- byte *plane1 = data + 5760 * 1;
- byte *plane2 = data + 5760 * 2;
- byte *plane3 = data + 5760 * 3;
- byte *plane4 = data + 5760 * 4;
- byte *plane5 = data + 5760 * 5;
- byte *plane6 = data + 5760 * 6;
- for (int i = 0; i < 5760; ++i) {
- byte d = plane6[i];
- d = (plane5[i] |= d);
- d = (plane4[i] |= d);
- d = (plane3[i] |= d);
- d = (plane2[i] |= d);
- d = (plane1[i] |= d);
- }
- byte dst[320*144];
- memset(dst, 0, sizeof(dst));
- static const byte flagTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
- for (int y = 0; y < 144; ++y) {
- for (int x = 0; x < 320; ++x) {
- if (!(flagTable[x&7] & data[y*40+(x>>3)]))
- dst[y*320+x] |= 0x80;
-
- int layer = 0;
- for (int i = 0; i < 7; ++i) {
- if (flagTable[x&7] & data[y*40+(x>>3)+i*5760])
- layer = i;
- }
+ // MSC files are always 320x144, thus we can safely assume
+ // this to be correct. Also they contain 7 planes instead
+ // of the normal 5 planes, which is used in 32 color mode.
+ // The need for 7 planes can be explained, because the MSC
+ // files have 6 bits for the layer number (bits 1 to 6)
+ // and one bit for the "blocked" flag (bit 0), and every
+ // plane contains one bit per pixel.
+ convertAmigaGfx(data, 320, 144, 7);
+
+ // We need to do some post conversion, since
+ // the AMIGA MSC format is different from the DOS
+ // one we use internally for our code.That is even
+ // after converting it from the AMIGA plane based
+ // approach to one byte per pixel approach.
+ for (int i = 0; i < 320 * 144; ++i) {
+ // The lowest bit indicates, whether the position
+ // is walkable or not. If the bit is set, the
+ // position is walkable, elsewise it is blocked.
+ if (data[i] & 1)
+ data[i] &= 0xFE;
+ else
+ data[i] |= 0x80;
- if (layer)
- dst[y*320+x] |= (layer+1);
- }
+ // The graphics layer for the pixel is saved
+ // in the following format:
+ // The highest bit set indicates the number of
+ // the graphics layer. We count the first
+ // bit as 0 here, thus we need to add one,
+ // to get the correct number.
+ //
+ // Funnily since the first bit (bit 0) is
+ // resevered for testing whether the position
+ // is walkable or not, there is no possibility
+ // for layer 1 to be present.
+ int layer = 0;
+ for (int k = 0; k < 7; ++k)
+ if (data[i] & (1 << k))
+ layer = k + 1;
+
+ data[i] &= 0x80;
+ data[i] |= layer;
}
- memcpy(data, dst, 320*144);
}
template<bool noXor>
@@ -2794,6 +2826,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
uint8 *srcPtr = srcData + 10 + palSize;
uint8 *dstData = getPagePtr(dstPage);
+ memset(dstData, 0, SCREEN_PAGE_SIZE);
if (dstPage == 0 || tempPage == 0)
_forceFullUpdate = true;
@@ -2811,11 +2844,11 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
error("Unhandled bitmap compression %d", compType);
}
- if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ if (_isAmiga) {
if (!scumm_stricmp(ext, "MSC"))
Screen::convertAmigaMsc(dstData);
else
- Screen::convertAmigaGfx(dstData, 320, 200, false);
+ Screen::convertAmigaGfx(dstData, 320, 200);
}
if (skip)
@@ -2832,7 +2865,7 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
debugC(3, kDebugLevelScreen, "Screen::loadPalette('%s', %p)", filename, (const void *)&pal);
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ if (_isAmiga)
pal.loadAmigaPalette(*stream, 0, stream->size() / Palette::kAmigaBytesPerColor);
else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode)
pal.loadPC98Palette(*stream, 0, stream->size() / Palette::kPC98BytesPerColor);
@@ -2851,7 +2884,7 @@ bool Screen::loadPaletteTable(const char *filename, int firstPalette) {
debugC(3, kDebugLevelScreen, "Screen::loadPaletteTable('%s', %d)", filename, firstPalette);
- if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ if (_isAmiga) {
const int numColors = getPalette(firstPalette).getNumColors();
const int palSize = getPalette(firstPalette).getNumColors() * Palette::kAmigaBytesPerColor;
const int numPals = stream->size() / palSize;
@@ -2874,7 +2907,7 @@ bool Screen::loadPaletteTable(const char *filename, int firstPalette) {
void Screen::loadPalette(const byte *data, Palette &pal, int bytes) {
Common::MemoryReadStream stream(data, bytes, false);
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ if (_isAmiga)
pal.loadAmigaPalette(stream, 0, stream.size() / Palette::kAmigaBytesPerColor);
else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode)
pal.loadPC98Palette(stream, 0, stream.size() / Palette::kPC98BytesPerColor);
@@ -3026,6 +3059,230 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
#pragma mark -
+DOSFont::DOSFont() {
+ _data = _widthTable = _heightTable = 0;
+ _colorMap = 0;
+ _width = _height = _numGlyphs = 0;
+ _bitmapOffsets = 0;
+}
+
+bool DOSFont::load(Common::SeekableReadStream &file) {
+ unload();
+
+ _data = new uint8[file.size()];
+ assert(_data);
+
+ file.read(_data, file.size());
+ if (file.err())
+ return false;
+
+ const uint16 fontSig = READ_LE_UINT16(_data + 2);
+
+ if (fontSig != 0x0500) {
+ warning("DOSFont: invalid font: %.04X)", fontSig);
+ return false;
+ }
+
+ const uint16 descOffset = READ_LE_UINT16(_data + 4);
+
+ _width = _data[descOffset + 5];
+ _height = _data[descOffset + 4];
+ _numGlyphs = _data[descOffset + 3] + 1;
+
+ _bitmapOffsets = (uint16 *)(_data + READ_LE_UINT16(_data + 6));
+ _widthTable = _data + READ_LE_UINT16(_data + 8);
+ _heightTable = _data + READ_LE_UINT16(_data + 12);
+
+ for (int i = 0; i < _numGlyphs; ++i)
+ _bitmapOffsets[i] = READ_LE_UINT16(&_bitmapOffsets[i]);
+
+ return true;
+}
+
+int DOSFont::getCharWidth(uint8 c) const {
+ if (c >= _numGlyphs)
+ return 0;
+ return _widthTable[c];
+}
+
+void DOSFont::drawChar(uint8 c, byte *dst, int pitch) const {
+ if (c >= _numGlyphs)
+ return;
+
+ if (!_bitmapOffsets[c])
+ return;
+
+ const uint8 *src = _data + _bitmapOffsets[c];
+ const uint8 charWidth = _widthTable[c];
+
+ if (!charWidth)
+ return;
+
+ pitch -= charWidth;
+
+ uint8 charH1 = _heightTable[c * 2 + 0];
+ uint8 charH2 = _heightTable[c * 2 + 1];
+ uint8 charH0 = _height - (charH1 + charH2);
+
+ while (charH1--) {
+ uint8 col = _colorMap[0];
+ for (int i = 0; i < charWidth; ++i) {
+ if (col != 0)
+ *dst = col;
+ ++dst;
+ }
+ dst += pitch;
+ }
+
+ while (charH2--) {
+ uint8 b = 0;
+ for (int i = 0; i < charWidth; ++i) {
+ uint8 col;
+ if (i & 1) {
+ col = _colorMap[b >> 4];
+ } else {
+ b = *src++;
+ col = _colorMap[b & 0xF];
+ }
+ if (col != 0) {
+ *dst = col;
+ }
+ ++dst;
+ }
+ dst += pitch;
+ }
+
+ while (charH0--) {
+ uint8 col = _colorMap[0];
+ for (int i = 0; i < charWidth; ++i) {
+ if (col != 0)
+ *dst = col;
+ ++dst;
+ }
+ dst += pitch;
+ }
+}
+
+void DOSFont::unload() {
+ delete[] _data;
+ _data = _widthTable = _heightTable = 0;
+ _colorMap = 0;
+ _width = _height = _numGlyphs = 0;
+ _bitmapOffsets = 0;
+}
+
+
+AMIGAFont::AMIGAFont() {
+ _width = _height = 0;
+ memset(_chars, 0, sizeof(_chars));
+}
+
+bool AMIGAFont::load(Common::SeekableReadStream &file) {
+ const uint16 dataSize = file.readUint16BE();
+ if (dataSize + 2 != file.size())
+ return false;
+
+ _width = file.readByte();
+ _height = file.readByte();
+
+ // Read the character definition offset table
+ uint16 offsets[ARRAYSIZE(_chars)];
+ for (int i = 0; i < ARRAYSIZE(_chars); ++i)
+ offsets[i] = file.readUint16BE() + 4;
+
+ if (file.err())
+ return false;
+
+ for (int i = 0; i < ARRAYSIZE(_chars); ++i) {
+ file.seek(offsets[i], SEEK_SET);
+
+ _chars[i].yOffset = file.readByte();
+ _chars[i].xOffset = file.readByte();
+ _chars[i].width = file.readByte();
+ file.readByte(); // unused
+
+ // If the y offset is 255, then the character
+ // does not have any bitmap representation
+ if (_chars[i].yOffset != 255) {
+ Character::Graphics &g = _chars[i].graphics;
+
+ g.width = file.readUint16BE();
+ g.height = file.readUint16BE();
+
+ int depth = file.readByte();
+ int specialWidth = file.readByte();
+ int flags = file.readByte();
+ int bytesPerPlane = file.readByte();
+
+ assert(depth != 0 && specialWidth == 0 && flags == 0 && bytesPerPlane != 0);
+
+ // Allocate a temporary buffer to store the plane data
+ const int planesSize = bytesPerPlane * g.height * depth;
+ uint8 *tempData = new uint8[MAX(g.width * g.height, planesSize)];
+ assert(tempData);
+
+ file.read(tempData, planesSize);
+
+ // Convert the plane based graphics to our graphic format
+ Screen::convertAmigaGfx(tempData, g.width, g.height, depth, false, bytesPerPlane);
+
+ // Create a buffer perfectly fitting the character
+ g.bitmap = new uint8[g.width * g.height];
+ assert(g.bitmap);
+
+ memcpy(g.bitmap, tempData, g.width * g.height);
+ delete[] tempData;
+ }
+
+ if (file.err())
+ return false;
+ }
+
+ return !file.err();
+}
+
+int AMIGAFont::getCharWidth(uint8 c) const {
+ if (c >= 255)
+ return 0;
+ return _chars[c].width;
+}
+
+void AMIGAFont::drawChar(uint8 c, byte *dst, int pitch) const {
+ if (c >= 255)
+ return;
+
+ if (_chars[c].yOffset == 255)
+ return;
+
+ dst += _chars[c].yOffset * pitch;
+ dst += _chars[c].xOffset;
+
+ pitch -= _chars[c].graphics.width;
+
+ const uint8 *src = _chars[c].graphics.bitmap;
+ assert(src);
+
+ for (int y = 0; y < _chars[c].graphics.height; ++y) {
+ for (int x = 0; x < _chars[c].graphics.width; ++x) {
+ if (*src)
+ *dst = *src;
+ ++src;
+ ++dst;
+ }
+
+ dst += pitch;
+ }
+}
+
+void AMIGAFont::unload() {
+ _width = _height = 0;
+ for (int i = 0; i < ARRAYSIZE(_chars); ++i)
+ delete[] _chars[i].graphics.bitmap;
+ memset(_chars, 0, sizeof(_chars));
+}
+
+#pragma mark -
+
Palette::Palette(const int numColors) : _palData(0), _numColors(numColors) {
_palData = new uint8[numColors * 3];
assert(_palData);
@@ -3049,9 +3306,9 @@ void Palette::loadAmigaPalette(Common::ReadStream &stream, int startIndex, int c
for (int i = 0; i < colors; ++i) {
uint16 col = stream.readUint16BE();
- _palData[(i + startIndex) * 3 + 2] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
- _palData[(i + startIndex) * 3 + 1] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
- _palData[(i + startIndex) * 3 + 0] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
+ _palData[(i + startIndex) * 3 + 2] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4;
+ _palData[(i + startIndex) * 3 + 1] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4;
+ _palData[(i + startIndex) * 3 + 0] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4;
}
}
@@ -3061,9 +3318,9 @@ void Palette::loadPC98Palette(Common::ReadStream &stream, int startIndex, int co
for (int i = 0; i < colors; ++i) {
const byte g = stream.readByte(), r = stream.readByte(), b = stream.readByte();
- _palData[(i + startIndex) * 3 + 0] = ((r & 0x0F) * 0x3F) / 0x0F;
- _palData[(i + startIndex) * 3 + 1] = ((g & 0x0F) * 0x3F) / 0x0F;
- _palData[(i + startIndex) * 3 + 2] = ((b & 0x0F) * 0x3F) / 0x0F;
+ _palData[(i + startIndex) * 3 + 0] = ((r & 0xF) * 0x3F) / 0xF;
+ _palData[(i + startIndex) * 3 + 1] = ((g & 0xF) * 0x3F) / 0xF;
+ _palData[(i + startIndex) * 3 + 2] = ((b & 0xF) * 0x3F) / 0xF;
}
}
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index d8380d104d..73a29ee2c7 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -56,15 +56,114 @@ struct ScreenDim {
uint16 unkE;
};
-struct Font {
- uint8 *fontData;
- uint8 *charWidthTable;
- uint16 fontDescOffset;
- uint16 charBitmapOffset;
- uint16 charWidthTableOffset;
- uint16 charHeightTableOffset;
-
- uint8 lastGlyph;
+/**
+ * A class that handles KYRA fonts.
+ */
+class Font {
+public:
+ virtual ~Font() {}
+
+ /**
+ * Tries to load a file from the given stream
+ */
+ virtual bool load(Common::SeekableReadStream &file) = 0;
+
+ /**
+ * The font height.
+ */
+ virtual int getHeight() const = 0;
+
+ /**
+ * The font width, this is the maximal character
+ * width.
+ */
+ virtual int getWidth() const = 0;
+
+ /**
+ * Gets the width of a specific character.
+ */
+ virtual int getCharWidth(uint8 c) const = 0;
+
+ /**
+ * Sets a text palette map. The map contains 16 entries.
+ */
+ virtual void setColorMap(const uint8 *src) = 0;
+
+ /**
+ * Draws a specific character.
+ *
+ * TODO/FIXME: Replace this with a nicer API. Currently
+ * the user has to assure that the character fits.
+ * We use this API, since it's hard to assure dirty rect
+ * handling from outside Screen.
+ */
+ virtual void drawChar(uint8 c, byte *dst, int pitch) const = 0;
+};
+
+/**
+ * Implementation of the Font interface for DOS fonts.
+ *
+ * TODO: Clean up the implementation. For example we might be able
+ * to not to keep the whole font in memory.
+ */
+class DOSFont : public Font {
+public:
+ DOSFont();
+ ~DOSFont() { unload(); }
+
+ bool load(Common::SeekableReadStream &file);
+ int getHeight() const { return _height; }
+ int getWidth() const { return _width; }
+ int getCharWidth(uint8 c) const;
+ void setColorMap(const uint8 *src) { _colorMap = src; }
+ void drawChar(uint8 c, byte *dst, int pitch) const;
+
+private:
+ void unload();
+
+ const uint8 *_colorMap;
+
+ uint8 *_data;
+
+ int _width, _height;
+
+ uint8 _numGlyphs;
+
+ uint8 *_widthTable;
+ uint8 *_heightTable;
+ uint16 *_bitmapOffsets;
+};
+
+/**
+ * Implementation of the Font interface for AMIGA fonts.
+ */
+class AMIGAFont : public Font {
+public:
+ AMIGAFont();
+ ~AMIGAFont() { unload(); }
+
+ bool load(Common::SeekableReadStream &file);
+ int getHeight() const { return _height; }
+ int getWidth() const { return _width; }
+ int getCharWidth(uint8 c) const;
+ void setColorMap(const uint8 *src) {}
+ void drawChar(uint8 c, byte *dst, int pitch) const;
+
+private:
+ void unload();
+
+ int _width, _height;
+
+ struct Character {
+ uint8 yOffset, xOffset, width;
+
+ struct Graphics {
+ uint16 width, height;
+ uint8 *bitmap;
+ } graphics;
+ };
+
+ Character _chars[255];
};
/**
@@ -256,6 +355,11 @@ public:
void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue);
virtual void setScreenPalette(const Palette &pal);
+ // AMIGA version only
+ bool isInterfacePaletteEnabled() const { return _interfacePaletteEnabled; }
+ void enableInterfacePalette(bool e);
+ void setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b);
+
void getRealPalette(int num, uint8 *dst);
Palette &getPalette(int num);
void copyPalette(const int dst, const int src);
@@ -342,12 +446,13 @@ public:
static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);
static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch, bool noXor);
- static void convertAmigaGfx(uint8 *data, int w, int h, bool offscreen = true);
+ static void convertAmigaGfx(uint8 *data, int w, int h, int depth = 5, bool wsa = false, int bytesPerPlane = -1);
static void convertAmigaMsc(uint8 *data);
protected:
uint8 *getPagePtr(int pageNum);
void updateDirtyRects();
+ void updateDirtyRectsAmiga();
void updateDirtyRectsOvl();
void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
@@ -374,6 +479,7 @@ protected:
bool _useOverlays;
bool _useSJIS;
bool _use16ColorMode;
+ bool _isAmiga;
Graphics::FontSJIS *_sjisFont;
uint8 _sjisInvisibleColor;
@@ -382,7 +488,7 @@ protected:
Common::Array<Palette *> _palettes;
Palette *_internFadePalette;
- Font _fonts[FID_NUM];
+ Font *_fonts[FID_NUM];
uint8 _textColorsMap[16];
uint8 *_decodeShapeBuffer;
@@ -469,6 +575,9 @@ protected:
int _drawShapeVar4;
int _drawShapeVar5;
+ // AMIGA version
+ bool _interfacePaletteEnabled;
+
// debug
bool _debugEnabled;
};
diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp
index 9fdeae1398..ed7bef0178 100644
--- a/engines/kyra/screen_lok.cpp
+++ b/engines/kyra/screen_lok.cpp
@@ -80,6 +80,9 @@ const ScreenDim *Screen_LoK::getScreenDim(int dim) {
}
void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return;
+
assert(_vm->palTable1()[palIndex]);
Palette tempPal(getPalette(0).getNumColors());
@@ -240,6 +243,22 @@ int Screen_LoK::getRectSize(int x, int y) {
return ((x*y) << 3);
}
+void Screen_LoK::postProcessCursor(uint8 *data, int width, int height, int pitch) {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga && _interfacePaletteEnabled) {
+ pitch -= width;
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ if (*data != _cursorColorKey)
+ *data += 32;
+ ++data;
+ }
+
+ data += pitch;
+ }
+ }
+}
+
#pragma mark -
Screen_LoK_16::Screen_LoK_16(KyraEngine_LoK *vm, OSystem *system) : Screen_LoK(vm, system) {
diff --git a/engines/kyra/screen_lok.h b/engines/kyra/screen_lok.h
index 4eb22df374..ae1d85c0a7 100644
--- a/engines/kyra/screen_lok.h
+++ b/engines/kyra/screen_lok.h
@@ -59,6 +59,9 @@ public:
void addBitBlitRect(int x, int y, int w, int h);
void bitBlitRects();
+ // AMIGA specific
+ virtual void postProcessCursor(uint8 *data, int width, int height, int pitch);
+
protected:
enum {
kNumBitBlitRects = 10
diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp
index 849c6b776d..a778a2066b 100644
--- a/engines/kyra/script_lok.cpp
+++ b/engines/kyra/script_lok.cpp
@@ -231,12 +231,13 @@ int KyraEngine_LoK::o1_fadeSpecialPalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
if (_currentCharacter->sceneId != 45) {
if (stackPos(0) == 13) {
- // TODO: Check this!
_screen->copyPalette(0, 12);
_screen->setScreenPalette(_screen->getPalette(0));
}
} else {
- warning("KyraEngine_LoK::o1_fadeSpecialPalette not implemented");
+ setupZanthiaPalette(stackPos(0));
+ _screen->getPalette(0).copy(_screen->getPalette(4), 12, 1);
+ _screen->fadePalette(_screen->getPalette(0), 2);
}
} else {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
@@ -579,7 +580,17 @@ int KyraEngine_LoK::o1_restoreAllObjectBackgrounds(EMCState *script) {
int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
- _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1));
+ if (_flags.platform == Common::kPlatformAmiga) {
+ if (_currentCharacter->sceneId == 45) {
+ setupZanthiaPalette(stackPos(0));
+ } else if (stackPos(0) == 29) {
+ _screen->copyPalette(0, 11);
+ } else if (stackPos(0) == 13) {
+ _screen->copyPalette(0, 12);
+ }
+ } else {
+ _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1));
+ }
return 0;
}
@@ -1081,7 +1092,9 @@ int KyraEngine_LoK::o1_specialEventDisplayBrynnsNote(EMCState *script) {
_screen->copyRegion(63, 8, 63, 8, 194, 128, 2, 0);
_screen->updateScreen();
_screen->showMouse();
- _screen->setFont(Screen::FID_6_FNT);
+
+ if (_flags.platform != Common::kPlatformAmiga && !_flags.isTalkie)
+ _screen->setFont(Screen::FID_6_FNT);
return 0;
}
@@ -1092,7 +1105,9 @@ int KyraEngine_LoK::o1_specialEventRemoveBrynnsNote(EMCState *script) {
_screen->loadPageFromDisk("HIDPAGE.TMP", 2);
_screen->updateScreen();
_screen->showMouse();
- _screen->setFont(Screen::FID_8_FNT);
+
+ if (_flags.platform != Common::kPlatformAmiga && !_flags.isTalkie)
+ _screen->setFont(Screen::FID_8_FNT);
return 0;
}
@@ -1213,37 +1228,77 @@ int KyraEngine_LoK::o1_findBrightestFireberry(EMCState *script) {
int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0));
- int palIndex = 0;
- switch (stackPos(0)) {
- case 0x1E:
- palIndex = 9;
- break;
- case 0x1F:
- palIndex = 10;
- break;
+ if (_flags.platform == Common::kPlatformAmiga) {
+ int palIndex = 0;
+
+ switch (stackPos(0)) {
+ case -1:
+ // The original seemed to draw some lines on page 2 here, which looks strange...
+ //if (!(_brandonStatusBit & 2))
+ // warning("Unimplemented case for o1_setFireberryGlowPalette");
+ palIndex = 9;
+ break;
- case 0x20:
- palIndex = 11;
- break;
+ case 30:
+ palIndex = 7;
+ break;
- case 0x21:
- case -1:
- palIndex = 12;
- break;
+ case 31:
+ palIndex = 8;
+ break;
- default:
- palIndex = 8;
- }
- if (_brandonStatusBit & 2) {
- if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 &&
- _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 &&
- (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) {
- palIndex = 14;
+ case 32:
+ case 33:
+ palIndex = 9;
+ break;
+
+ case 28: case 29: default:
+ palIndex = 6;
+ }
+
+ if (_brandonStatusBit & 2) {
+ if (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)
+ palIndex = 10;
}
+
+ _screen->copyPalette(0, palIndex);
+ } else {
+ int palIndex = 0;
+
+ switch (stackPos(0)) {
+ case 0x1E:
+ palIndex = 9;
+ break;
+
+ case 0x1F:
+ palIndex = 10;
+ break;
+
+ case 0x20:
+ palIndex = 11;
+ break;
+
+ case 0x21:
+ case -1:
+ palIndex = 12;
+ break;
+
+ default:
+ palIndex = 8;
+ }
+
+ if (_brandonStatusBit & 2) {
+ if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 &&
+ _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 &&
+ (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) {
+ palIndex = 14;
+ }
+ }
+
+ _screen->getPalette(1).copy(_specialPalettes[palIndex], 0, 15, 228);
}
- _screen->getPalette(1).copy(_specialPalettes[palIndex], 0, 15, 228);
return 0;
}
@@ -1255,9 +1310,11 @@ int KyraEngine_LoK::o1_drinkPotionAnimation(EMCState *script) {
int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_makeAmuletAppear(%p) ()", (const void *)script);
- WSAMovie_v1 amulet(this);
- amulet.open("AMULET.WSA", 1, 0);
- if (amulet.opened()) {
+ Movie *amulet = createWSAMovie();
+ assert(amulet);
+ amulet->open("AMULET.WSA", 1, 0);
+
+ if (amulet->opened()) {
assert(_amuleteAnim);
_screen->hideMouse();
snd_playSoundEffect(0x70);
@@ -1275,7 +1332,7 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) {
if (code == 14)
snd_playSoundEffect(0x73);
- amulet.displayFrame(code, 0, 224, 152, 0, 0, 0);
+ amulet->displayFrame(code, 0, 224, 152, 0, 0, 0);
_animator->_updateScreen = true;
while (_system->getMillis() < nextTime) {
@@ -1287,6 +1344,8 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) {
}
_screen->showMouse();
}
+
+ delete amulet;
setGameFlag(0x2D);
return 0;
}
@@ -1335,7 +1394,7 @@ int KyraEngine_LoK::o1_waitForConfirmationMouseClick(EMCState *script) {
updateInput();
- int input = checkInput(_buttonList, false) & 0xFF;
+ int input = checkInput(0, false) & 0xFF;
removeInputTop();
if (input == 200)
break;
diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp
index aeac4ce9df..4086d06c00 100644
--- a/engines/kyra/seqplayer.cpp
+++ b/engines/kyra/seqplayer.cpp
@@ -389,7 +389,8 @@ void SeqPlayer::s1_copyRegionSpecial() {
const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2;
const int y = 179;
_screen->setTextColorMap(colorMap);
- _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC);
_screen->printText(copyStr, x, y, 0xF, 0xC);
}
break;
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index b5ae7a50ec..206f8f0a87 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -555,7 +555,9 @@ void KyraEngine_LoK::seq_winterScroll1() {
_animator->sprites()[0].active = 0;
_sprites->_anims[1].play = true;
_animator->sprites()[1].active = 1;
- setGameFlag(0xA2);
+
+ if (_flags.platform != Common::kPlatformAmiga)
+ setGameFlag(0xA2);
}
for (int i = midpoint; i < 123 + numFrames; ++i) {
@@ -569,10 +571,15 @@ void KyraEngine_LoK::seq_winterScroll1() {
_sprites->_anims[i].play = false;
_animator->sprites()[i].active = 0;
}
- _screen->getPalette(0).copy(palTable2()[0], 0, 20, 228);
- _screen->fadePalette(_screen->getPalette(0), 72);
- _screen->setScreenPalette(_screen->getPalette(0));
- setGameFlag(0xB3);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
+ _screen->copyPalette(0, 11);
+ } else {
+ _screen->getPalette(0).copy(palTable2()[0], 0, 20, 228);
+ _screen->fadePalette(_screen->getPalette(0), 72);
+ _screen->setScreenPalette(_screen->getPalette(0));
+ setGameFlag(0xB3);
+ }
} else {
delayWithTicks(120);
}
@@ -673,7 +680,7 @@ void KyraEngine_LoK::seq_makeBrandonNormal2() {
_animator->animRefreshNPC(0);
delayWithTicks(8);
}
- _animator->setBrandonAnimSeqSize(4, 48);
+ _animator->setBrandonAnimSeqSize(3, 48);
_currentCharacter->currentAnimFrame = 7;
_animator->animRefreshNPC(0);
@@ -718,10 +725,16 @@ void KyraEngine_LoK::seq_makeBrandonWisp() {
_animator->animRefreshNPC(0);
_animator->updateAllObjectShapes();
- if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245)
- _screen->fadeSpecialPalette(30, 234, 13, 4);
- else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186)
- _screen->fadeSpecialPalette(14, 228, 15, 4);
+ if (_flags.platform == Common::kPlatformAmiga) {
+ if ((_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) ||
+ (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186))
+ _screen->fadePalette(_screen->getPalette(10), 0x54);
+ } else {
+ if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245)
+ _screen->fadeSpecialPalette(30, 234, 13, 4);
+ else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186)
+ _screen->fadeSpecialPalette(14, 228, 15, 4);
+ }
freeShapes123();
_screen->showMouse();
@@ -770,6 +783,7 @@ void KyraEngine_LoK::seq_dispelMagicAnimation() {
void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) {
int newItem = -1;
+
static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C };
static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D };
@@ -791,63 +805,135 @@ void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) {
setMouseItem(newItem);
_screen->showMouse();
_itemInHand = newItem;
+
assert(_fullFlask);
assert(type < _fullFlask_Size && type >= 0);
+
static const uint16 voiceEntries[] = {
0x1F40, 0x1F41, 0x1F42, 0x1F45
};
assert(type < ARRAYSIZE(voiceEntries));
+
characterSays(voiceEntries[type], _fullFlask[type], 0, -2);
}
void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) {
- uint8 red, green, blue;
+ if (_flags.platform == Common::kPlatformAmiga) {
+ uint8 r, g, b;
+
+ switch (item) {
+ case 60: case 61:
+ // 0xC22
+ r = 50;
+ g = 8;
+ b = 8;
+ break;
- switch (item) {
- case 60:
- case 61:
- red = 63;
- green = blue = 6;
- break;
- case 62:
- case 63:
- red = green = 0;
- blue = 67;
- break;
- case 64:
- case 65:
- red = 84;
- green = 78;
- blue = 14;
- break;
- case 66:
- red = blue = 0;
- green = 48;
- break;
- case 67:
- red = 100;
- green = 48;
- blue = 23;
- break;
- case 68:
- red = 73;
- green = 0;
- blue = 89;
- break;
- case 69:
- red = green = 73;
- blue = 86;
- break;
- default:
- red = 33;
- green = 66;
- blue = 100;
- }
- red = (uint8)((double)red * 0.63);
- green = (uint8)((double)green * 0.63);
- blue = (uint8)((double)blue * 0.63);
+ case 62: case 63: case 76:
+ case 77:
+ // 0x00E
+ r = 0;
+ g = 0;
+ b = 58;
+ break;
+
+ case 64: case 65:
+ // 0xFF5
+ r = 63;
+ g = 63;
+ b = 21;
+ break;
+
+ case 66:
+ // 0x090
+ r = 0;
+ g = 37;
+ b = 0;
+ break;
+
+ case 67:
+ // 0xC61
+ r = 50;
+ g = 25;
+ b = 4;
+ break;
+
+ case 68:
+ // 0xE2E
+ r = 58;
+ g = 8;
+ b = 58;
+ break;
+
+ case 69:
+ // 0xBBB
+ r = 46;
+ g = 46;
+ b = 46;
+ break;
+
+ default:
+ // 0xFFF
+ r = 63;
+ g = 63;
+ b = 63;
+ }
+
+ _screen->setPaletteIndex(16, r, g, b);
+ } else {
+ uint8 red, green, blue;
+
+ switch (item) {
+ case 60: case 61:
+ red = 63;
+ green = blue = 6;
+ break;
+
+ case 62: case 63:
+ red = green = 0;
+ blue = 67;
+ break;
+
+ case 64: case 65:
+ red = 84;
+ green = 78;
+ blue = 14;
+ break;
+
+ case 66:
+ red = blue = 0;
+ green = 48;
+ break;
+
+ case 67:
+ red = 100;
+ green = 48;
+ blue = 23;
+ break;
+
+ case 68:
+ red = 73;
+ green = 0;
+ blue = 89;
+ break;
- _screen->setPaletteIndex(0xFE, red, green, blue);
+ case 69:
+ red = green = 73;
+ blue = 86;
+ break;
+
+ default:
+ red = 33;
+ green = 66;
+ blue = 100;
+ }
+
+ red = red * 0x3F / 100;
+ green = green * 0x3F / 100;
+ blue = blue * 0x3F / 100;
+
+ _screen->setPaletteIndex(0xFE, red, green, blue);
+ }
_screen->hideMouse();
checkAmuletAnimFlags();
@@ -862,7 +948,9 @@ void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) {
_animator->animRefreshNPC(0);
delayWithTicks(5);
}
+
snd_playSoundEffect(0x34);
+
for (int i = 0; i < 2; ++i) {
_currentCharacter->currentAnimFrame = 130;
_animator->animRefreshNPC(0);
@@ -886,7 +974,10 @@ void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) {
_currentCharacter->currentAnimFrame = 7;
_animator->animRefreshNPC(0);
freeShapes123();
- _screen->setPaletteIndex(0xFE, 30, 30, 30);
+
+ if (_flags.platform != Common::kPlatformAmiga)
+ _screen->setPaletteIndex(0xFE, 30, 30, 30);
+
_screen->showMouse();
}
@@ -901,20 +992,25 @@ int KyraEngine_LoK::seq_playEnd() {
if (_endSequenceNeedLoading) {
snd_playWanderScoreViaMap(50, 1);
setupPanPages();
- _finalA = new WSAMovie_v1(this);
+
+ _finalA = createWSAMovie();
assert(_finalA);
_finalA->open("finala.wsa", 1, 0);
- _finalB = new WSAMovie_v1(this);
+
+ _finalB = createWSAMovie();
assert(_finalB);
_finalB->open("finalb.wsa", 1, 0);
- _finalC = new WSAMovie_v1(this);
+
+ _finalC = createWSAMovie();
assert(_finalC);
_endSequenceNeedLoading = 0;
_finalC->open("finalc.wsa", 1, 0);
+
_screen->_curPage = 0;
_beadStateVar = 0;
_malcolmFlag = 0;
_unkEndSeqVar2 = _system->getMillis() + 600 * _tickLength;
+
_screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2);
}
@@ -943,17 +1039,25 @@ int KyraEngine_LoK::seq_playEnd() {
_endSequenceSkipFlag = 1;
if (_text->printed())
_text->restoreTalkTextMessageBkgd(2, 0);
+
_screen->_curPage = 0;
_screen->hideMouse();
- _screen->fadeSpecialPalette(32, 228, 20, 60);
+
+ if (_flags.platform != Common::kPlatformAmiga)
+ _screen->fadeSpecialPalette(32, 228, 20, 60);
+
delay(60 * _tickLength);
+
_screen->loadBitmap("GEMHEAL.CPS", 3, 3, &_screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
_screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0);
+
uint32 nextTime = _system->getMillis() + 120 * _tickLength;
- _finalA = new WSAMovie_v1(this);
+
+ _finalA = createWSAMovie();
assert(_finalA);
_finalA->open("finald.wsa", 1, 0);
+
delayUntil(nextTime);
snd_playSoundEffect(0x40);
for (int i = 0; i < 22; ++i) {
@@ -967,6 +1071,7 @@ int KyraEngine_LoK::seq_playEnd() {
_screen->updateScreen();
}
delete _finalA;
+
_finalA = 0;
seq_playEnding();
return 1;
@@ -985,11 +1090,13 @@ void KyraEngine_LoK::seq_brandonToStone() {
assert(_brandonStoneTable);
setupShapes123(_brandonStoneTable, 14, 0);
_animator->setBrandonAnimSeqSize(5, 51);
+
for (int i = 123; i <= 136; ++i) {
_currentCharacter->currentAnimFrame = i;
_animator->animRefreshNPC(0);
delayWithTicks(8);
}
+
_animator->resetBrandonAnimSeqSize();
freeShapes123();
_screen->showMouse();
@@ -1001,8 +1108,17 @@ void KyraEngine_LoK::seq_playEnding() {
_screen->hideMouse();
_screen->_curPage = 0;
_screen->fadeToBlack();
- _screen->loadBitmap("REUNION.CPS", 3, 3, &_screen->getPalette(0));
- _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
+ _screen->loadBitmap("GEMCUT.CPS", 3, 3, &_screen->getPalette(0));
+ _screen->copyRegion(232, 136, 176, 56, 56, 56, 2, 2);
+ _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
+ } else {
+ _screen->loadBitmap("REUNION.CPS", 3, 3, &_screen->getPalette(0));
+ _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+ }
+
_screen->_curPage = 0;
// XXX
assert(_homeString);
@@ -1035,8 +1151,10 @@ void KyraEngine_LoK::seq_playCredits() {
memset(strings, 0, sizeof(strings));
+ _screen->enableInterfacePalette(false);
+
_screen->hideMouse();
- if (!_flags.isTalkie) {
+ if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga) {
_screen->loadFont(Screen::FID_CRED6_FNT, "CREDIT6.FNT");
_screen->loadFont(Screen::FID_CRED8_FNT, "CREDIT8.FNT");
} else
@@ -1056,7 +1174,8 @@ void KyraEngine_LoK::seq_playCredits() {
uint8 *buffer = 0;
uint32 size = 0;
- if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) {
+ if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98
+ || _flags.platform == Common::kPlatformAmiga) {
int sizeTmp = 0;
const uint8 *bufferTmp = _staticres->loadRawData(k1CreditsStrings, sizeTmp);
buffer = new uint8[sizeTmp];
@@ -1094,12 +1213,12 @@ void KyraEngine_LoK::seq_playCredits() {
if (*currentString == 1) {
currentString++;
- if (!_flags.isTalkie)
+ if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga)
_screen->setFont(Screen::FID_CRED6_FNT);
} else {
if (*currentString == 2)
currentString++;
- if (!_flags.isTalkie)
+ if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga)
_screen->setFont(Screen::FID_CRED8_FNT);
}
strings[i].font = _screen->_currentFont;
@@ -1122,6 +1241,9 @@ void KyraEngine_LoK::seq_playCredits() {
_screen->getPalette(2).clear();
_screen->setScreenPalette(_screen->getPalette(2));
+ if (_flags.platform == Common::kPlatformAmiga)
+ _screen->setPaletteIndex(16, 63, 63, 63);
+
_screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 0, Screen::CR_NO_P_CHECK);
_screen->fadePalette(_screen->getPalette(0), 0x5A);
@@ -1473,7 +1595,7 @@ int KyraEngine_LoK::handleBeadState() {
_beadStateVar = 0;
}
} else {
- _screen->copyBlockToPage(_screen->_curPage, beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
beadState1.x = x;
beadState1.y = y;
@@ -1663,6 +1785,14 @@ void KyraEngine_LoK::closeFinalWsa() {
}
void KyraEngine_LoK::updateKyragemFading() {
+ if (_flags.platform == Common::kPlatformAmiga) {
+ // The AMIGA version seems to have no fading for the Kyragem. The code does not
+ // alter the screen palette.
+ //
+ // TODO: Check this in the original.
+ return;
+ }
+
static const uint8 kyraGemPalette[0x28] = {
0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22,
0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03,
@@ -1674,14 +1804,17 @@ void KyraEngine_LoK::updateKyragemFading() {
return;
_kyragemFadingState.timerCount = _system->getMillis() + 4 * _tickLength;
+
int palPos = 684;
for (int i = 0; i < 20; ++i) {
_screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset];
_screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset];
_screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset];
}
+
_screen->setScreenPalette(_screen->getPalette(0));
_animator->_updateScreen = true;
+
switch (_kyragemFadingState.nextOperation) {
case 0:
--_kyragemFadingState.bOffset;
diff --git a/engines/kyra/sound_amiga.cpp b/engines/kyra/sound_amiga.cpp
index 3d552fda0e..6c4c2b19a5 100644
--- a/engines/kyra/sound_amiga.cpp
+++ b/engines/kyra/sound_amiga.cpp
@@ -156,8 +156,8 @@ void SoundAmiga::playTrack(uint8 track) {
case kFileGame:
if (track >= 11 && track < ARRAYSIZE(tempoIngame) + 11) {
score = track - 11;
- loop = loopIngame[track] != 0;
- tempo = tempoIngame[track];
+ loop = loopIngame[score] != 0;
+ tempo = tempoIngame[score];
}
break;
diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp
index f644feeb65..9877ceebc4 100644
--- a/engines/kyra/sprites_lol.cpp
+++ b/engines/kyra/sprites_lol.cpp
@@ -496,9 +496,8 @@ int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int
_monsterCurBlock = block;
if (testWallFlag(block, -1, wallFlag))
return 1;
- }
-
- _monsterCurBlock = 0;
+ _monsterCurBlock = 0;
+ }
if (!(testFlag & 2))
return 0;
@@ -1372,12 +1371,12 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 };
static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 };
- if (++_monsterCountUnk > 10) {
- _monsterCountUnk = 0;
- _monsterShiftAlt ^= 1;
+ if (++_monsterStepCounter > 10) {
+ _monsterStepCounter = 0;
+ _monsterStepMode ^= 1;
}
- const int8 *tbl = _monsterShiftAlt ? walkMonsterTable2 : walkMonsterTable1;
+ const int8 *tbl = _monsterStepMode ? walkMonsterTable2 : walkMonsterTable1;
int sx = monster->x;
int sy = monster->y;
@@ -1411,8 +1410,10 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
uint8 w = _levelBlockProperties[_monsterCurBlock].walls[(s >> 1) ^ 2];
if (_wllWallFlags[w] & 0x20) {
- if (_wllBuffer3[w] == 5)
+ if (_wllBuffer3[w] == 5) {
openCloseDoor(_monsterCurBlock, 1);
+ return -1;
+ }
}
if (_wllWallFlags[w] & 8)
@@ -1423,10 +1424,10 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
}
int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {
- int8 b1x = block1 & 0x1f;
- int8 b1y = block1 >> 5;
- int8 b2x = block2 & 0x1f;
- int8 b2y = block2 >> 5;
+ int b1x = block1 & 0x1f;
+ int b1y = block1 >> 5;
+ int b2x = block2 & 0x1f;
+ int b2y = block2 >> 5;
uint8 dy = ABS(b2y - b1y);
uint8 dx = ABS(b2x - b1x);
@@ -1434,7 +1435,7 @@ int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {
if (dx > dy)
SWAP(dx, dy);
- return (dx << 1) + dy;
+ return (dx >> 1) + dy;
}
int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock) {
@@ -1444,7 +1445,7 @@ int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction
return 5;
int dir = calcMonsterDirection(monsterBlock & 0x1f, monsterBlock >> 5, curBlock & 0x1f, curBlock >> 5);
- if ((dir & 1) || (dir != direction << 1))
+ if ((dir & 1) || (dir != (direction << 1)))
return 5;
if (((monsterBlock & 0x1f) != (curBlock & 0x1f)) && ((monsterBlock & 0xffe0) != (curBlock & 0xffe0)))
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index c7bef26d61..83f4b22b6d 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -44,7 +44,7 @@
namespace Kyra {
-#define RESFILE_VERSION 48
+#define RESFILE_VERSION 49
namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
@@ -1598,10 +1598,15 @@ void KyraEngine_LoK::loadMainScreen(int page) {
else
warning("no main graphics file found");
- if (_flags.platform == Common::kPlatformAmiga)
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0, Screen::CR_NO_P_CHECK);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
_screen->copyPalette(1, 0);
+ _screen->setInterfacePalette(_screen->getPalette(1), 0x3F, 0x3F, 0x3F);
- _screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0);
+ // TODO: Move this to a better place
+ _screen->enableInterfacePalette(true);
+ }
}
void KyraEngine_HoF::initStaticResource() {
@@ -2249,6 +2254,22 @@ void GUI_LoK::initStaticResource() {
_menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeWalk);
_menu[5].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeText);
_menu[5].item[5].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsApply);
+
+ // The AMIGA version uses different colors, due to its 32 color nature. We did setup the 256 color version
+ // colors above, so we need to overwrite those with the correct values over here.
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ for (int i = 0; i < 6; ++i) {
+ _menu[i].bkgdColor = 17;
+ _menu[i].color1 = 31;
+ _menu[i].color2 = 18;
+
+ for (int j = 0; j < _menu[i].numberOfItems; ++j) {
+ _menu[i].item[j].bkgdColor = 17;
+ _menu[i].item[j].color1 = 31;
+ _menu[i].item[j].color2 = 18;
+ }
+ }
+ }
}
void KyraEngine_LoK::setupButtonData() {
diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp
index 4d511eae01..20094a45ab 100644
--- a/engines/kyra/text.cpp
+++ b/engines/kyra/text.cpp
@@ -179,7 +179,7 @@ void TextDisplayer::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
void TextDisplayer::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
if (_talkMessagePrinted) {
_talkMessagePrinted = false;
- _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
+ _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK);
}
}
@@ -200,37 +200,15 @@ void TextDisplayer::printTalkTextMessage(const char *text, int x, int y, uint8 c
_screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK);
int curPage = _screen->_curPage;
_screen->_curPage = srcPage;
- for (int i = 0; i < lineCount; ++i) {
- top = i * 10 + _talkMessageY;
- char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
- int left = getCenterStringX(msg, x1, x2);
- printText(msg, left, top, color, 0xC, 0);
- }
- _screen->_curPage = curPage;
- _talkMessagePrinted = true;
-}
-void TextDisplayer::printIntroTextMessage(const char *text, int x, int y, uint8 col1, uint8 col2, uint8 col3, int dstPage, Screen::FontId font) {
- char *str = preprocessString(text);
- int lineCount = buildMessageSubstrings(str);
- int top = y - lineCount * 10;
- if (top < 0) {
- top = 0;
- }
- _talkMessageY = top;
- _talkMessageH = lineCount * 10;
- int w = getWidestLineWidth(lineCount);
- int x1, x2;
- calcWidestLineBounds(x1, x2, w, x);
- _talkCoords.x = x1;
- _talkCoords.w = w + 2;
- int curPage = _screen->setCurPage(dstPage);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ setTextColor(color);
for (int i = 0; i < lineCount; ++i) {
top = i * 10 + _talkMessageY;
char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
int left = getCenterStringX(msg, x1, x2);
- printText(msg, left, top, col1, col2, col3, font);
+ printText(msg, left, top, color, 0xC, 0);
}
_screen->_curPage = curPage;
_talkMessagePrinted = true;
@@ -248,7 +226,7 @@ void TextDisplayer::printText(const char *str, int x, int y, uint8 c0, uint8 c1,
}
void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX) {
- uint8 colorTable[] = {0x0F, 0x9, 0x0C9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
+ uint8 colorTable[] = {0x0F, 0x09, 0xC9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
int top, left, x1, x2, w, x;
char *msg;
@@ -259,6 +237,9 @@ void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX
x = charX;
calcWidestLineBounds(x1, x2, w, x);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ setTextColor(color);
+
for (int i = 0; i < lineCount; ++i) {
top = i * 10 + _talkMessageY;
msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
@@ -266,4 +247,91 @@ void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX
printText(msg, left, top, color, 0xC, 0);
}
}
+
+void TextDisplayer::setTextColor(uint8 color) {
+ byte r, g, b;
+
+ switch (color) {
+ case 4:
+ // 0x09E
+ r = 0;
+ g = 37;
+ b = 58;
+ break;
+
+ case 5:
+ // 0xFF5
+ r = 63;
+ g = 63;
+ b = 21;
+ break;
+
+ case 27:
+ // 0x5FF
+ r = 21;
+ g = 63;
+ b = 63;
+ break;
+
+ case 34:
+ // 0x8E5
+ r = 33;
+ g = 58;
+ b = 21;
+ break;
+
+ case 58:
+ // 0x9FB
+ r = 37;
+ g = 63;
+ b = 46;
+ break;
+
+ case 85:
+ // 0x7CF
+ r = 29;
+ g = 50;
+ b = 63;
+ break;
+
+ case 114:
+ case 117:
+ // 0xFAF
+ r = 63;
+ g = 42;
+ b = 63;
+ break;
+
+ case 128:
+ case 129:
+ // 0xFCC
+ r = 63;
+ g = 50;
+ b = 50;
+ break;
+
+ case 201:
+ // 0xFD8
+ r = 63;
+ g = 54;
+ b = 33;
+ break;
+
+ case 216:
+ // 0xFC6
+ r = 63;
+ g = 50;
+ b = 25;
+ break;
+
+ default:
+ // 0xEEE
+ r = 58;
+ g = 58;
+ b = 58;
+ }
+
+ _screen->setPaletteIndex(0x10, r, g, b);
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/text.h b/engines/kyra/text.h
index d45e5f9242..73d77dcb4c 100644
--- a/engines/kyra/text.h
+++ b/engines/kyra/text.h
@@ -50,8 +50,6 @@ public:
virtual void calcWidestLineBounds(int &x1, int &x2, int w, int cx);
virtual void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage);
- void printIntroTextMessage(const char *text, int x, int y, uint8 col1, uint8 col2, uint8 col3,
- int dstPage, Screen::FontId font=Screen::FID_8_FNT);
virtual void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT);
void printCharacterText(const char *text, int8 charNum, int charX);
@@ -66,6 +64,9 @@ protected:
uint16 y, x, w;
};
+ // TODO: AMIGA and LoK specific, move to a better location
+ void setTextColor(uint8 color);
+
enum {
TALK_SUBSTRING_LEN = 80,
TALK_SUBSTRING_NUM = 6
@@ -76,6 +77,7 @@ protected:
TalkCoords _talkCoords;
bool _talkMessagePrinted;
};
+
} // end of namespace Kyra
#endif
diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp
index 3f4bfb65ac..d2128b7037 100644
--- a/engines/kyra/text_lok.cpp
+++ b/engines/kyra/text_lok.cpp
@@ -322,18 +322,27 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu
void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) {
_screen->hideMouse();
- _screen->fillRect(8, 143, 311, 152, 12);
+ _screen->fillRect(8, 143, 311, 152, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
- if (_startSentencePalIndex != color || _fadeText != false) {
- _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3];
+ if (_flags.platform == Common::kPlatformAmiga) {
+ if (color != 19) {
+ _currSentenceColor[0] = 0x3F;
+ _currSentenceColor[1] = 0x3F;
+ _currSentenceColor[2] = 0x3F;
+
+ _screen->setInterfacePalette(_screen->getPalette(1),
+ _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
+ }
+ } else if (_startSentencePalIndex != color || _fadeText != false) {
+ _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3+0];
_currSentenceColor[1] = _screen->getPalette(0)[766] = _screen->getPalette(0)[color*3+1];
_currSentenceColor[2] = _screen->getPalette(0)[767] = _screen->getPalette(0)[color*3+2];
_screen->setScreenPalette(_screen->getPalette(0));
- _startSentencePalIndex = 0;
+ _startSentencePalIndex = color;
}
- _text->printText(sentence, 8, 143, 0xFF, 12, 0);
+ _text->printText(sentence, 8, 143, 0xFF, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
_screen->showMouse();
setTextFadeTimerCountdown(15);
_fadeText = false;
@@ -364,10 +373,15 @@ void KyraEngine_LoK::updateTextFade() {
}
}
- _screen->getPalette(0)[765] = _currSentenceColor[0];
- _screen->getPalette(0)[766] = _currSentenceColor[1];
- _screen->getPalette(0)[767] = _currSentenceColor[2];
- _screen->setScreenPalette(_screen->getPalette(0));
+ if (_flags.platform == Common::kPlatformAmiga) {
+ _screen->setInterfacePalette(_screen->getPalette(1),
+ _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
+ } else {
+ _screen->getPalette(0)[765] = _currSentenceColor[0];
+ _screen->getPalette(0)[766] = _currSentenceColor[1];
+ _screen->getPalette(0)[767] = _currSentenceColor[2];
+ _screen->setScreenPalette(_screen->getPalette(0));
+ }
if (finished) {
_fadeText = false;
diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp
index ef3fd1a966..b221f869b7 100644
--- a/engines/kyra/wsamovie.cpp
+++ b/engines/kyra/wsamovie.cpp
@@ -75,11 +75,10 @@ int WSAMovie_v1::open(const char *filename, int offscreenDecode, Palette *palBuf
}
if (_numFrames & 0x8000) {
- // This is used in the Amiga version, the wsa playing code
- // doesn't include any handling of it though, so we disable
- // this warning for now.
- //warning("Unhandled wsa flags 0x80");
- _flags |= 0x80;
+ // This is used in the Amiga version.
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ warning("Unhandled wsa flags 0x8000");
+ _flags |= WF_FLIPPED;
_numFrames &= 0x7FFF;
}
_currentFrame = _numFrames;
@@ -262,7 +261,7 @@ void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, uint16
if (_currentFrame == _numFrames) {
if (!(_flags & WF_NO_FIRST_FRAME)) {
Screen::decodeFrameDelta(dst, _deltaBuffer, true);
- Screen::convertAmigaGfx(dst, _width, _height);
+ Screen::convertAmigaGfx(dst, _width, _height, 5, (_flags & WF_FLIPPED) != 0);
if (_flags & WF_OFFSCREEN_DECODE) {
dst = _offscreenBuffer;
@@ -341,7 +340,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
const uint8 *src = _frameData + _frameOffsTable[frameNum];
Screen::decodeFrame4(src, _deltaBuffer, _deltaBufferSize);
Screen::decodeFrameDelta(dst, _deltaBuffer, true);
- Screen::convertAmigaGfx(dst, _width, _height);
+ Screen::convertAmigaGfx(dst, _width, _height, 5, (_flags & WF_FLIPPED) != 0);
src = dst;
dst = 0;
diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h
index 49ac5a28fe..957ee386ef 100644
--- a/engines/kyra/wsamovie.h
+++ b/engines/kyra/wsamovie.h
@@ -85,6 +85,7 @@ public:
WF_OFFSCREEN_DECODE = 0x10,
WF_NO_LAST_FRAME = 0x20,
WF_NO_FIRST_FRAME = 0x40,
+ WF_FLIPPED = 0x80,
WF_HAS_PALETTE = 0x100,
WF_XOR = 0x200
};
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 2ddc6979c9..eacae8e697 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -120,8 +120,11 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
#endif
// Segments
DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
+ DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
DCmd_Register("segment_info", WRAP_METHOD(Console, cmdSegmentInfo));
+ DCmd_Register("seginfo", WRAP_METHOD(Console, cmdSegmentInfo)); // alias
DCmd_Register("segment_kill", WRAP_METHOD(Console, cmdKillSegment));
+ DCmd_Register("segkill", WRAP_METHOD(Console, cmdKillSegment)); // alias
// Garbage collection
DCmd_Register("gc", WRAP_METHOD(Console, cmdGCInvoke));
DCmd_Register("gc_objects", WRAP_METHOD(Console, cmdGCObjects));
@@ -157,7 +160,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
DCmd_Register("go", WRAP_METHOD(Console, cmdGo));
// Breakpoints
DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList));
+ DCmd_Register("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias
DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
+ DCmd_Register("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod));
DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointExecMethod)); // alias
DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction));
@@ -165,7 +170,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
// VM
DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
+ DCmd_Register("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias
DCmd_Register("vm_vars", WRAP_METHOD(Console, cmdVMVars));
+ DCmd_Register("vmvars", WRAP_METHOD(Console, cmdVMVars)); // alias
DCmd_Register("stack", WRAP_METHOD(Console, cmdStack));
DCmd_Register("value_type", WRAP_METHOD(Console, cmdValueType));
DCmd_Register("view_listnode", WRAP_METHOD(Console, cmdViewListNode));
@@ -300,9 +307,9 @@ bool Console::cmdHelp(int argc, const char **argv) {
#endif
DebugPrintf("\n");
DebugPrintf("Segments:\n");
- DebugPrintf(" segment_table - Lists all segments\n");
- DebugPrintf(" segment_info - Provides information on the specified segment\n");
- DebugPrintf(" segment_kill - Deletes the specified segment\n");
+ DebugPrintf(" segment_table / segtable - Lists all segments\n");
+ DebugPrintf(" segment_info / seginfo - Provides information on the specified segment\n");
+ DebugPrintf(" segment_kill / segkill - Deletes the specified segment\n");
DebugPrintf("\n");
DebugPrintf("Garbage collection:\n");
DebugPrintf(" gc - Invokes the garbage collector\n");
@@ -335,15 +342,15 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" go - Executes the script\n");
DebugPrintf("\n");
DebugPrintf("Breakpoints:\n");
- DebugPrintf(" bp_list - Lists the current breakpoints\n");
- DebugPrintf(" bp_del - Deletes a breakpoint with the specified index\n");
+ DebugPrintf(" bp_list / bplist - Lists the current breakpoints\n");
+ DebugPrintf(" bp_del / bpdel - Deletes a breakpoint with the specified index\n");
DebugPrintf(" bp_exec_method / bpx - Sets a breakpoint on the execution of the specified method\n");
DebugPrintf(" bp_exec_function / bpe - Sets a breakpoint on the execution of the specified exported function\n");
DebugPrintf("\n");
DebugPrintf("VM:\n");
DebugPrintf(" script_steps - Shows the number of executed SCI operations\n");
- DebugPrintf(" vm_varlist - Shows the addresses of variables in the VM\n");
- DebugPrintf(" vm_vars - Displays or changes variables in the VM\n");
+ DebugPrintf(" vm_varlist / vmvarlist - Shows the addresses of variables in the VM\n");
+ DebugPrintf(" vm_vars / vmvars - Displays or changes variables in the VM\n");
DebugPrintf(" stack - Lists the specified number of stack elements\n");
DebugPrintf(" value_type - Determines the type of a value\n");
DebugPrintf(" view_listnode - Examines the list node at the given address\n");
@@ -1713,7 +1720,7 @@ bool Console::cmdVMVarlist(int argc, const char **argv) {
}
bool Console::cmdVMVars(int argc, const char **argv) {
- if (argc < 2) {
+ if (argc < 3) {
DebugPrintf("Displays or changes variables in the VM\n");
DebugPrintf("Usage: %s <type> <varnum> [<value>]\n", argv[0]);
DebugPrintf("First parameter is either g(lobal), l(ocal), t(emp) or p(aram).\n");
@@ -1747,10 +1754,10 @@ bool Console::cmdVMVars(int argc, const char **argv) {
}
switch (argc) {
- case 2:
+ case 3:
DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(scriptState.variables[vartype][idx]));
break;
- case 3:
+ case 4:
if (parse_reg_t(_vm->_gamestate, argv[3], &scriptState.variables[vartype][idx])) {
DebugPrintf("Invalid address passed.\n");
DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 7118eb682d..d0b3919c60 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -569,6 +569,20 @@ static const struct SciGameDescription SciGameDescriptions[] = {
SCI_VERSION_1
},
+ // Eco Quest - French DOS Floppy (from Strangerke)
+ // SCI interpreter version 1.ECO.013
+ {{"ecoquest", "Floppy", {
+ {"resource.map", 0, "67742945cd59b896d9f22a549f605217", 4407},
+ {"resource.000", 0, "0b12a91c935e385308af8d17811deded", 973723},
+ {"resource.001", 0, "fc7fba54b6bb88fd7e9c229636599aa9", 1205841},
+ {"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872},
+ {"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520},
+ {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH},
+ 0,
+ SCI_VERSION_AUTODETECT,
+ SCI_VERSION_1
+ },
+
// Eco Quest 2 - English DOS Non-Interactive Demo
// SCI interpreter version 1.001.055
{{"ecoquest2", "Demo", {
@@ -591,6 +605,17 @@ static const struct SciGameDescription SciGameDescriptions[] = {
SCI_VERSION_1_1
},
+ // Eco Quest 2 - French DOS Floppy (from Strangerke)
+ // SCI interpreter version 1.001.081
+ {{"ecoquest2", "Floppy", {
+ {"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588},
+ {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946},
+ {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH},
+ 0,
+ SCI_VERSION_AUTODETECT,
+ SCI_VERSION_1_1
+ },
+
// Freddy Pharkas - English DOS demo (from FRG)
// SCI interpreter version 1.001.069
{{"freddypharkas", "Demo", {
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index 0a74ac32e4..fa64957bec 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -497,6 +497,9 @@ int game_init(EngineState *s) {
if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
game_init_sound(s, 0);
+ // Load game language into printLang property of game object
+ s->getLanguage();
+
return 0;
}
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 4133f4cb3b..2ccd88b709 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -320,6 +320,7 @@ SciKernelFunction kfunct_mappers[] = {
/*(?)*/ DEFUN("Lock", kLock, "iii*"),
/*(?)*/ DEFUN("Palette", kPalette, "i.*"),
/*(?)*/ DEFUN("IsItSkip", kIsItSkip, "iiiii"),
+ /*7b*/ DEFUN("StrSplit", kStrSplit, "rrZr"),
// Non-experimental Functions without a fixed ID
DEFUN("CosMult", kTimesCos, "ii"),
@@ -345,7 +346,6 @@ SciKernelFunction kfunct_mappers[] = {
DEFUN("MemorySegment", kStub, ".*"),
DEFUN("ListOps", kStub, ".*"),
DEFUN("ATan", kStub, ".*"),
- DEFUN("StrSplit", kStub, ".*"),
DEFUN("MergePoly", kStub, ".*"),
DEFUN("AssertPalette", kStub, ".*"),
DEFUN("TextColors", kStub, ".*"),
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 15f7c9fcf3..6a275a9adb 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -402,12 +402,6 @@ List *lookup_list(EngineState *s, reg_t addr);
#define _K_SOUND_STATUS_PLAYING 3
-
-/* Kernel optimization flags */
-#define KERNEL_OPT_FLAG_GOT_EVENT (1<<0)
-#define KERNEL_OPT_FLAG_GOT_2NDEVENT (1<<1)
-
-
/******************** Kernel functions ********************/
// New kernel functions
@@ -540,6 +534,7 @@ reg_t kResCheck(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t kShowMovie(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t kSetVideoMode(EngineState *s, int funct_nr, int argc, reg_t *argv);
+reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t k_Unknown(EngineState *s, int funct_nr, int argc, reg_t *argv);
// The Unknown/Unnamed kernel function
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index c4b3f5d71a..5ac09e6c76 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -42,12 +42,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) {
int oldx, oldy;
int modifier_mask = s->_version <= SCI_VERSION_0 ? SCI_EVM_ALL : SCI_EVM_NO_FOOLOCK;
- if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) {
- // Penalty time- too many requests to this function without waiting!
- int delay = s->script_000->locals_block->_locals[SCI_VARIABLE_GAME_SPEED].offset;
- gfxop_sleep(s->gfx_state, delay * 1000 / 60);
- }
-
// If there's a simkey pending, and the game wants a keyboard event, use the
// simkey instead of a normal event
if (g_debug_simulated_key && (mask & SCI_EVT_KEYBOARD)) {
@@ -71,15 +65,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) {
//gfxop_set_pointer_position(s->gfx_state, Common::Point(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y));
- if (e.type)
- s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT);
- else {
- if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_EVENT)
- s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_2NDEVENT;
- else
- s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_EVENT;
- }
-
switch (e.type) {
case SCI_EVT_QUIT:
quit_vm();
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index c7086ddef7..915b07e8a3 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -664,12 +664,13 @@ reg_t kWait(EngineState *s, int funct_nr, int argc, reg_t *argv) {
s->r_acc = make_reg(0, ((long)time - (long)s->last_wait_time) * 60 / 1000);
s->last_wait_time = time;
- // Reset optimization flags: Game is playing along nicely anyway
- s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT);
-
sleep_time *= g_debug_sleeptime_factor;
GFX_ASSERT(gfxop_sleep(s->gfx_state, sleep_time * 1000 / 60));
+ // Reset speed throttler: Game is playing along nicely anyway
+ if (sleep_time > 0)
+ s->speedThrottler->reset();
+
return s->r_acc;
}
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index c693009b35..2f0072ec67 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -251,7 +251,7 @@ reg_t kStub(EngineState *s, int funct_nr, int argc, reg_t *argv) {
}
strcat(tmpbuf, ")");
- warning(tmpbuf);
+ warning("%s", tmpbuf);
return NULL_REG;
}
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index b6bb404d5b..6e5a19bba9 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -812,4 +812,21 @@ reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv) {
return s->r_acc;
}
+reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv) {
+ const char *format = kernel_dereference_char_pointer(s, argv[1], 0);
+ const char *sep = !argv[2].isNull() ? kernel_dereference_char_pointer(s, argv[2], 0) : NULL;
+ Common::String str = s->strSplit(format, sep);
+
+ // Make sure target buffer is large enough
+ char *buf = kernel_dereference_char_pointer(s, argv[0], str.size() + 1);
+
+ if (buf) {
+ strcpy(buf, str.c_str());
+ return argv[0];
+ } else {
+ warning("StrSplit: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(argv[0]), str.size() + 1, str.c_str());
+ return NULL_REG;
+ }
+}
+
} // End of namespace Sci
diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp
index c019f7a3bc..a55d692afe 100644
--- a/engines/sci/engine/message.cpp
+++ b/engines/sci/engine/message.cpp
@@ -33,7 +33,7 @@ MessageTuple MessageState::getTuple() {
t.noun = *(_engineCursor.index_record + 0);
t.verb = *(_engineCursor.index_record + 1);
- if (_version == 2101) {
+ if (_version == 2) {
t.cond = 0;
t.seq = 1;
} else {
@@ -47,7 +47,7 @@ MessageTuple MessageState::getTuple() {
MessageTuple MessageState::getRefTuple() {
MessageTuple t;
- if (_version == 2101) {
+ if (_version == 2) {
t.noun = 0;
t.verb = 0;
t.cond = 0;
@@ -68,7 +68,7 @@ void MessageState::initCursor() {
}
void MessageState::advanceCursor(bool increaseSeq) {
- _engineCursor.index_record += ((_version == 2101) ? 4 : 11);
+ _engineCursor.index_record += ((_version == 2) ? 4 : 11);
_engineCursor.index++;
if (increaseSeq)
@@ -142,7 +142,7 @@ int MessageState::getMessage() {
}
int MessageState::getTalker() {
- return (_version == 2101) ? -1 : *(_engineCursor.index_record + 4);
+ return (_version == 2) ? -1 : *(_engineCursor.index_record + 4);
}
MessageTuple &MessageState::getLastTuple() {
@@ -154,7 +154,7 @@ int MessageState::getLastModule() {
}
Common::String MessageState::getText() {
- char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
+ char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5));
Common::String strippedStr;
Common::String skippedSubstr;
@@ -215,7 +215,7 @@ void MessageState::gotoNext() {
}
int MessageState::getLength() {
- int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
+ int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5));
char *stringptr = (char *)_currentResource->data + offset;
return strlen(stringptr);
}
@@ -244,8 +244,12 @@ int MessageState::loadRes(ResourceManager *resmgr, int module, bool lock) {
_locked = lock;
_version = READ_LE_UINT16(_currentResource->data);
+ debug(5, "Message: reading resource %d.msg, version %d.%03d", _module, _version / 1000, _version % 1000);
- int offs = (_version == 2101) ? 0 : 4;
+ // We assume for now that storing the major version is sufficient
+ _version /= 1000;
+
+ int offs = (_version == 2) ? 0 : 4;
_recordCount = READ_LE_UINT16(_currentResource->data + 4 + offs);
_indexRecords = _currentResource->data + 6 + offs;
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 11dd56f2aa..0341ecb73d 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -311,13 +311,15 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
void script_debug(EngineState *s, bool bp) {
// Do we support a separate console?
- /* if (sci_debug_flags & _DEBUG_FLAG_LOGGING) { */
+#if 0
+ if (sci_debug_flags & _DEBUG_FLAG_LOGGING) {
printf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc));
disassemble(s, scriptState.xs->addr.pc, 0, 1);
if (scriptState.seeking == kDebugSeekGlobal)
printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial,
scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial]));
- /* } */
+ }
+#endif
#if 0
if (!scriptState.debugging)
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 38320c29cc..f0e9863068 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -114,9 +114,12 @@ EngineState::EngineState(ResourceManager *res, sci_version_t version, uint32 fla
gc_countdown = 0;
successor = 0;
+
+ speedThrottler = new SpeedThrottler(version);
}
EngineState::~EngineState() {
+ delete speedThrottler;
}
uint16 EngineState::currentRoomNumber() const {
@@ -172,15 +175,62 @@ Common::String EngineState::getLanguageString(const char *str, kLanguage lang) c
return Common::String(str);
}
+kLanguage EngineState::getLanguage() {
+ kLanguage lang = K_LANG_ENGLISH;
+
+ if (((SciEngine*)g_engine)->getKernel()->_selectorMap.printLang != -1) {
+ EngineState *s = this;
+
+ lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
+
+ if ((_version == SCI_VERSION_1_1) || (lang == K_LANG_NONE)) {
+ // If language is set to none, we use the language from the game detector.
+ // SSCI reads this from resource.cfg (early games do not have a language
+ // setting in resource.cfg, but instead have the secondary language number
+ // hardcoded in the game script).
+ // SCI1.1 games always use the language setting from the config file
+ // (essentially disabling runtime language switching).
+ // Note: only a limited number of multilanguage games have been tested
+ // so far, so this information may not be 100% accurate.
+ switch (((Sci::SciEngine*)g_engine)->getLanguage()) {
+ case Common::FR_FRA:
+ lang = K_LANG_FRENCH;
+ break;
+ case Common::ES_ESP:
+ lang = K_LANG_SPANISH;
+ break;
+ case Common::IT_ITA:
+ lang = K_LANG_ITALIAN;
+ break;
+ case Common::DE_DEU:
+ lang = K_LANG_GERMAN;
+ break;
+ case Common::JA_JPN:
+ lang = K_LANG_JAPANESE;
+ break;
+ case Common::PT_BRA:
+ lang = K_LANG_PORTUGUESE;
+ break;
+ default:
+ lang = K_LANG_ENGLISH;
+ }
+
+ // Store language in printLang selector
+ PUT_SEL32V(s->game_obj, printLang, lang);
+ }
+ }
+
+ return lang;
+}
+
Common::String EngineState::strSplit(const char *str, const char *sep) {
EngineState *s = this;
- kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
- kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
+ kLanguage lang = getLanguage();
+ kLanguage subLang = K_LANG_NONE;
- // Use English when no language settings are present in the game
- if (lang == K_LANG_NONE)
- lang = K_LANG_ENGLISH;
+ if (((SciEngine*)g_engine)->getKernel()->_selectorMap.subtitleLang != -1)
+ subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
Common::String retval = getLanguageString(str, lang);
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index b41e9e383a..a814a20df8 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -119,12 +119,53 @@ public:
bool isOpen() const;
};
+
+class SpeedThrottler {
+public:
+ enum {
+ kSegmentLength = 20 /**< Time segment length in ms */
+ };
+
+ SpeedThrottler(sci_version_t version) {
+ if (version >= SCI_VERSION_1_1)
+ _maxInstructions = 3300;
+ else if (version >= SCI_VERSION_1)
+ _maxInstructions = 2200;
+ else
+ _maxInstructions = 1100;
+ reset();
+ }
+
+ void postInstruction() {
+ if (++_curInstructions >= _maxInstructions) {
+ uint32 time = g_system->getMillis();
+ uint32 elapsed = time - _timestamp;
+
+ if (elapsed < kSegmentLength)
+ g_system->delayMillis(kSegmentLength - elapsed);
+
+ reset();
+ }
+ }
+
+ void reset() {
+ _timestamp = g_system->getMillis();
+ _curInstructions = 0;
+ }
+
+private:
+ uint32 _timestamp; /**< Timestamp of current time segment */
+ uint32 _maxInstructions; /**< Maximum amount of instructions per time segment */
+ uint32 _curInstructions; /**< Amount of instructions executed in current time segment */
+};
+
struct EngineState : public Common::Serializable {
public:
EngineState(ResourceManager *res, sci_version_t version, uint32 flags);
virtual ~EngineState();
virtual void saveLoadWithSerializer(Common::Serializer &ser);
+ kLanguage getLanguage();
public:
int widget_serial_counter; /**< Used for savegames */
@@ -257,6 +298,8 @@ public:
MessageState _msgState;
+ SpeedThrottler *speedThrottler;
+
EngineState *successor; /**< Successor of this state: Used for restoring */
private:
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 0f8fee0876..ae07c314d4 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -126,9 +126,9 @@ static int validate_variable(reg_t *r, reg_t *stack_base, int type, int max, int
}
if (g_debug_weak_validations)
- warning(txt);
+ warning("%s", txt);
else
- error(txt);
+ error("%s", txt);
#ifdef STRICT_READ
return 1;
@@ -1424,6 +1424,8 @@ void run_vm(EngineState *s, int restoring) {
}
//#endif
++script_step_counter;
+
+ s->speedThrottler->postInstruction();
}
}
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 5054bffd30..99a28153c4 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -413,6 +413,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "maniac", "Maniac Mansion (SW).prg", kGenUnchanged, Common::SE_SWE, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (U).prg", kGenUnchanged, Common::EN_USA, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (G).prg", kGenUnchanged, Common::DE_DEU, Common::kPlatformNES, "NES" },
+ { "maniac", "Maniac Mansion (I).prg", kGenUnchanged, Common::IT_ITA, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (Sp).prg", kGenUnchanged, Common::ES_ESP, Common::kPlatformNES, "NES" },
{ "zak", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
diff --git a/engines/scumm/file_nes.cpp b/engines/scumm/file_nes.cpp
index 444b117037..e2604039a4 100644
--- a/engines/scumm/file_nes.cpp
+++ b/engines/scumm/file_nes.cpp
@@ -113,6 +113,16 @@ static const ScummNESFile::Resource res_roomgfx_esp[40] = {
{ 0x07CA4, 0x02D6 }, { 0x10001, 0x06A3 }, { 0x106A4, 0x091F }, { 0x10FC3, 0x0361 }, { 0x11324, 0x0489 },
{ 0x117AD, 0x0437 }, { 0x11BE4, 0x086E }, { 0x12452, 0x0199 }, { 0x125EB, 0x0947 }, { 0x12F32, 0x037A }
};
+static const ScummNESFile::Resource res_roomgfx_ita[40] = {
+ { 0x04001, 0x03EF }, { 0x043F0, 0x069E }, { 0x04A8E, 0x0327 }, { 0x04DB5, 0x053B }, { 0x052F0, 0x06BE },
+ { 0x059AE, 0x0682 }, { 0x06030, 0x0778 }, { 0x067A8, 0x0517 }, { 0x06CBF, 0x07FB }, { 0x074BA, 0x07BE },
+ { 0x08001, 0x07A5 }, { 0x087A6, 0x06DD }, { 0x08E83, 0x04EA }, { 0x0936D, 0x07E2 }, { 0x09B4F, 0x0791 },
+ { 0x0A2E0, 0x07B5 }, { 0x0AA95, 0x0515 }, { 0x0AFAA, 0x0799 }, { 0x0B743, 0x04BB }, { 0x0BBFE, 0x0319 },
+ { 0x0C001, 0x0464 }, { 0x0C465, 0x072C }, { 0x0CB91, 0x0827 }, { 0x0D3B8, 0x0515 }, { 0x0D8CD, 0x064E },
+ { 0x0DF1B, 0x0775 }, { 0x0E690, 0x06DD }, { 0x0ED6D, 0x0376 }, { 0x0F0E3, 0x05F7 }, { 0x0F6DA, 0x0787 },
+ { 0x07C78, 0x02D6 }, { 0x10001, 0x06A3 }, { 0x106A4, 0x0921 }, { 0x10FC5, 0x0361 }, { 0x11326, 0x0489 },
+ { 0x117AF, 0x0437 }, { 0x11BE6, 0x0863 }, { 0x12449, 0x0199 }, { 0x125E2, 0x0947 }, { 0x12F29, 0x037A }
+};
const ScummNESFile::ResourceGroup res_roomgfx = {
ScummNESFile::NES_ROOMGFX,
@@ -123,6 +133,7 @@ const ScummNESFile::ResourceGroup res_roomgfx = {
res_roomgfx_fra,
res_roomgfx_ger,
res_roomgfx_esp,
+ res_roomgfx_ita,
}
};
@@ -132,6 +143,7 @@ static const ScummNESFile::Resource res_costumegfx_swe[2] = { { 0x2EFE1, 0x0EB8
static const ScummNESFile::Resource res_costumegfx_fra[2] = { { 0x30001, 0x0EB8 }, { 0x2F608, 0x0340 } };
static const ScummNESFile::Resource res_costumegfx_ger[2] = { { 0x30001, 0x0EB8 }, { 0x2F4CE, 0x0340 } };
static const ScummNESFile::Resource res_costumegfx_esp[2] = { { 0x30001, 0x0EB8 }, { 0x2F0F6, 0x0340 } };
+static const ScummNESFile::Resource res_costumegfx_ita[2] = { { 0x30001, 0x0EB8 }, { 0x2F4A0, 0x0340 } };
const ScummNESFile::ResourceGroup res_costumegfx = {
ScummNESFile::NES_COSTUMEGFX,
@@ -142,6 +154,7 @@ const ScummNESFile::ResourceGroup res_costumegfx = {
res_costumegfx_fra,
res_costumegfx_ger,
res_costumegfx_esp,
+ res_costumegfx_ita,
}
};
@@ -223,6 +236,19 @@ static const ScummNESFile::Resource res_rooms_esp[55] = {
{ 0x289BE, 0x058E }, { 0x2A418, 0x0201 }, { 0x2A6BE, 0x0325 }, { 0x23D84, 0x01FC }, { 0x2AC46, 0x02A9 },
{ 0x2AEEF, 0x02C9 }, { 0x2B2C0, 0x03D2 }, { 0x27D12, 0x0207 }, { 0x2B7FC, 0x0168 }, { 0x2BD06, 0x0169 }
};
+static const ScummNESFile::Resource res_rooms_ita[55] = {
+ { 0x00000, 0x0000 }, { 0x14001, 0x0D70 }, { 0x132A3, 0x04EA }, { 0x15423, 0x086E }, { 0x1378D, 0x06B1 },
+ { 0x15D16, 0x070F }, { 0x16658, 0x04DB }, { 0x16B33, 0x0AEF }, { 0x18001, 0x06DF }, { 0x17991, 0x03E1 },
+ { 0x18C5C, 0x065E }, { 0x19316, 0x04AF }, { 0x199EA, 0x0448 }, { 0x1A09D, 0x0479 }, { 0x1A516, 0x0445 },
+ { 0x1A95B, 0x03A7 }, { 0x1AD02, 0x0826 }, { 0x1B588, 0x0693 }, { 0x1C001, 0x0B92 }, { 0x1CD70, 0x0484 },
+ { 0x1D4E3, 0x0598 }, { 0x1DFCB, 0x0538 }, { 0x1E9C9, 0x05D1 }, { 0x1F052, 0x0394 }, { 0x1F70D, 0x0741 },
+ { 0x20001, 0x04C2 }, { 0x2053F, 0x0528 }, { 0x21718, 0x05F6 }, { 0x21EB5, 0x0486 }, { 0x223E8, 0x048C },
+ { 0x228DA, 0x093A }, { 0x24001, 0x037A }, { 0x247EE, 0x03CA }, { 0x24BB8, 0x050D }, { 0x25289, 0x0346 },
+ { 0x1BCAC, 0x01CA }, { 0x255CF, 0x045F }, { 0x25A2E, 0x0552 }, { 0x25F80, 0x0651 }, { 0x26B93, 0x024B },
+ { 0x26DDE, 0x01FA }, { 0x270D6, 0x0217 }, { 0x275E4, 0x02F4 }, { 0x28001, 0x045C }, { 0x284CE, 0x08BD },
+ { 0x28DDF, 0x05DF }, { 0x27AC9, 0x0201 }, { 0x2A8A3, 0x0325 }, { 0x27D6F, 0x01FC }, { 0x2AE66, 0x02A9 },
+ { 0x2B10F, 0x02E7 }, { 0x2B4F9, 0x03DE }, { 0x2BA31, 0x0206 }, { 0x2C001, 0x0168 }, { 0x17DC0, 0x0169 }
+};
const ScummNESFile::ResourceGroup res_rooms = {
ScummNESFile::NES_ROOM,
@@ -233,6 +259,7 @@ const ScummNESFile::ResourceGroup res_rooms = {
res_rooms_fra,
res_rooms_ger,
res_rooms_esp,
+ res_rooms_ita,
}
};
@@ -464,6 +491,44 @@ static const ScummNESFile::Resource res_scripts_esp[179] = {
{ 0x2A2C7, 0x0005 }, { 0x2A2CC, 0x0005 }, { 0x2A2D1, 0x0005 }, { 0x2A2D6, 0x0005 }, { 0x216E8, 0x0033 },
{ 0x2A2DB, 0x0005 }, { 0x00000, 0x0000 }, { 0x2A2E0, 0x009C }, { 0x2A37C, 0x009C }
};
+static const ScummNESFile::Resource res_scripts_ita[179] = {
+ { 0x00000, 0x0000 }, { 0x293BE, 0x046B }, { 0x29829, 0x020C }, { 0x29A35, 0x00AA }, { 0x29ADF, 0x03FD },
+ { 0x29EDC, 0x01A1 }, { 0x00000, 0x0000 }, { 0x2A07D, 0x005C }, { 0x00000, 0x0000 }, { 0x2A0D9, 0x0005 },
+ { 0x2C169, 0x000D }, { 0x2C176, 0x000D }, { 0x186E0, 0x0040 }, { 0x18720, 0x0016 }, { 0x1B528, 0x0046 },
+ { 0x1EF9A, 0x00B8 }, { 0x21D0E, 0x0056 }, { 0x17622, 0x0027 }, { 0x1FE4E, 0x0027 }, { 0x1FE75, 0x0027 },
+ { 0x1BC1B, 0x0022 }, { 0x15C91, 0x0085 }, { 0x2233B, 0x001E }, { 0x22359, 0x008F }, { 0x192BA, 0x002B },
+ { 0x1CB93, 0x0065 }, { 0x1CBF8, 0x003F }, { 0x1CC37, 0x004E }, { 0x1CC85, 0x0055 }, { 0x204C3, 0x007C },
+ { 0x16425, 0x0035 }, { 0x1645A, 0x001C }, { 0x16476, 0x0014 }, { 0x1648A, 0x001C }, { 0x164A6, 0x0027 },
+ { 0x164CD, 0x018B }, { 0x1D1F4, 0x009B }, { 0x1D28F, 0x010A }, { 0x1D399, 0x001C }, { 0x1D3B5, 0x0056 },
+ { 0x1D40B, 0x0072 }, { 0x1E503, 0x0028 }, { 0x1E52B, 0x01AA }, { 0x1E6D5, 0x0233 }, { 0x2845D, 0x0071 },
+ { 0x17D72, 0x004E }, { 0x13E3E, 0x0039 }, { 0x18736, 0x02C8 }, { 0x189FE, 0x00BB }, { 0x18AB9, 0x019E },
+ { 0x00000, 0x0000 }, { 0x19E32, 0x00F8 }, { 0x21D64, 0x00F7 }, { 0x1E908, 0x00B0 }, { 0x21E5B, 0x0047 },
+ { 0x2C183, 0x004D }, { 0x13E77, 0x0024 }, { 0x14D71, 0x0014 }, { 0x17649, 0x0058 }, { 0x176A1, 0x010A },
+ { 0x177AB, 0x0009 }, { 0x14D85, 0x01B7 }, { 0x2ABC8, 0x029E }, { 0x23214, 0x070B }, { 0x2C1D0, 0x001A },
+ { 0x2C1EA, 0x0021 }, { 0x2C20B, 0x0022 }, { 0x2C22D, 0x0023 }, { 0x2C250, 0x0016 }, { 0x2C266, 0x001E },
+ { 0x2C284, 0x0016 }, { 0x2C29A, 0x0027 }, { 0x00000, 0x0000 }, { 0x2C2C1, 0x000E }, { 0x177B4, 0x00AA },
+ { 0x22874, 0x0066 }, { 0x14F3C, 0x007B }, { 0x1F3E6, 0x0126 }, { 0x1FE9C, 0x001D }, { 0x1F50C, 0x00B4 },
+ { 0x1F5C0, 0x00AA }, { 0x1785E, 0x006D }, { 0x178CB, 0x003F }, { 0x1F66A, 0x00A3 }, { 0x2C2CF, 0x00AF },
+ { 0x2C37E, 0x00BD }, { 0x2C43B, 0x0085 }, { 0x20A67, 0x01AA }, { 0x20C11, 0x016A }, { 0x20D7B, 0x0073 },
+ { 0x20DEE, 0x003B }, { 0x20E29, 0x00F0 }, { 0x20F19, 0x0047 }, { 0x20F60, 0x00FD }, { 0x2105D, 0x00FF },
+ { 0x2115C, 0x0157 }, { 0x212B3, 0x0195 }, { 0x21448, 0x002E }, { 0x21476, 0x00A9 }, { 0x2437B, 0x011F },
+ { 0x1BC3D, 0x006F }, { 0x1CCDA, 0x0096 }, { 0x28D8B, 0x0054 }, { 0x19F2A, 0x00B8 }, { 0x19FE2, 0x0071 },
+ { 0x14FB7, 0x0057 }, { 0x272ED, 0x02F7 }, { 0x1DA7B, 0x021C }, { 0x1DC97, 0x00FA }, { 0x1DD91, 0x0053 },
+ { 0x1DDE4, 0x01CF }, { 0x1500E, 0x004D }, { 0x26FD8, 0x00FE }, { 0x21EA2, 0x0013 }, { 0x2A0DE, 0x00F0 },
+ { 0x2449A, 0x00DC }, { 0x2151F, 0x00E7 }, { 0x24576, 0x0022 }, { 0x2B8D7, 0x00FE }, { 0x24598, 0x00BB },
+ { 0x250C5, 0x0188 }, { 0x1B56E, 0x000D }, { 0x1B57B, 0x000D }, { 0x2391F, 0x0182 }, { 0x278D8, 0x01F1 },
+ { 0x23AA1, 0x0150 }, { 0x23BF1, 0x01C2 }, { 0x23DB3, 0x0016 }, { 0x2B9D5, 0x005C }, { 0x23DC9, 0x0020 },
+ { 0x27CCA, 0x00A5 }, { 0x2A1CE, 0x0384 }, { 0x1505B, 0x00FA }, { 0x2B3F6, 0x005E }, { 0x00000, 0x0000 },
+ { 0x2524D, 0x003C }, { 0x1E9B8, 0x0011 }, { 0x13E9B, 0x0018 }, { 0x265D1, 0x001F }, { 0x265F0, 0x0054 },
+ { 0x26644, 0x0155 }, { 0x26799, 0x004B }, { 0x267E4, 0x017C }, { 0x26960, 0x0027 }, { 0x26987, 0x0041 },
+ { 0x269C8, 0x01CB }, { 0x13EB3, 0x001F }, { 0x24653, 0x002A }, { 0x15155, 0x01A4 }, { 0x192E5, 0x0031 },
+ { 0x1790A, 0x0087 }, { 0x21606, 0x00DF }, { 0x1D47D, 0x0018 }, { 0x1D495, 0x004E }, { 0x18C57, 0x0005 },
+ { 0x152F9, 0x011F }, { 0x15418, 0x000B }, { 0x2467D, 0x0136 }, { 0x247B3, 0x0014 }, { 0x1DFB3, 0x0018 },
+ { 0x247C7, 0x0027 }, { 0x1A053, 0x004A }, { 0x00000, 0x0000 }, { 0x2B454, 0x00A5 }, { 0x2A552, 0x00BB },
+ { 0x2A60D, 0x0140 }, { 0x197C5, 0x00C6 }, { 0x1988B, 0x014D }, { 0x199D8, 0x0012 }, { 0x2A74D, 0x0005 },
+ { 0x2A752, 0x0005 }, { 0x2A757, 0x0005 }, { 0x2A75C, 0x0005 }, { 0x2A761, 0x0005 }, { 0x216E5, 0x0033 },
+ { 0x2A766, 0x0005 }, { 0x00000, 0x0000 }, { 0x2A76B, 0x009C }, { 0x2A807, 0x009C }
+};
const ScummNESFile::ResourceGroup res_scripts = {
ScummNESFile::NES_SCRIPT,
@@ -474,6 +539,7 @@ const ScummNESFile::ResourceGroup res_scripts = {
res_scripts_fra,
res_scripts_ger,
res_scripts_esp,
+ res_scripts_ita,
}
};
@@ -591,6 +657,25 @@ static const ScummNESFile::Resource res_sounds_esp[82] = {
{ 0x36320, 0x0E56 }, { 0x37176, 0x0C70 }, { 0x38001, 0x0DEC }, { 0x38DED, 0x0B77 }, { 0x33B4F, 0x042F },
{ 0x39964, 0x0AC5 }, { 0x3A429, 0x0BE4 }
};
+static const ScummNESFile::Resource res_sounds_ita[82] = {
+ { 0x0BF54, 0x000A }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 },
+ { 0x30ECA, 0x0832 }, { 0x0BF5E, 0x0011 }, { 0x1FEB9, 0x0073 }, { 0x0BF6F, 0x0011 }, { 0x13F57, 0x0011 },
+ { 0x23EFE, 0x0056 }, { 0x1BF37, 0x001F }, { 0x13F68, 0x0011 }, { 0x0FF76, 0x000A }, { 0x17F64, 0x000A },
+ { 0x1BF56, 0x0019 }, { 0x1FF2C, 0x004B }, { 0x17F6E, 0x000A }, { 0x1BF6F, 0x000F }, { 0x23F54, 0x001D },
+ { 0x2BE61, 0x0045 }, { 0x23F71, 0x000F }, { 0x2BEA6, 0x001B }, { 0x2BEC1, 0x0033 }, { 0x27F6B, 0x0011 },
+ { 0x2BEF4, 0x000F }, { 0x2BF03, 0x0075 }, { 0x2F7F1, 0x0014 }, { 0x0BF54, 0x000A }, { 0x2F805, 0x00FF },
+ { 0x2F904, 0x000F }, { 0x2F913, 0x000F }, { 0x2F922, 0x0092 }, { 0x2F922, 0x0092 }, { 0x2F9B4, 0x002D },
+ { 0x2F9E1, 0x00F8 }, { 0x2FAD9, 0x0016 }, { 0x2FAEF, 0x0011 }, { 0x2FB00, 0x004B }, { 0x2FB4B, 0x0011 },
+ { 0x2FB5C, 0x003B }, { 0x2FB97, 0x008A }, { 0x2FC21, 0x0011 }, { 0x2FC32, 0x000F }, { 0x2FC41, 0x00A2 },
+ { 0x2FCE3, 0x00D3 }, { 0x2FDB6, 0x0097 }, { 0x2BEF4, 0x000F }, { 0x2FC41, 0x00A2 }, { 0x316FC, 0x05D1 },
+ { 0x316FC, 0x05D1 }, { 0x2FE4D, 0x0011 }, { 0x0BF54, 0x000A }, { 0x2BF03, 0x0075 }, { 0x1BF37, 0x001F },
+ { 0x31CCD, 0x098E }, { 0x2FB00, 0x004B }, { 0x2FE5E, 0x0011 }, { 0x30ECA, 0x0832 }, { 0x2FE6F, 0x000F },
+ { 0x2FE7E, 0x002F }, { 0x2FEAD, 0x001D }, { 0x2FECA, 0x0018 }, { 0x2FEE2, 0x0016 }, { 0x2FEF8, 0x001B },
+ { 0x3265B, 0x0088 }, { 0x2FF13, 0x0065 }, { 0x326E3, 0x0065 }, { 0x32748, 0x0073 }, { 0x327BB, 0x00F9 },
+ { 0x328B4, 0x049E }, { 0x32D52, 0x0EA8 }, { 0x34001, 0x0B18 }, { 0x34B19, 0x0B9C }, { 0x356B5, 0x0C6B },
+ { 0x36320, 0x0E56 }, { 0x37176, 0x0C70 }, { 0x38001, 0x0DEC }, { 0x38DED, 0x0B77 }, { 0x39964, 0x042F },
+ { 0x39D93, 0x0AC5 }, { 0x3A858, 0x0BE4 }
+};
const ScummNESFile::ResourceGroup res_sounds = {
ScummNESFile::NES_SOUND,
@@ -601,6 +686,7 @@ const ScummNESFile::ResourceGroup res_sounds = {
res_sounds_fra,
res_sounds_ger,
res_sounds_esp,
+ res_sounds_ita,
}
};
@@ -646,6 +732,13 @@ static const ScummNESFile::Resource res_costumes_esp[25] = {
{ 0x0FEF1, 0x0055 }, { 0x13F28, 0x003B }, { 0x0FEF1, 0x0055 }, { 0x17F2A, 0x0045 }, { 0x1FE71, 0x0040 },
{ 0x1FEB1, 0x003C }, { 0x13EEE, 0x003A }, { 0x13EEE, 0x003A }, { 0x0FEF1, 0x0055 }, { 0x13EA3, 0x004B }
};
+static const ScummNESFile::Resource res_costumes_ita[25] = {
+ { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 },
+ { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x13ED2, 0x004B }, { 0x0FEEB, 0x0055 },
+ { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FF40, 0x0036 }, { 0x13F1D, 0x003A }, { 0x13F1D, 0x003A },
+ { 0x0FEEB, 0x0055 }, { 0x17F29, 0x003B }, { 0x0FEEB, 0x0055 }, { 0x1BE76, 0x0045 }, { 0x1BEBB, 0x0040 },
+ { 0x1BEFB, 0x003C }, { 0x13F1D, 0x003A }, { 0x13F1D, 0x003A }, { 0x0FEEB, 0x0055 }, { 0x13ED2, 0x004B }
+};
const ScummNESFile::ResourceGroup res_costumes = {
ScummNESFile::NES_COSTUME,
@@ -656,6 +749,7 @@ const ScummNESFile::ResourceGroup res_costumes = {
res_costumes_fra,
res_costumes_ger,
res_costumes_esp,
+ res_costumes_ita,
}
};
@@ -665,6 +759,7 @@ static const ScummNESFile::Resource res_globdata_swe[1] = { { 0x2C001, 0x0307 }
static const ScummNESFile::Resource res_globdata_fra[1] = { { 0x2C628, 0x0307 } };
static const ScummNESFile::Resource res_globdata_ger[1] = { { 0x2C4EE, 0x0307 } };
static const ScummNESFile::Resource res_globdata_esp[1] = { { 0x2C001, 0x0307 } };
+static const ScummNESFile::Resource res_globdata_ita[1] = { { 0x2C4C0, 0x0307 } };
const ScummNESFile::ResourceGroup res_globdata = {
ScummNESFile::NES_GLOBDATA,
@@ -675,6 +770,7 @@ const ScummNESFile::ResourceGroup res_globdata = {
res_globdata_fra,
res_globdata_ger,
res_globdata_esp,
+ res_globdata_ita,
}
};
@@ -685,6 +781,7 @@ static const ScummNESFile::Resource res_sprpals_swe[2] = { { 0x07F55, 0x0010 },
static const ScummNESFile::Resource res_sprpals_fra[2] = { { 0x07ED8, 0x0010 }, { 0x07EE8, 0x0010 } };
static const ScummNESFile::Resource res_sprpals_ger[2] = { { 0x07F6B, 0x0010 }, { 0x0BF17, 0x0010 } };
static const ScummNESFile::Resource res_sprpals_esp[2] = { { 0x0BF15, 0x0010 }, { 0x0BF25, 0x0010 } };
+static const ScummNESFile::Resource res_sprpals_ita[2] = { { 0x07F54, 0x0010 }, { 0x07F64, 0x0010 } };
const ScummNESFile::ResourceGroup res_sprpals = {
ScummNESFile::NES_SPRPALS,
@@ -695,6 +792,7 @@ const ScummNESFile::ResourceGroup res_sprpals = {
res_sprpals_fra,
res_sprpals_ger,
res_sprpals_esp,
+ res_sprpals_ita,
}
};
@@ -705,6 +803,7 @@ static const ScummNESFile::Resource res_sprdesc_swe[2] = { { 0x0BF1B, 0x0031 },
static const ScummNESFile::Resource res_sprdesc_fra[2] = { { 0x07EF8, 0x0031 }, { 0x07F29, 0x0009 } };
static const ScummNESFile::Resource res_sprdesc_ger[2] = { { 0x0BF27, 0x0031 }, { 0x0BF58, 0x0009 } };
static const ScummNESFile::Resource res_sprdesc_esp[2] = { { 0x0BF35, 0x0031 }, { 0x0BF66, 0x0009 } };
+static const ScummNESFile::Resource res_sprdesc_ita[2] = { { 0x0BF17, 0x0031 }, { 0x07F74, 0x0009 } };
const ScummNESFile::ResourceGroup res_sprdesc = {
ScummNESFile::NES_SPRDESC,
@@ -715,6 +814,7 @@ const ScummNESFile::ResourceGroup res_sprdesc = {
res_sprdesc_fra,
res_sprdesc_ger,
res_sprdesc_esp,
+ res_sprdesc_ita,
}
};
@@ -725,6 +825,7 @@ static const ScummNESFile::Resource res_sprlens_swe[2] = { { 0x13E6A, 0x0115 },
static const ScummNESFile::Resource res_sprlens_fra[2] = { { 0x0FE61, 0x0115 }, { 0x07ED2, 0x0006 } };
static const ScummNESFile::Resource res_sprlens_ger[2] = { { 0x2BE1A, 0x0115 }, { 0x07F65, 0x0006 } };
static const ScummNESFile::Resource res_sprlens_esp[2] = { { 0x2EFE1, 0x0115 }, { 0x07F7A, 0x0006 } };
+static const ScummNESFile::Resource res_sprlens_ita[2] = { { 0x23DE9, 0x0115 }, { 0x07F4E, 0x0006 } };
const ScummNESFile::ResourceGroup res_sprlens = {
ScummNESFile::NES_SPRLENS,
@@ -735,6 +836,7 @@ const ScummNESFile::ResourceGroup res_sprlens = {
res_sprlens_fra,
res_sprlens_ger,
res_sprlens_esp,
+ res_sprlens_ita,
}
};
@@ -745,6 +847,7 @@ static const ScummNESFile::Resource res_sproffs_swe[2] = { { 0x2BCE0, 0x022A },
static const ScummNESFile::Resource res_sproffs_fra[2] = { { 0x2F959, 0x022A }, { 0x07F32, 0x000C } };
static const ScummNESFile::Resource res_sproffs_ger[2] = { { 0x2F81F, 0x022A }, { 0x0BF61, 0x000C } };
static const ScummNESFile::Resource res_sproffs_esp[2] = { { 0x2F447, 0x022A }, { 0x0BF6F, 0x000C } };
+static const ScummNESFile::Resource res_sproffs_ita[2] = { { 0x2BC37, 0x022A }, { 0x0BF48, 0x000C } };
const ScummNESFile::ResourceGroup res_sproffs = {
ScummNESFile::NES_SPROFFS,
@@ -755,6 +858,7 @@ const ScummNESFile::ResourceGroup res_sproffs = {
res_sproffs_fra,
res_sproffs_ger,
res_sproffs_esp,
+ res_sproffs_ita,
}
};
@@ -765,6 +869,7 @@ static const ScummNESFile::Resource res_sprdata_swe[2] = { { 0x2C401, 0x2BE0 },
static const ScummNESFile::Resource res_sprdata_fra[2] = { { 0x2CA28, 0x2BE0 }, { 0x07E48, 0x008A } };
static const ScummNESFile::Resource res_sprdata_ger[2] = { { 0x2C8EE, 0x2BE0 }, { 0x0FE61, 0x008A } };
static const ScummNESFile::Resource res_sprdata_esp[2] = { { 0x2C401, 0x2BE0 }, { 0x0FE67, 0x008A } };
+static const ScummNESFile::Resource res_sprdata_ita[2] = { { 0x2C8C0, 0x2BE0 }, { 0x0FE61, 0x008A } };
const ScummNESFile::ResourceGroup res_sprdata = {
ScummNESFile::NES_SPRDATA,
@@ -775,6 +880,7 @@ const ScummNESFile::ResourceGroup res_sprdata = {
res_sprdata_fra,
res_sprdata_ger,
res_sprdata_esp,
+ res_sprdata_ita,
}
};
@@ -784,6 +890,7 @@ static const ScummNESFile::Resource res_charset_swe[1] = { { 0x3F739, 0x0090 } }
static const ScummNESFile::Resource res_charset_fra[1] = { { 0x3F739, 0x0090 } };
static const ScummNESFile::Resource res_charset_ger[1] = { { 0x3F739, 0x0090 } };
static const ScummNESFile::Resource res_charset_esp[1] = { { 0x3F739, 0x0090 } };
+static const ScummNESFile::Resource res_charset_ita[1] = { { 0x3F739, 0x0090 } };
const ScummNESFile::ResourceGroup res_charset = {
ScummNESFile::NES_CHARSET,
@@ -794,6 +901,7 @@ const ScummNESFile::ResourceGroup res_charset = {
res_charset_fra,
res_charset_ger,
res_charset_esp,
+ res_charset_ita,
}
};
@@ -803,6 +911,7 @@ static const ScummNESFile::Resource res_preplist_swe[1] = { { 0x3FBA9, 0x000E }
static const ScummNESFile::Resource res_preplist_fra[1] = { { 0x3FBAF, 0x0010 } };
static const ScummNESFile::Resource res_preplist_ger[1] = { { 0x3FBAB, 0x000F } };
static const ScummNESFile::Resource res_preplist_esp[1] = { { 0x3FBAE, 0x000F } };
+static const ScummNESFile::Resource res_preplist_ita[1] = { { 0x3FBAA, 0x0010 } };
const ScummNESFile::ResourceGroup res_preplist = {
ScummNESFile::NES_PREPLIST,
@@ -813,6 +922,7 @@ const ScummNESFile::ResourceGroup res_preplist = {
res_preplist_fra,
res_preplist_ger,
res_preplist_esp,
+ res_preplist_ita,
}
};
@@ -1281,6 +1391,9 @@ bool ScummNESFile::open(const Common::String &filename) {
} else if (!strcmp(md5str, "f163cf53f7850e43fb482471e5c52e1a")) {
_ROMset = kROMsetSpain;
debug(2, "ROM contents verified as Maniac Mansion (Spain)");
+ } else if (!strcmp(md5str, "54a68a5f5e3c86da42b7ca5f51e79b1d")) {
+ _ROMset = kROMsetItaly;
+ debug(2, "ROM contents verified as Maniac Mansion (Italy)");
} else {
error("Unsupported Maniac Mansion ROM, md5: %s", md5str);
return false;
diff --git a/engines/scumm/file_nes.h b/engines/scumm/file_nes.h
index b255705922..274ec02ed0 100644
--- a/engines/scumm/file_nes.h
+++ b/engines/scumm/file_nes.h
@@ -41,6 +41,7 @@ public:
kROMsetFrance,
kROMsetGermany,
kROMsetSpain,
+ kROMsetItaly,
kROMsetNum
};
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 18cba0ab4a..fa5d2011b0 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -671,6 +671,16 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
width -= 16;
if (width <= 0)
return;
+
+ // HACK: In this way we won't get a screen with dirty side strips when
+ // loading a narrow room in a full screen room.
+ if (width == 224 && height == 240 && x == 16) {
+ char blackbuf[16 * 240];
+ memset(blackbuf, 0, 16 * 240); // Prepare a buffer 16px wide and 240px high, to fit on a lateral strip
+
+ width = 240; // Fix right strip
+ _system->copyRectToScreen((const byte *)blackbuf, 16, 0, 0, 16, 240); // Fix left strip
+ }
}
}
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index cb7f906f13..9a1d6485e2 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 Thu Jul 30 10:23:41 2009
+ This file was generated by the md5table tool on Mon Aug 10 19:27:14 2009
DO NOT EDIT MANUALLY!
*/
@@ -46,6 +46,7 @@ static const MD5Table md5table[] = {
{ "0b3222aaa7efcf283eb621e0cefd26cc", "puttputt", "HE 60", "", -1, Common::RU_RUS, Common::kPlatformPC },
{ "0be88565f734b1e9e77ccaaf3bb14b29", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC },
{ "0bf1a3eb198ca1bd2ebe104825cec770", "puttrace", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
+ { "0c331637580950aea2346e012ef2a868", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformAtariST },
{ "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "0cccfa5223099a60e76cfcca57a1a141", "freddi3", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformPC },
@@ -425,7 +426,7 @@ static const MD5Table md5table[] = {
{ "a525c1753c1db5011c00417da37887ef", "PuttTime", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a56e8d9d4281c53c3f63c9bd22a59e21", "catalog", "HE CUP", "Preview", 10978342, Common::EN_ANY, Common::kPlatformUnknown },
- { "a570381b028972d891052ee1e51dc011", "maniac", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformAtariST },
+ { "a570381b028972d891052ee1e51dc011", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformAtariST },
{ "a5c5388da9bf0e6662fdca8813a79d13", "farm", "", "", 86962, Common::EN_ANY, Common::kPlatformWindows },
{ "a654fb60c3b67d6317a7894ffd9f25c5", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a7cacad9c40c4dc9e1812abf6c8af9d5", "puttcircus", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -563,6 +564,7 @@ static const MD5Table md5table[] = {
{ "e144f5f49d9241d2a9dee2576b3d09cb", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "e17db1ddf91b39ca6bbc8ad3ed19e883", "monkey", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
{ "e246e02db9630533a40d99c9f54a8e01", "monkey2", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "e28bc6dbec750bced1b7c98d6caa32ce", "maniac", "NES", "", 262144, Common::IT_ITA, Common::kPlatformNES },
{ "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC },
{ "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "e44ea295a3f8fe4f41983080dab1e9ce", "freddi", "HE 90", "Updated", -1, Common::FR_FRA, Common::kPlatformMacintosh },
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index d1676772a8..07e2ce8bca 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -391,8 +391,8 @@ void Sound::playSound(int soundID) {
000070: 01 18 5a 00 10 00 02 28 5f 00 01 00 00 00 00 00 |..Z....(_.......|
*/
}
- else if ((_vm->_game.platform == Common::kPlatformMacintosh) && (_vm->_game.id == GID_INDY3) && (ptr[26] == 0)) {
- // Sound fomat as used in Indy3 EGA Mac.
+ else if ((_vm->_game.platform == Common::kPlatformMacintosh) && (_vm->_game.id == GID_INDY3) && READ_BE_UINT16(ptr + 8) == 0x1C) {
+ // Sound format as used in Indy3 EGA Mac.
// It seems to be closely related to the Amiga format, see player_v3a.cpp
// The following is known:
// offset 0, 16 LE: total size
@@ -411,8 +411,8 @@ void Sound::playSound(int soundID) {
flags = Audio::Mixer::FLAG_AUTOFREE;
size = READ_BE_UINT16(ptr + 12);
- if (size == 0) // WORKAROUND bug #1852635: Sound 54 has size 0.
- return;
+ assert(size);
+
rate = 3579545 / READ_BE_UINT16(ptr + 20);
sound = (char *)malloc(size);
int vol = ptr[24] * 4;
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 4b5e0ce450..957c4f7626 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -2196,6 +2196,10 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
_ctx->bSample = false;
}
}
+
+ // Decrement the subtitles timeout counter
+ if (_ctx->ticks > 0) --_ctx->ticks;
+
} else {
// No sample - just depends on time
if (_ctx->ticks-- <= 0)
@@ -2327,6 +2331,10 @@ static void PrintObjNonPointed(CORO_PARAM, const SCNHANDLE text, const OBJECT *p
_ctx->bSample = false;
}
}
+
+ // Decrement the subtitles timeout counter
+ if (_ctx->ticks > 0) --_ctx->ticks;
+
} else {
// No sample - just depends on time
if (_ctx->ticks-- <= 0)
@@ -3437,6 +3445,10 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
_ctx->bSample = false;
}
}
+
+ // Decrement the subtitles timeout counter
+ if (_ctx->ticks > 0) --_ctx->ticks;
+
} else {
// No sample - just depends on time
if (_ctx->ticks-- <= 0)