[Scummvm-git-logs] scummvm master -> a1f440c073eb21302ccb6b185e1045015ed4badb
sev-
sev at scummvm.org
Tue Apr 20 21:56:41 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
a1f440c073 SCUMM: FM-TOWNS: Add optional trimming to 200 pixels height
Commit: a1f440c073eb21302ccb6b185e1045015ed4badb
https://github.com/scummvm/scummvm/commit/a1f440c073eb21302ccb6b185e1045015ed4badb
Author: Zvika Haramaty (haramaty.zvika at gmail.com)
Date: 2021-04-20T23:56:39+02:00
Commit Message:
SCUMM: FM-TOWNS: Add optional trimming to 200 pixels height
Trimming the screen to 200 pixels allows using aspect ratio correction.
Changed paths:
engines/scumm/charset.cpp
engines/scumm/detection.cpp
engines/scumm/detection.h
engines/scumm/detection_tables.h
engines/scumm/resource.cpp
engines/scumm/saveload.cpp
engines/scumm/script_v5.cpp
engines/scumm/scumm.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 173213539b..7fea5d69e5 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -850,8 +850,10 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
assertRange(0, _curId, _vm->_numCharsets - 1, "charset");
- if ((vs = _vm->findVirtScreen(_top)) == NULL)
+ if ((vs = _vm->findVirtScreen(_top)) == NULL) {
+ warning("findVirtScreen(%d) failed, therefore printChar cannot print '%c'", _top, chr);
return;
+ }
if (chr == '@')
return;
@@ -1334,6 +1336,9 @@ void CharsetRendererTownsV3::drawBits1(Graphics::Surface &dest, int x, int y, co
return;
}
+ if (y + height > dest.h)
+ error("Trying to draw below screen boundries");
+
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
#ifdef USE_RGB_COLOR
if (_sjisCurChar) {
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 552df4f4c9..21f89b5e93 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -168,14 +168,29 @@ static const ExtraGuiOption mmnesObjectLabelsOption = {
false
};
+static const ExtraGuiOption fmtownsTrimTo200 = {
+ _s("Trim FM-TOWNS games to 200 pixels height"),
+ _s("Cut the extra 40 pixels at the bottom of the screen, to make it standard 200 pixels height, allowing using 'aspect ratio correction'"),
+ "trim_fmtowns_to_200_pixels",
+ false
+};
+
+
const ExtraGuiOptions ScummMetaEngineDetection::getExtraGuiOptions(const Common::String &target) const {
ExtraGuiOptions options;
+ // Query the GUI options
+ const Common::String guiOptionsString = ConfMan.get("guioptions", target);
+ const Common::String guiOptions = parseGameGUIOptions(guiOptionsString);
+
if (target.empty() || ConfMan.get("gameid", target) == "comi") {
options.push_back(comiObjectLabelsOption);
}
if (target.empty() || Common::parsePlatform(ConfMan.get("platform", target)) == Common::kPlatformNES) {
options.push_back(mmnesObjectLabelsOption);
}
+ if (target.empty() || (ConfMan.get("platform", target) == "fmtowns" && guiOptions.contains(GUIO_TRIM_FMTOWNS_TO_200_PIXELS))) {
+ options.push_back(fmtownsTrimTo200);
+ }
return options;
}
diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index 11d3abf3c5..3d4beea7cc 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -28,6 +28,10 @@
namespace Scumm {
+
+// GUI-options, primarily used by detection_tables.h
+#define GUIO_TRIM_FMTOWNS_TO_200_PIXELS GUIO_GAMEOPTIONS1
+
/**
* Descriptor of a specific SCUMM game. Used internally to store
* information about the tons of game variants that exist.
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 06f110a104..7de7558d3b 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -165,16 +165,16 @@ static const GameSettings gameVariantsTable[] = {
{"zak", "V1", "v1", GID_ZAK, 1, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"zak", "V2", "v2", GID_ZAK, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
- {"zak", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
- {"zakloom", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
- {"indyloom", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
- {"indyzak", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
+ {"zak", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
+ {"zakloom", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
+ {"indyloom", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
+ {"indyzak", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
{"indy3", "EGA", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"indy3", "No AdLib", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"indy3", "Steam", "steam", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
- {"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
+ {"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
{"loom", "EGA", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
{"loom", "No AdLib", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
@@ -190,20 +190,20 @@ static const GameSettings gameVariantsTable[] = {
{"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR, GF_16COLOR, Common::kPlatformAtariST, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
- {"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
+ {"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
{"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey", "SE Talkie", 0, GID_MONKEY, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_AUDIOTRACKS, UNK, GUIO0()},
{"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
{"monkey2", "Amiga", 0, GID_MONKEY2, 5, 0, MDT_AMIGA, 0, Common::kPlatformAmiga, GUIO2(GUIO_NOSPEECH, GUIO_MIDIAMIGA)},
- {"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO5(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
+ {"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO5(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
{"monkey2", "SE Talkie",0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "Steam", "steam", GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
{"atlantis", "Amiga", 0, GID_INDY4, 5, 0, MDT_AMIGA, 0, Common::kPlatformAmiga, GUIO2(GUIO_NOSPEECH, GUIO_MIDIAMIGA)},
- {"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO4(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
+ {"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO4(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_TRIM_FMTOWNS_TO_200_PIXELS)},
{"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO0()},
{"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NOSPEECH)},
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index c9888a56a2..8e7feab54e 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -697,6 +697,8 @@ int ScummEngine::loadResource(ResType type, ResId idx) {
}
_fileHandle->read(_res->createResource(type, idx, size), size);
+ applyWorkaroundIfNeeded(type, idx);
+
// dump the resource if requested
if (_dumpScripts && type == rtScript) {
dumpResource("script-", idx, getResourceAddress(rtScript, idx));
@@ -1642,4 +1644,23 @@ const char *nameOfResType(ResType type) {
}
}
+
+void ScummEngine::applyWorkaroundIfNeeded(ResType type, int idx) {
+ // WORKAROUND: FM-TOWNS Zak used the extra 40 pixels at the bottom to increase the inventory to 10 items
+ // if we trim to 200 pixels, we can show only 6 items
+ // therefore we patch the inventory script (20)
+ // replacing the 5 occurences of 10 as limit to 6
+ if (_game.platform == Common::kPlatformFMTowns && _game.id == GID_ZAK && ConfMan.getBool("trim_fmtowns_to_200_pixels"))
+ if (type == rtScript && idx == 20) {
+ byte *ptr = getResourceAddress(rtScript, idx);
+ for (int cnt = 5; cnt; ptr++) {
+ if (*ptr == 10) {
+ *ptr = 6;
+ cnt--;
+ }
+ }
+ }
+}
+
+
} // End of namespace Scumm
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 786f39e37b..997756e85e 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -68,7 +68,7 @@ struct SaveInfoSection {
#define SaveInfoSectionSize (4+4+4 + 4+4 + 4+2)
-#define CURRENT_VER 99
+#define CURRENT_VER 100
#define INFOSECTION_VERSION 2
#pragma mark -
@@ -1007,6 +1007,10 @@ void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint16LE(camera._dest.y, VER(8));
s.syncAsSint16LE(camera._cur.x, VER(8));
s.syncAsSint16LE(camera._cur.y, VER(8));
+ if (_game.platform == Common::kPlatformFMTowns)
+ // WORKAROUND: FM-TOWNS original _screenHeight is 240. if we use trim_fmtowns_to_200_pixels, it's reduced to 200
+ // camera's y is always half of the screen. in order to share save games between the two modes, we need to update the y
+ camera._cur.y = _screenHeight / 2;
s.syncAsSint16LE(camera._last.x, VER(8));
s.syncAsSint16LE(camera._last.y, VER(8));
s.syncAsSint16LE(camera._accel.x, VER(8));
@@ -1258,6 +1262,7 @@ void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
while (s.syncAsUint16LE(idx), idx != 0xFFFF) {
assert(idx < _res->_types[type].size());
loadResource(s, type, idx);
+ applyWorkaroundIfNeeded(type, idx);
}
}
}
@@ -1415,6 +1420,25 @@ void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
s.syncBytes(_bitVars, _numBitVariables / 8);
+ // WORKAROUND: FM-TOWNS Zak used the extra 40 pixels at the bottom to increase the inventory to 10 items
+ // if we trim to 200 pixels, we can show only 6 items
+ // therefore we need to make sure that the inventory is now display correctly, regardless of the mode that the game was saved with
+ if (s.isLoading() && _game.platform == Common::kPlatformFMTowns && _game.id == GID_ZAK) {
+ if (ConfMan.getBool("trim_fmtowns_to_200_pixels"))
+ _verbs[getVerbSlot(116, 0)].curRect.top = 208 - 18; // make down arrow higher
+ else
+ _verbs[getVerbSlot(116, 0)].curRect.top = 208; // return down arrow to its original location
+
+ if (ConfMan.getBool("trim_fmtowns_to_200_pixels"))
+ // VAR(102) to VAR(111) originally keep the 10 displayed inventory items; clean the last 4 ones
+ for (int v = 102 + 6; v <= 111; v++)
+ VAR(v) = 0;
+
+ // make sure the appropriate verbs and arrows are displayed
+ runInventoryScript(0);
+ }
+
+
//
// Save/load a list of the locked objects
//
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 24693bd58c..5195cb9685 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -32,6 +32,7 @@
#include "scumm/verbs.h"
#include "common/savefile.h"
+#include "common/config-manager.h"
namespace Scumm {
@@ -2367,6 +2368,11 @@ void ScummEngine_v5::o5_verbOps() {
break;
}
}
+ } else if (_game.platform == Common::kPlatformFMTowns && ConfMan.getBool("trim_fmtowns_to_200_pixels")) {
+ if (_game.id == GID_ZAK && verb == 116)
+ // WORKAROUND: FM-TOWNS Zak used the extra 40 pixels at the bottom to increase the inventory to 10 items
+ // if we trim to 200 pixels, we need to move the 'down arrow' (verb 116) to higher location
+ vs->curRect.top -= 18;
}
break;
case 6: // SO_VERB_ON
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 59232223fc..ae16ad429f 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -542,6 +542,14 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_renderMode = Common::kRenderDefault;
}
+ if (_game.platform == Common::kPlatformFMTowns && _game.id != GID_LOOM && _game.version == 3)
+ if (ConfMan.getBool("aspect_ratio") && !ConfMan.getBool("trim_fmtowns_to_200_pixels")) {
+ GUI::MessageDialog dialog(
+ _("You have enabled 'aspect ratio correction'. However, FM-TOWNS' natural resolution is 320x240, which doesn't allow aspect ratio correction.\n"
+ "Aspect ratio correction can be acheived by trimming the resolution to 320x200, under 'engine' tab."));
+ dialog.runModal();
+ }
+
// Check some render mode restrictions
if (_game.version <= 1)
_renderMode = Common::kRenderDefault;
@@ -569,9 +577,12 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_hexdumpScripts = false;
_showStack = false;
- if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) { // FM-TOWNS V3 games use 320x240
+ if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) { // FM-TOWNS V3 games originally use 320x240, and we have an option to trim to 200
_screenWidth = 320;
- _screenHeight = 240;
+ if (ConfMan.getBool("trim_fmtowns_to_200_pixels"))
+ _screenHeight = 200;
+ else
+ _screenHeight = 240;
} else if (_game.version == 8 || _game.heversion >= 71) {
// COMI uses 640x480. Likewise starting from version 7.1, HE games use
// 640x480, too.
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 649d327f54..af561c2f59 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -698,6 +698,7 @@ protected:
public:
const byte *findResourceData(uint32 tag, const byte *ptr);
const byte *findResource(uint32 tag, const byte *ptr);
+ void applyWorkaroundIfNeeded(ResType type, int idx);
int getResourceDataSize(const byte *ptr) const;
void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
More information about the Scummvm-git-logs
mailing list