aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorTravis Howell2003-07-18 05:49:21 +0000
committerTravis Howell2003-07-18 05:49:21 +0000
commitf20c47bb216210ed681d3d24698de90821de2703 (patch)
tree2315359358817c8841c89c7f518a94ddc3b6af03 /scumm
parent0c47e125af56afb47c1eaa205ea7370fc2e4e747 (diff)
downloadscummvm-rg350-f20c47bb216210ed681d3d24698de90821de2703.tar.gz
scummvm-rg350-f20c47bb216210ed681d3d24698de90821de2703.tar.bz2
scummvm-rg350-f20c47bb216210ed681d3d24698de90821de2703.zip
Add Indy3 FM Towns support, patch #773434
svn-id: r9062
Diffstat (limited to 'scumm')
-rw-r--r--scumm/charset.cpp4
-rw-r--r--scumm/help.cpp5
-rw-r--r--scumm/resource.cpp2
-rw-r--r--scumm/resource_v3.cpp4
-rw-r--r--scumm/script.cpp11
-rw-r--r--scumm/script_v5.cpp22
-rw-r--r--scumm/scumm.h4
-rw-r--r--scumm/scummvm.cpp6
-rw-r--r--scumm/sound.cpp2
9 files changed, 38 insertions, 22 deletions
diff --git a/scumm/charset.cpp b/scumm/charset.cpp
index 49365cbc4e..46253071a4 100644
--- a/scumm/charset.cpp
+++ b/scumm/charset.cpp
@@ -928,8 +928,8 @@ int CharsetRendererV3::getCharWidth(byte chr) {
void CharsetRendererV3::setColor(byte color)
{
_color = color;
- _shadowColor = (_vm->_gameId == GID_ZAK256) ? 8 : 0;
- if (_vm->_gameId == GID_ZAK256) {
+ _shadowColor = (_vm->_features & GF_FMTOWNS) ? 8 : 0;
+ if (_vm->_features & GF_FMTOWNS) {
_dropShadow = ((_color & 0x80) != 0);
_color &= 0x7f;
} else if (_vm->_features & GF_16COLOR) {
diff --git a/scumm/help.cpp b/scumm/help.cpp
index 29d53052f3..677bfc08d3 100644
--- a/scumm/help.cpp
+++ b/scumm/help.cpp
@@ -31,6 +31,7 @@ int ScummHelp::numPages(byte gameId) {
break;
case GID_INDY3:
case GID_INDY3_256:
+ case GID_INDY3_TOWNS:
return 6;
break;
case GID_LOOM:
@@ -141,6 +142,7 @@ void ScummHelp::updateStrings(byte gameId, byte version, int page,
break;
case GID_INDY3:
case GID_INDY3_256:
+ case GID_INDY3_TOWNS:
ADD_BIND("q", "Push");
ADD_BIND("a", "Pull");
ADD_BIND("z", "Give");
@@ -264,6 +266,7 @@ void ScummHelp::updateStrings(byte gameId, byte version, int page,
case GID_INDY3:
case GID_ZAK256:
case GID_INDY3_256:
+ case GID_INDY3_TOWNS:
title = "Other game controls:";
ADD_TEXT("Inventory:");
ADD_BIND("y", "Upper left item");
@@ -289,6 +292,7 @@ void ScummHelp::updateStrings(byte gameId, byte version, int page,
switch (gameId) {
case GID_INDY3:
case GID_INDY3_256:
+ case GID_INDY3_TOWNS:
title = "Fighting controls (numpad):";
ADD_BIND("7", "Step back");
ADD_BIND("4", "Step back");
@@ -312,6 +316,7 @@ void ScummHelp::updateStrings(byte gameId, byte version, int page,
switch (gameId) {
case GID_INDY3:
case GID_INDY3_256:
+ case GID_INDY3_TOWNS:
title = "Biplane controls (numpad):";
ADD_BIND("7", "Fly to upper left");
ADD_BIND("4", "Fly to left");
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
index e1bfa4347f..6f2f5f08d2 100644
--- a/scumm/resource.cpp
+++ b/scumm/resource.cpp
@@ -652,7 +652,7 @@ int Scumm::loadResource(int type, int idx) {
tag = _fileHandle.readUint16LE();
_fileHandle.seek(-6, SEEK_CUR);
/* FIXME */
- if ((type == rtSound) && !(_features & GF_AMIGA) && (_gameId != GID_ZAK256)) {
+ if ((type == rtSound) && !(_features & GF_AMIGA) && !(_features & GF_FMTOWNS)) {
return readSoundResourceSmallHeader(type, idx);
}
} else {
diff --git a/scumm/resource_v3.cpp b/scumm/resource_v3.cpp
index 92b103ef34..d4c38d2c23 100644
--- a/scumm/resource_v3.cpp
+++ b/scumm/resource_v3.cpp
@@ -152,7 +152,9 @@ void Scumm_v3::readIndexFile() {
break;
default:
- error("Bad ID %c%c found in directory!", blocktype & 0xFF, blocktype >> 8);
+ // FIXME: this is a little hack because Indy3 FM Towns has 32 bytes appended to 00.LFL.
+ if (_gameId != GID_INDY3_TOWNS)
+ error("Bad ID %c%c found in directory!", blocktype & 0xFF, blocktype >> 8);
return;
}
}
diff --git a/scumm/script.cpp b/scumm/script.cpp
index 151b8dcb4a..8281f7ce55 100644
--- a/scumm/script.cpp
+++ b/scumm/script.cpp
@@ -507,13 +507,18 @@ int Scumm::readVar(uint var) {
return (_scummVars[ var ] & ( 1 << bit ) ) ? 1 : 0;
} else {
var &= 0x7FFF;
+#if defined(BYPASS_COPY_PROT)
+ if (_gameId == GID_INDY3_TOWNS && var == 1508) {
+ return 0;
+ }
+#endif
checkRange(_numBitVariables - 1, 0, var, "Bit variable %d out of range(r)");
return (_bitVars[var >> 3] & (1 << (var & 7))) ? 1 : 0;
}
}
if (var & 0x4000) {
- if (_gameId == GID_INDY3_256) {
+ if (_gameId == GID_INDY3_256 || _gameId == GID_INDY3_TOWNS) {
var &= 0xF;
} else {
var &= 0xFFF;
@@ -580,7 +585,7 @@ void Scumm::writeVar(uint var, int value) {
}
if (var & 0x4000) {
- if (_gameId == GID_INDY3_256) {
+ if (_gameId == GID_INDY3_256 || _gameId == GID_INDY3_TOWNS) {
var &= 0xF;
} else {
var &= 0xFFF;
@@ -758,7 +763,7 @@ void Scumm::runExitScript() {
// not actual data not even a 00 (stop code)
// maybe we should be limiting ourselves to strictly reading the size
// described in the header?
- if (_gameId == GID_INDY3_256) {
+ if (_gameId == GID_INDY3_256 || _gameId == GID_INDY3_TOWNS) {
// FIXME: Oddly, Indy3 seems to contain exit scripts with only a size
// and a tag - not even a terminating NULL!
byte *roomptr = getResourceAddress(rtRoom, _roomResource);
diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp
index 0d77cef1d3..bdff5aa004 100644
--- a/scumm/script_v5.cpp
+++ b/scumm/script_v5.cpp
@@ -599,7 +599,7 @@ void Scumm_v5::o5_chainScript() {
// the actor ID of the opposing soldier. So, we copy that value
// over to the Local[5] variable of script 33.
// See also bug #743314.
- if (_gameId == GID_INDY3_256 && vm.slot[cur].number == 32 && script == 33) {
+ if ((_gameId == GID_INDY3_256 || _gameId == GID_INDY3_TOWNS) && vm.slot[cur].number == 32 && script == 33) {
vars[5] = vm.localvar[cur][5];
}
@@ -667,7 +667,7 @@ void Scumm_v5::o5_cursorCommand() {
initCharset(getVarOrDirectByte(0x80));
break;
case 14: /* unk */
- if (_features & GF_OLD_BUNDLE || _gameId == GID_INDY3_256) {
+ if (_features & GF_OLD_BUNDLE || _gameId == GID_INDY3_256 || _gameId == GID_INDY3_TOWNS) {
// FIXME: What is this supposed to do? From comparing
// Indy3's script 118 to the Passport Demo's script 58
// my guess is that it's some sort of "init charset",
@@ -690,7 +690,7 @@ void Scumm_v5::o5_cursorCommand() {
break;
}
- if (!(_features & GF_OLD_BUNDLE) && _gameId != GID_INDY3_256) {
+ if (!(_features & GF_OLD_BUNDLE) && _gameId != GID_INDY3_256 && _gameId != GID_INDY3_TOWNS) {
VAR(VAR_CURSORSTATE) = _cursor.state;
VAR(VAR_USERPUT) = _userPut;
}
@@ -975,7 +975,7 @@ void Scumm_v5::o5_getActorScale() {
return;
// INDY3 uses this opcode as a wait_for_actor();
- if ((_gameId == GID_INDY3_256) || (_gameId == GID_INDY3)) {
+ if ((_gameId == GID_INDY3_TOWNS) || (_gameId == GID_INDY3_256) || (_gameId == GID_INDY3)) {
const byte *oldaddr = _scriptPointer - 1;
a = derefActor(getVarOrDirectByte(0x80), "o5_getActorScale (wait)");
if (a->moving) {
@@ -1009,7 +1009,7 @@ void Scumm_v5::o5_getActorX() {
int a;
getResultPos();
- if (_gameId == GID_INDY3_256 || _gameId == GID_INDY3)
+ if (_gameId == GID_INDY3_TOWNS || _gameId == GID_INDY3_256 || _gameId == GID_INDY3)
a = getVarOrDirectByte(0x80);
else
a = getVarOrDirectWord(0x80);
@@ -1021,7 +1021,7 @@ void Scumm_v5::o5_getActorY() {
int a;
getResultPos();
- if (_gameId == GID_INDY3_256 || _gameId == GID_INDY3) {
+ if (_gameId == GID_INDY3_TOWNS || _gameId == GID_INDY3_256 || _gameId == GID_INDY3) {
a = getVarOrDirectByte(0x80);
// FIXME - bug 636433 workaround (can't get into Zeppelin)
@@ -1505,7 +1505,7 @@ void Scumm_v5::o5_resourceRoutines() {
_opcode = fetchScriptByte();
if (_opcode != 17)
resid = getVarOrDirectByte(0x80);
- if (_gameId != GID_ZAK256) {
+ if (!(_features & GF_FMTOWNS)) {
// FIXME - this probably can be removed eventually, I don't think the following
// check will ever be triggered, but then I could be wrong and it's better
// to play it safe.
@@ -2014,7 +2014,7 @@ void Scumm_v5::o5_setVarRange() {
}
void Scumm_v5::o5_startMusic() {
- if (_gameId == GID_ZAK256) {
+ if (_features & GF_FMTOWNS) {
// In Zak256, this seems to be some kind of Audio CD status query function.
// See also bug #762589 (thanks to Hibernatus for providing the information).
getResultPos();
@@ -2341,7 +2341,7 @@ void Scumm_v5::o5_verbOps() {
void Scumm_v5::o5_wait() {
const byte *oldaddr = _scriptPointer - 1;
- if ((_gameId == GID_INDY3_256) || (_gameId == GID_INDY3)) {
+ if ((_gameId == GID_INDY3_TOWNS) || (_gameId == GID_INDY3_256) || (_gameId == GID_INDY3)) {
_opcode = 2;
} else
_opcode = fetchScriptByte();
@@ -2584,7 +2584,7 @@ void Scumm_v5::decodeParseString() {
// It's also needed for Loom, or the lines Bobbin
// speaks during the intro are put at position 0,0.
// In addition, Loom needs to remember the text colour.
- if (_gameId == GID_INDY3_256 || _gameId == GID_INDY3 || _gameId == GID_LOOM) {
+ if (_gameId == GID_INDY3_TOWNS || _gameId == GID_INDY3_256 || _gameId == GID_INDY3 || _gameId == GID_LOOM) {
_string[textSlot].t_xpos = _string[textSlot].xpos;
_string[textSlot].t_ypos = _string[textSlot].ypos;
_string[textSlot].t_color = _string[textSlot].color;
@@ -2615,7 +2615,7 @@ void Scumm_v5::o5_oldRoomEffect() {
a = getVarOrDirectWord(0x80);
#if 1
- if (_gameId == GID_ZAK256) {
+ if (_features & GF_FMTOWNS) {
// FIXME / TODO: OK the first thing to note is: at least in Zak256,
// maybe also in other games, this opcode does a bit more. I added
// some stubs here, but somebody with a full IDA or more knowledge
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 07c23e5dae..082514fe54 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -84,6 +84,7 @@ enum GameFeatures {
GF_AMIGA = 1 << 14,
GF_HUMONGOUS = 1 << 15,
GF_AFTER_HEV7 = 1 << 16,
+ GF_FMTOWNS = 1 << 17,
GF_EXTERNAL_CHARSET = GF_SMALL_HEADER
};
@@ -212,7 +213,8 @@ enum ScummGameId {
GID_ZAK,
GID_PUTTDEMO,
GID_PUTTPUTT,
- GID_MONKEY_SEGA
+ GID_MONKEY_SEGA,
+ GID_INDY3_TOWNS
};
#define _maxRooms res.num[rtRoom]
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index e3543de13b..482e597fbd 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -90,10 +90,12 @@ static const VersionSettings scumm_settings[] = {
/* Scumm Version 3 */
{"indy3EGA", "Indiana Jones and the Last Crusade", GID_INDY3, 3, VersionSettings::ADLIB_ALWAYS,
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALLING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"},
+ {"indy3Towns", "Indiana Jones and the Last Crusade (FM Towns)", GID_INDY3_TOWNS, 3, VersionSettings::ADLIB_ALWAYS,
+ GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALLING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
{"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3_256, 3, VersionSettings::ADLIB_ALWAYS,
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALLING | GF_OLD256 | GF_ADLIB_DEFAULT, "00.LFL"},
{"zak256", "Zak McKracken and the Alien Mindbenders (256)", GID_ZAK256, 3, VersionSettings::ADLIB_ALWAYS,
- GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALLING | GF_OLD256 | GF_AUDIOTRACKS, "00.LFL"},
+ GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALLING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
{"loom", "Loom", GID_LOOM, 3, VersionSettings::ADLIB_ALWAYS,
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALLING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"},
@@ -567,7 +569,7 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst)
_hexdumpScripts = false;
_showStack = false;
- if (_gameId == GID_ZAK256) { // FmTowns is 320x240
+ if (_features & GF_FMTOWNS) { // FmTowns is 320x240
_screenWidth = 320;
_screenHeight = 240;
} else if (_gameId == GID_CMI) {
diff --git a/scumm/sound.cpp b/scumm/sound.cpp
index 375d8d0eba..37dd6c5f88 100644
--- a/scumm/sound.cpp
+++ b/scumm/sound.cpp
@@ -803,7 +803,7 @@ void Sound::stopSound(int a) {
stopCD();
}
- if (_scumm->_gameId == GID_ZAK256) {
+ if (_scumm->_features & GF_FMTOWNS) {
_scumm->_mixer->stopID(a);
} else if (_scumm->_imuseDigital) {
_scumm->_imuseDigital->stopSound(a);