[Scummvm-git-logs] scummvm master -> f8c4fe63e33c6bfe8008dd8429121938e335a0b2
sev-
sev at scummvm.org
Mon May 17 16:44:42 UTC 2021
This automated email contains information about 16 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
819cfb8383 SCUMM: Initial work on Mac Loom font renderer
70a36d6b71 SCUMM: Use high-resolution cursor for Mac Loom
fbefa65da9 SCUMM: Mark screen as dirty in the Mac font renderer
5b70ddd802 SCUMM: Fix text color and shadow
27420f78d4 SCUMM: Simplified Mac font rendering
85ba3876e4 SCUMM: Fix Mac text rendering.
6980ddb337 SCUMM: Add hard-coded Macintosh palette for Loom
5c0c64bc5a SCUMM: Fixed black screen after loading savegame.
ec6f0b1cf3 SCUMM: Some fixes for removing text
93cbb988a6 SCUMM: Some fixes that I'm not sure exactly what they do
3ef517d2a1 SCUMM: Fix some memory leaks
9051349f31 SCUMM: Always draw notes and note names with a shadow in Mac Loom
620d885eac SCUMM: Clarify comment about shadowed text in Mac Loom
cdfe9b5b4c SCUMM: Add practice mode box for Mac Loom
c0c072f4c4 SCUMM: Add hack against Mac Loom distaff glitch
f8c4fe63e3 SCUMM: Hack Mac Loom note names to never be light gray
Commit: 819cfb8383cb8282fcbe78a4ef301ad1154492b9
https://github.com/scummvm/scummvm/commit/819cfb8383cb8282fcbe78a4ef301ad1154492b9
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Initial work on Mac Loom font renderer
The main purpose of this set of changes is to refactor the code to make
it easier to pass the name of the Macintosh resource file to other parts
of the engine (it used to be hard-coded in the music players), and to
scale-up the graphics by 2.
The actual font rendering is almost completely broken.
Changed paths:
engines/scumm/charset.cpp
engines/scumm/charset.h
engines/scumm/cursor.cpp
engines/scumm/gfx.cpp
engines/scumm/input.cpp
engines/scumm/players/player_mac.cpp
engines/scumm/players/player_mac.h
engines/scumm/players/player_v3m.cpp
engines/scumm/players/player_v3m.h
engines/scumm/players/player_v5m.cpp
engines/scumm/players/player_v5m.h
engines/scumm/resource.cpp
engines/scumm/scumm.cpp
engines/scumm/scumm.h
engines/scumm/scumm_v7.h
engines/scumm/string.cpp
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 7fea5d69e5..5643c8d3d8 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/macresman.h"
#include "scumm/charset.h"
#include "scumm/scumm.h"
@@ -1511,6 +1512,68 @@ void CharsetRendererPCE::setDrawCharIntern(uint16 chr) {
}
#endif
+CharsetRendererMac::CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile)
+ : CharsetRenderer(vm) {
+
+ // As far as I can tell, Loom uses only font size 13 for in-game text.
+ // The font is also provided in sizes 9 and 12, and it's possible that
+ // 12 is used for system messages, e.g. the original pause dialog. We
+ // don't support that.
+ //
+ // I have no idea what size 9 is used for. Possibly the original About
+ // dialog?
+ //
+ // As far as I can tell, the game does not use anything fancy, like
+ // different styles, and the font does not appear to have a kerning
+ // table.
+ //
+ // Special characters:
+ //
+ // 16-23 are the note names c through c'.
+ // 60 is an upside-down note, i.e. the one used for c'.
+ // 95 is a used for the rest of the notes.
+
+ if (_vm->_game.id == GID_LOOM) {
+ Common::MacResManager resource;
+ resource.open(fontFile);
+
+ uint16 fontId = 0;
+
+ Common::SeekableReadStream *fond = resource.getResource(MKTAG('F', 'O', 'N', 'D'), "Loom");
+ Graphics::MacFontFamily fontFamily;
+
+ if (fond) {
+ if (fontFamily.load(*fond)) {
+ Common::Array<Graphics::MacFontFamily::AsscEntry> *assoc = fontFamily.getAssocTable();
+ for (uint i = 0; i < assoc->size(); i++) {
+ if ((*assoc)[i]._fontSize == 13) {
+ fontId = (*assoc)[i]._fontID;
+ break;
+ }
+ }
+ }
+ }
+
+ assert(fontId);
+
+ Common::SeekableReadStream *font = resource.getResource(MKTAG('F', 'O', 'N', 'T'), fontId);
+ _macFont.loadFont(*font, &fontFamily, 13, 0);
+ }
+}
+
+int CharsetRendererMac::getFontHeight() {
+ return _macFont.getFontHeight();
+}
+
+int CharsetRendererMac::getCharWidth(uint16 chr) {
+ return _macFont.getCharWidth(chr);
+}
+
+void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
+ _macFont.drawChar(&_vm->_textSurface, chr, _left, _top, _color);
+ _left += getCharWidth(chr);
+}
+
#ifdef ENABLE_SCUMM_7_8
CharsetRendererNut::CharsetRendererNut(ScummEngine *vm)
: CharsetRenderer(vm) {
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index 977e2f61d1..f7170ede50 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/rect.h"
+#include "graphics/fonts/macfont.h"
#include "graphics/sjis.h"
#include "scumm/scumm.h"
#include "scumm/gfx.h"
@@ -274,6 +275,19 @@ public:
int getCharWidth(uint16 chr) override { return 8; }
};
+class CharsetRendererMac : public CharsetRenderer {
+protected:
+ Graphics::MacFONTFont _macFont;
+
+public:
+ CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile);
+
+ void setCurID(int32 id) override {}
+ int getFontHeight() override;
+ int getCharWidth(uint16 chr) override;
+ void printChar(int chr, bool ignoreCharsetMask) override;
+};
+
#ifdef ENABLE_SCUMM_7_8
class CharsetRendererNut : public CharsetRenderer {
protected:
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 21ffc2ae7f..25e0fa86bc 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -389,6 +389,11 @@ void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
}
void ScummEngine_v5::redefineBuiltinCursorFromChar(int index, int chr) {
+ // TODO: The Mac cursor has to be extracted from the CURS resource.
+ // Or possibly just hard-code it, since it's so simple.
+ if (_game.platform == Common::kPlatformMacintosh)
+ return;
+
// Cursor image in both Loom versions are based on images from charset.
// This function is *only* supported for Loom!
assert(_game.id == GID_LOOM);
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 9cc1b8548b..dd802ba1e9 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -331,6 +331,10 @@ void ScummEngine::initScreens(int b, int h) {
_res->nukeResource(rtBuffer, i + 5);
}
+ if (_macScreen) {
+ _textSurface.fillRect(Common::Rect(0, 0, _textSurface.w, _textSurface.h), 0);
+ }
+
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_townsScreen) {
if (!_townsClearLayerFlag && (h - b != _virtscr[kMainVirtScreen].h))
@@ -638,6 +642,11 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
if (width <= 0 || height <= 0)
return;
+ if (_macScreen) {
+ mac_drawStripToScreen(vs, top, x, y, width, height);
+ return;
+ }
+
const void *src = vs->getPixels(x, top);
int m = _textSurfaceMultiplier;
int vsPitch;
@@ -780,6 +789,34 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
_system->copyRectToScreen(src, pitch, x, y, width, height);
}
+ void ScummEngine::mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height) {
+ const byte *src1 = vs->getPixels(x, top);
+ const byte *src2 = (byte *)_textSurface.getBasePtr(x * 2, y * 2);
+ byte *dst = (byte *)_macScreen->getBasePtr(x * 2, y * 2);
+
+ for (int h = 0; h < height; h++) {
+ for (int w = 0; w < width; w++) {
+ dst[2 * w] = src1[w];
+ dst[2 * w + 1] = src1[w];
+ }
+
+ src1 += vs->pitch;
+ memcpy(dst + _macScreen->pitch, dst, width * 2);
+
+ for (int i = 0; i < 2; i++) {
+ for (int w = 0; w < width * 2; w++) {
+ if (src2[w]) {
+ dst[w] = src2[w];
+ }
+ }
+ src2 += _textSurface.pitch;
+ dst += _macScreen->pitch;
+ }
+ }
+
+ _system->copyRectToScreen(_macScreen->getBasePtr(x * 2, y * 2), _macScreen->pitch, x * 2, y * 2, width * 2, height * 2);
+}
+
// CGA
// indy3 loom maniac monkey1 zak
//
@@ -4048,6 +4085,9 @@ void ScummEngine::dissolveEffect(int width, int height) {
towns_drawStripToScreen(vs, x, y + vs->topline, x, y, width, height);
else
#endif
+ if (_macScreen)
+ mac_drawStripToScreen(vs, y, x, y + vs->topline, width, height);
+ else
_system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index bee589d889..46de5fd2f6 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -185,7 +185,7 @@ void ScummEngine::parseEvent(Common::Event event) {
_mouse.x -= (kHercWidth - _screenWidth * 2) / 2;
_mouse.x >>= 1;
_mouse.y = _mouse.y * 4 / 7;
- } else if (_useCJKMode && _textSurfaceMultiplier == 2) {
+ } else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2)) {
_mouse.x >>= 1;
_mouse.y >>= 1;
}
diff --git a/engines/scumm/players/player_mac.cpp b/engines/scumm/players/player_mac.cpp
index 2f2efdf724..b9c9279471 100644
--- a/engines/scumm/players/player_mac.cpp
+++ b/engines/scumm/players/player_mac.cpp
@@ -30,6 +30,7 @@ namespace Scumm {
Player_Mac::Player_Mac(ScummEngine *scumm, Audio::Mixer *mixer, int numberOfChannels, int channelMask, bool fadeNoteEnds)
: _vm(scumm),
+ _channel(NULL),
_mixer(mixer),
_sampleRate(_mixer->getOutputRate()),
_soundPlaying(-1),
@@ -40,12 +41,11 @@ Player_Mac::Player_Mac(ScummEngine *scumm, Audio::Mixer *mixer, int numberOfChan
assert(mixer);
}
-void Player_Mac::init() {
+void Player_Mac::init(const Common::String &instrumentFile) {
+ _instrumentFile = instrumentFile;
_channel = new Player_Mac::Channel[_numberOfChannels];
- int i;
-
- for (i = 0; i < _numberOfChannels; i++) {
+ for (int i = 0; i < _numberOfChannels; i++) {
_channel[i]._looped = false;
_channel[i]._length = 0;
_channel[i]._data = NULL;
@@ -76,17 +76,16 @@ void Player_Mac::init() {
_pitchTable[125] = 2799362;
_pitchTable[126] = 2965820;
_pitchTable[127] = 3142177;
- for (i = 115; i >= 0; --i) {
+
+ for (int i = 115; i >= 0; --i) {
_pitchTable[i] = _pitchTable[i + 12] / 2;
}
setMusicVolume(255);
- if (!checkMusicAvailable()) {
- return;
+ if (!instrumentFile.empty()) {
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
}
-
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
}
Player_Mac::~Player_Mac() {
diff --git a/engines/scumm/players/player_mac.h b/engines/scumm/players/player_mac.h
index 4eb8a2dfef..4c872eed00 100644
--- a/engines/scumm/players/player_mac.h
+++ b/engines/scumm/players/player_mac.h
@@ -46,7 +46,7 @@ public:
Player_Mac(ScummEngine *scumm, Audio::Mixer *mixer, int numberOfChannels, int channelMask, bool fadeNoteEnds);
~Player_Mac() override;
- void init();
+ void init(const Common::String &instrumentFile);
// MusicEngine API
void setMusicVolume(int vol) override;
@@ -98,7 +98,6 @@ private:
int _channelMask;
bool _fadeNoteEnds;
- virtual bool checkMusicAvailable() { return false; }
virtual bool loadMusic(const byte *ptr) { return false; }
virtual bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) { return false; }
@@ -123,6 +122,7 @@ protected:
friend void syncWithSerializer(Common::Serializer &, Channel &);
ScummEngine *const _vm;
+ Common::String _instrumentFile;
Channel *_channel;
uint32 durationToSamples(uint16 duration);
diff --git a/engines/scumm/players/player_v3m.cpp b/engines/scumm/players/player_v3m.cpp
index cede032102..b228440a1a 100644
--- a/engines/scumm/players/player_v3m.cpp
+++ b/engines/scumm/players/player_v3m.cpp
@@ -105,45 +105,9 @@ Player_V3M::Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer)
// not sure if stream 4 is ever used, but let's use it just in case.
}
-// \xAA is a trademark glyph in Mac OS Roman. We try that, but also the Windows
-// version, the UTF-8 version, and just plain without in case the file system
-// can't handle exotic characters like that.
-
-static const char *loomFileNames[] = {
- "Loom\xAA",
- "Loom\x99",
- "Loom\xE2\x84\xA2",
- "Loom"
-};
-
-bool Player_V3M::checkMusicAvailable() {
- Common::MacResManager resource;
-
- for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) {
- if (resource.exists(loomFileNames[i])) {
- return true;
- }
- }
-
- GUI::MessageDialog dialog(_(
- "Could not find the 'Loom' Macintosh executable to read the\n"
- "instruments from. Music will be disabled."), _("OK"));
- dialog.runModal();
- return false;
-}
-
bool Player_V3M::loadMusic(const byte *ptr) {
Common::MacResManager resource;
- bool found = false;
-
- for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) {
- if (resource.open(loomFileNames[i])) {
- found = true;
- break;
- }
- }
-
- if (!found) {
+ if (!resource.open(_instrumentFile)) {
return false;
}
@@ -157,7 +121,6 @@ bool Player_V3M::loadMusic(const byte *ptr) {
// interpreter also has shown that no sound is played while the
// screen is shaking.
debug(5, "Player_V3M::loadMusic: Skipping unknown music type %02X%02X", ptr[4], ptr[5]);
- resource.close();
return false;
}
@@ -176,15 +139,14 @@ bool Player_V3M::loadMusic(const byte *ptr) {
_channel[i]._notesLeft = true;
Common::SeekableReadStream *stream = resource.getResource(RES_SND, instrument);
+
if (_channel[i].loadInstrument(stream)) {
debug(6, "Player_V3M::loadMusic: Channel %d - Loaded Instrument %d (%s)", i, instrument, resource.getResName(RES_SND, instrument).c_str());
} else {
- resource.close();
return false;
}
}
- resource.close();
return true;
}
diff --git a/engines/scumm/players/player_v3m.h b/engines/scumm/players/player_v3m.h
index 5d6b59a162..ea2d10e252 100644
--- a/engines/scumm/players/player_v3m.h
+++ b/engines/scumm/players/player_v3m.h
@@ -44,7 +44,6 @@ class Player_V3M : public Player_Mac {
public:
Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer);
- bool checkMusicAvailable() override;
bool loadMusic(const byte *ptr) override;
bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) override;
};
diff --git a/engines/scumm/players/player_v5m.cpp b/engines/scumm/players/player_v5m.cpp
index 5be92d024b..b8529ce823 100644
--- a/engines/scumm/players/player_v5m.cpp
+++ b/engines/scumm/players/player_v5m.cpp
@@ -86,43 +86,9 @@ Player_V5M::Player_V5M(ScummEngine *scumm, Audio::Mixer *mixer)
assert(_vm->_game.id == GID_MONKEY);
}
-// Try both with and without underscore in the filename, because hfsutils may
-// turn the space into an underscore. At least, it did for me.
-
-static const char *monkeyIslandFileNames[] = {
- "Monkey Island",
- "Monkey_Island"
-};
-
-bool Player_V5M::checkMusicAvailable() {
- Common::MacResManager resource;
-
- for (int i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) {
- if (resource.exists(monkeyIslandFileNames[i])) {
- return true;
- }
- }
-
- GUI::MessageDialog dialog(_(
- "Could not find the 'Monkey Island' Macintosh executable to read the\n"
- "instruments from. Music will be disabled."), _("OK"));
- dialog.runModal();
- return false;
-}
-
bool Player_V5M::loadMusic(const byte *ptr) {
Common::MacResManager resource;
- bool found = false;
- uint i;
-
- for (i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) {
- if (resource.open(monkeyIslandFileNames[i])) {
- found = true;
- break;
- }
- }
-
- if (!found) {
+ if (!resource.open(_instrumentFile)) {
return false;
}
@@ -133,7 +99,7 @@ bool Player_V5M::loadMusic(const byte *ptr) {
Common::MacResIDArray idArray = resource.getResIDArray(RES_SND);
// Load the three channels and their instruments
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
assert(READ_BE_UINT32(ptr) == MKTAG('C', 'h', 'a', 'n'));
uint32 len = READ_BE_UINT32(ptr + 4);
uint32 instrument = READ_BE_UINT32(ptr + 8);
@@ -172,7 +138,7 @@ bool Player_V5M::loadMusic(const byte *ptr) {
uint32 samples[3];
uint32 maxSamples = 0;
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
samples[i] = 0;
for (uint j = 0; j < _channel[i]._length; j += 4) {
samples[i] += durationToSamples(READ_BE_UINT16(&_channel[i]._data[j]));
@@ -182,7 +148,7 @@ bool Player_V5M::loadMusic(const byte *ptr) {
}
}
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
_lastNoteSamples[i] = maxSamples - samples[i];
}
diff --git a/engines/scumm/players/player_v5m.h b/engines/scumm/players/player_v5m.h
index 7721983fa5..02b44e9da2 100644
--- a/engines/scumm/players/player_v5m.h
+++ b/engines/scumm/players/player_v5m.h
@@ -44,7 +44,6 @@ class Player_V5M : public Player_Mac {
public:
Player_V5M(ScummEngine *scumm, Audio::Mixer *mixer);
- bool checkMusicAvailable() override;
bool loadMusic(const byte *ptr) override;
bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) override;
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 8e7feab54e..c1d4cf6c52 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -21,6 +21,7 @@
*/
#include "common/str.h"
+#include "common/macresman.h"
#ifndef MACOSX
#include "common/config-manager.h"
#endif
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index b71458f415..0dbe54e8f8 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -22,6 +22,7 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
+#include "common/macresman.h"
#include "common/md5.h"
#include "common/events.h"
#include "common/system.h"
@@ -292,6 +293,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_hePalettes = NULL;
_hePaletteSlot = 0;
_16BitPalette = NULL;
+ _macScreen = NULL;
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
_townsScreen = 0;
_scrollRequest = _scrollDeltaAdjust = 0;
@@ -690,6 +692,11 @@ ScummEngine::~ScummEngine() {
free(_16BitPalette);
+ if (_macScreen) {
+ _macScreen->free();
+ delete _macScreen;
+ }
+
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
delete _townsScreen;
#ifdef USE_RGB_COLOR
@@ -1302,13 +1309,73 @@ Common::Error ScummEngine::init() {
// Load it earlier so _useCJKMode variable could be set
loadCJKFont();
+ Common::String macResourceFile;
+
+ if (_game.platform == Common::kPlatformMacintosh) {
+ Common::MacResManager resource;
+
+ if (_game.id == GID_LOOM) {
+ // \xAA is a trademark glyph in Mac OS Roman. We try
+ // that, but also the Windows version, the UTF-8
+ // version, and just plain without in case the file
+ // system can't handle exotic characters like that.
+
+ static const char *loomFileNames[] = {
+ "Loom\xAA",
+ "Loom\x99",
+ "Loom\xE2\x84\xA2",
+ "Loom"
+ };
+
+ for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) {
+ if (resource.exists(loomFileNames[i])) {
+ macResourceFile = loomFileNames[i];
+
+ _textSurfaceMultiplier = 2;
+ _macScreen = new Graphics::Surface();
+ _macScreen->create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
+ break;
+ }
+ }
+
+ if (macResourceFile.empty()) {
+ GUI::MessageDialog dialog(_(
+"Could not find the 'Loom' Macintosh executable. Music and high-resolution\n"
+"font will be disabled."), _("OK"));
+ dialog.runModal();
+ }
+ } else if (_game.id == GID_MONKEY) {
+ // Try both with and without underscore in the
+ // filename, because some tools (e.g. hfsutils) may
+ // turn the space into an underscore.
+
+ static const char *monkeyIslandFileNames[] = {
+ "Monkey Island",
+ "Monkey_Island"
+ };
+
+ for (int i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) {
+ if (resource.exists(monkeyIslandFileNames[i])) {
+ macResourceFile = monkeyIslandFileNames[i];
+ }
+ }
+
+ if (macResourceFile.empty()) {
+ GUI::MessageDialog dialog(_(
+"Could not find the 'Monkey Island' Macintosh executable to read the\n"
+"instruments from. Music will be disabled."), _("OK"));
+ dialog.runModal();
+ }
+ }
+ }
+
// Initialize backend
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
initGraphics(kHercWidth, kHercHeight);
} else {
int screenWidth = _screenWidth;
int screenHeight = _screenHeight;
- if (_useCJKMode) {
+ if (_useCJKMode || _macScreen) {
// CJK FT and DIG use usual NUT fonts, not FM-TOWNS ROM, so
// there is no text surface for them. This takes that into account
screenWidth *= _textSurfaceMultiplier;
@@ -1372,7 +1439,7 @@ Common::Error ScummEngine::init() {
_outputPixelFormat = _system->getScreenFormat();
- setupScumm();
+ setupScumm(macResourceFile);
readIndexFile();
@@ -1390,7 +1457,19 @@ Common::Error ScummEngine::init() {
return Common::kNoError;
}
-void ScummEngine::setupScumm() {
+void ScummEngine::setupScumm(const Common::String &macResourceFile) {
+ Common::String macInstrumentFile;
+ Common::String macFontFile;
+
+ if (_game.platform == Common::kPlatformMacintosh) {
+ if (_game.id == GID_LOOM) {
+ macInstrumentFile = macResourceFile;
+ macFontFile = macResourceFile;
+ } else if (_game.id == GID_MONKEY) {
+ macInstrumentFile = macResourceFile;
+ }
+ }
+
// On some systems it's not safe to run CD audio games from the CD.
if (_game.features & GF_AUDIOTRACKS && !Common::File::exists("CDDA.SOU")) {
checkCD();
@@ -1404,13 +1483,13 @@ void ScummEngine::setupScumm() {
_sound = new Sound(this, _mixer);
// Setup the music engine
- setupMusic(_game.midi);
+ setupMusic(_game.midi, macInstrumentFile);
// Load localization data, if present
loadLanguageBundle();
// Create the charset renderer
- setupCharsetRenderer();
+ setupCharsetRenderer(macFontFile);
// Create and clear the text surface
_textSurface.create(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, Graphics::PixelFormat::createFormatCLUT8());
@@ -1491,7 +1570,7 @@ void ScummEngine::setupScumm() {
}
#ifdef ENABLE_SCUMM_7_8
-void ScummEngine_v7::setupScumm() {
+void ScummEngine_v7::setupScumm(const Common::String &macResourceFile) {
if (_game.id == GID_DIG && (_game.features & GF_DEMO))
_smushFrameRate = 15;
@@ -1503,7 +1582,7 @@ void ScummEngine_v7::setupScumm() {
ConfMan.flushToDisk();
_musicEngine = _imuseDigital = new IMuseDigital(this, _mixer, dimuseTempo);
- ScummEngine::setupScumm();
+ ScummEngine::setupScumm(macResourceFile);
// Create FT INSANE object
if (_game.id == GID_FT)
@@ -1517,7 +1596,7 @@ void ScummEngine_v7::setupScumm() {
}
#endif
-void ScummEngine::setupCharsetRenderer() {
+void ScummEngine::setupCharsetRenderer(const Common::String &macFontFile) {
if (_game.version <= 2) {
if (_game.platform == Common::kPlatformNES)
_charset = new CharsetRendererNES(this);
@@ -1531,6 +1610,8 @@ void ScummEngine::setupCharsetRenderer() {
#endif
if (_game.platform == Common::kPlatformFMTowns)
_charset = new CharsetRendererTownsV3(this);
+ else if (_game.platform == Common::kPlatformMacintosh && !macFontFile.empty())
+ _charset = new CharsetRendererMac(this, macFontFile);
else
_charset = new CharsetRendererV3(this);
#ifdef ENABLE_SCUMM_7_8
@@ -1599,6 +1680,10 @@ void ScummEngine::resetScumm() {
}
#endif
+ if (_macScreen) {
+ _macScreen->fillRect(Common::Rect(_macScreen->w, _macScreen->h), 0);
+ }
+
if (_game.version == 0) {
initScreens(8, 144);
} else if ((_game.id == GID_MANIAC) && (_game.version <= 1) && !(_game.platform == Common::kPlatformNES)) {
@@ -1886,7 +1971,7 @@ void ScummEngine_v100he::resetScumm() {
}
#endif
-void ScummEngine::setupMusic(int midi) {
+void ScummEngine::setupMusic(int midi, const Common::String &macInstrumentFile) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(midi);
_native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
@@ -2000,10 +2085,10 @@ void ScummEngine::setupMusic(int midi) {
_musicEngine = new Player_V4A(this, _mixer);
} else if (_game.platform == Common::kPlatformMacintosh && _game.id == GID_LOOM) {
_musicEngine = new Player_V3M(this, _mixer);
- ((Player_V3M *)_musicEngine)->init();
+ ((Player_V3M *)_musicEngine)->init(macInstrumentFile);
} else if (_game.platform == Common::kPlatformMacintosh && _game.id == GID_MONKEY) {
_musicEngine = new Player_V5M(this, _mixer);
- ((Player_V5M *)_musicEngine)->init();
+ ((Player_V5M *)_musicEngine)->init(macInstrumentFile);
} else if (_game.id == GID_MANIAC && _game.version == 1) {
_musicEngine = new Player_V1(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK);
} else if (_game.version <= 2) {
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 6443a08911..1bb70742f3 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -344,19 +344,19 @@ public:
void pauseEngineIntern(bool pause) override;
protected:
- virtual void setupScumm();
+ virtual void setupScumm(const Common::String &macResourceFile);
virtual void resetScumm();
virtual void setupScummVars();
virtual void resetScummVars();
- void setupCharsetRenderer();
+ void setupCharsetRenderer(const Common::String &macFontFile);
void setupCostumeRenderer();
virtual void loadLanguageBundle();
void loadCJKFont();
void loadKorFont();
- void setupMusic(int midi);
+ void setupMusic(int midi, const Common::String &macInstrumentFile);
void setTalkSpeed(int talkspeed);
int getTalkSpeed();
@@ -951,7 +951,8 @@ protected:
virtual void drawDirtyScreenParts();
void updateDirtyScreen(VirtScreenNumber slot);
- void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
+ void drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom);
+ void mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height);
void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
public:
@@ -1378,6 +1379,7 @@ protected:
byte _townsActiveLayerFlags;
static const uint8 _townsLayer2Mask[];
+ Graphics::Surface *_macScreen;
TownsScreen *_townsScreen;
#else
void scrollLeft() { redrawBGStrip(_gdi->_numStrips - 1, 1); }
diff --git a/engines/scumm/scumm_v7.h b/engines/scumm/scumm_v7.h
index 6d9088a017..a774ff0b7d 100644
--- a/engines/scumm/scumm_v7.h
+++ b/engines/scumm/scumm_v7.h
@@ -105,7 +105,7 @@ protected:
void processInput() override;
void processKeyboard(Common::KeyState lastKeyHit) override;
- void setupScumm() override;
+ void setupScumm(const Common::String &macResourceFile) override;
void setupScummVars() override;
void resetScummVars() override;
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index cedb95bab1..0f5e316294 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -652,6 +652,12 @@ void ScummEngine::CHARSET_1() {
_charset->_center = _string[0].center;
_charset->setColor(_charsetColor);
+ if (_macScreen) {
+ _charset->_top *= 2;
+ _charset->_startLeft *= 2;
+ _charset->_left *= 2;
+ }
+
if (a && a->_charset)
_charset->setCurID(a->_charset);
else
@@ -1022,6 +1028,12 @@ void ScummEngine::drawString(int a, const byte *msg) {
_charset->_disableOffsX = _charset->_firstChar = true;
_charset->setCurID(_string[a].charset);
+ if (_macScreen) {
+ _charset->_top *= 2;
+ _charset->_startLeft *= 2;
+ _charset->_left *= 2;
+ }
+
// HACK: Correct positions of text in books in Indy3 Mac.
// See also bug #8759.
if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh && a == 1) {
Commit: 70a36d6b71195cfcfec350cd81b540b7e390e973
https://github.com/scummvm/scummvm/commit/70a36d6b71195cfcfec350cd81b540b7e390e973
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Use high-resolution cursor for Mac Loom
Changed paths:
engines/scumm/cursor.cpp
engines/scumm/scumm.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 25e0fa86bc..13faef70ec 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -21,8 +21,10 @@
*/
#include "common/system.h"
+#include "common/macresman.h"
#include "common/util.h"
#include "graphics/cursorman.h"
+#include "graphics/maccursor.h"
#ifdef ENABLE_HE
#include "graphics/wincursor.h"
#endif
@@ -389,9 +391,7 @@ void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
}
void ScummEngine_v5::redefineBuiltinCursorFromChar(int index, int chr) {
- // TODO: The Mac cursor has to be extracted from the CURS resource.
- // Or possibly just hard-code it, since it's so simple.
- if (_game.platform == Common::kPlatformMacintosh)
+ if (!_macCursorFile.empty())
return;
// Cursor image in both Loom versions are based on images from charset.
@@ -597,6 +597,19 @@ void ScummEngine_v5::resetCursors() {
}
void ScummEngine_v5::setBuiltinCursor(int idx) {
+ if (!_macCursorFile.empty()) {
+ Common::MacResManager resource;
+ if (resource.open(_macCursorFile)) {
+ Common::MacResIDArray resArray = resource.getResIDArray(MKTAG('C', 'U', 'R', 'S'));
+ Common::SeekableReadStream *curs = resource.getResource(MKTAG('C', 'U', 'R', 'S'), resArray[0]);
+ Graphics::MacCursor macCursor;
+ if (macCursor.readFromStream(*curs)) {
+ CursorMan.replaceCursor(&macCursor);
+ return;
+ }
+ }
+ }
+
int i, j;
uint16 color;
const uint16 *src = _cursorImages[_currentCursor];
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 0dbe54e8f8..3ea4107a47 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1341,7 +1341,7 @@ Common::Error ScummEngine::init() {
if (macResourceFile.empty()) {
GUI::MessageDialog dialog(_(
"Could not find the 'Loom' Macintosh executable. Music and high-resolution\n"
-"font will be disabled."), _("OK"));
+"versions of font and cursor will be disabled."), _("OK"));
dialog.runModal();
}
} else if (_game.id == GID_MONKEY) {
@@ -1465,6 +1465,7 @@ void ScummEngine::setupScumm(const Common::String &macResourceFile) {
if (_game.id == GID_LOOM) {
macInstrumentFile = macResourceFile;
macFontFile = macResourceFile;
+ _macCursorFile = macResourceFile;
} else if (_game.id == GID_MONKEY) {
macInstrumentFile = macResourceFile;
}
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 1bb70742f3..97d52ef1a4 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -634,6 +634,7 @@ protected:
public:
/** The name of the (macintosh/rescumm style) container file, if any. */
Common::String _containerFile;
+ Common::String _macCursorFile;
bool openFile(BaseScummFile &file, const Common::String &filename, bool resourceFile = false);
Commit: fbefa65da99c9b3d67b38a745300bac630cb17ae
https://github.com/scummvm/scummvm/commit/fbefa65da99c9b3d67b38a745300bac630cb17ae
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Mark screen as dirty in the Mac font renderer
The difficulty buttons are now drawn almost correctly, even if little
else is. (The text position appears to be slightly wrong.)
Changed paths:
engines/scumm/charset.cpp
engines/scumm/charset.h
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 5643c8d3d8..ef7894110b 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1569,9 +1569,37 @@ int CharsetRendererMac::getCharWidth(uint16 chr) {
return _macFont.getCharWidth(chr);
}
+int CharsetRendererMac::evenDown(int x) {
+ if (x & 1)
+ x--;
+ return x;
+}
+
+int CharsetRendererMac::evenUp(int x) {
+ if (x & 1)
+ x++;
+ return x;
+}
+
void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
_macFont.drawChar(&_vm->_textSurface, chr, _left, _top, _color);
- _left += getCharWidth(chr);
+ int width = _macFont.getCharWidth(chr);
+
+ // Mark the virtual screen as dirty, using downscaled coordinates.
+
+ VirtScreen *vs;
+
+ if ((vs = _vm->findVirtScreen(_top / 2)) != NULL) {
+ int vsLeft = evenDown(_left) / 2;
+ int vsRight = evenUp(_left + width) / 2;
+ int vsTop = evenDown(_top) / 2;
+ int vsBottom = evenUp(_top + _macFont.getFontHeight()) / 2;
+
+ _vm->markRectAsDirty(vs->number, vsLeft, vsRight, vsTop - vs->topline, vsBottom - vs->topline);
+ }
+
+ // Adjust the position, using real screen coordinates
+ _left += width;
}
#ifdef ENABLE_SCUMM_7_8
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index f7170ede50..ddb28f0841 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -279,6 +279,8 @@ class CharsetRendererMac : public CharsetRenderer {
protected:
Graphics::MacFONTFont _macFont;
+ int evenDown(int x);
+ int evenUp(int x);
public:
CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile);
Commit: 5b70ddd8026074b0f32381b01fc2612caee0ace6
https://github.com/scummvm/scummvm/commit/5b70ddd8026074b0f32381b01fc2612caee0ace6
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Fix text color and shadow
Text positioning is still all over the place, though.
Changed paths:
engines/scumm/actor.cpp
engines/scumm/charset.cpp
engines/scumm/charset.h
engines/scumm/gfx.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index fe05297df8..21abde0e7e 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -2954,6 +2954,9 @@ void ScummEngine::stopTalk() {
towns_restoreCharsetBg();
else
#endif
+ if (_macScreen)
+ mac_restoreCharsetBg();
+ else
restoreCharsetBg();
}
}
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index ef7894110b..c98d498dad 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1513,7 +1513,7 @@ void CharsetRendererPCE::setDrawCharIntern(uint16 chr) {
#endif
CharsetRendererMac::CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile)
- : CharsetRenderer(vm) {
+ : CharsetRendererCommon(vm) {
// As far as I can tell, Loom uses only font size 13 for in-game text.
// The font is also provided in sizes 9 and 12, and it's possible that
@@ -1582,26 +1582,75 @@ int CharsetRendererMac::evenUp(int x) {
}
void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
- _macFont.drawChar(&_vm->_textSurface, chr, _left, _top, _color);
- int width = _macFont.getCharWidth(chr);
-
// Mark the virtual screen as dirty, using downscaled coordinates.
VirtScreen *vs;
+ int top = evenDown(_top) / 2;
+
+ if ((vs = _vm->findVirtScreen(top)) == NULL) {
+ warning("findVirtScreen(%d) failed, therefore printChar cannot print '%c'", top, chr);
+ return;
+ }
+
+ if (chr == '@')
+ return;
+
+ if (_enableShadow) {
+ _macFont.drawChar(&_vm->_textSurface, chr, _left + 1, _top - 1, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, _left - 1, _top + 1, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, _left + 2, _top + 2, _shadowColor);
+ }
+ _macFont.drawChar(&_vm->_textSurface, chr, _left, _top, _color);
+ int width = _macFont.getCharWidth(chr);
+
+ int left = _left;
+ int right = _left + width;
+ int bottom = _top + _macFont.getFontHeight();
+
+ if (_enableShadow) {
+ left--;
+ right += 2;
+ top--;
+ bottom++;
+ }
+
+ int vsLeft = evenDown(left) / 2;
+ int vsRight = evenUp(right) / 2;
+ int vsTop = evenDown(top) / 2;
+ int vsBottom = evenUp(bottom) / 2;
- if ((vs = _vm->findVirtScreen(_top / 2)) != NULL) {
- int vsLeft = evenDown(_left) / 2;
- int vsRight = evenUp(_left + width) / 2;
- int vsTop = evenDown(_top) / 2;
- int vsBottom = evenUp(_top + _macFont.getFontHeight()) / 2;
+ if (_firstChar) {
+ _str.left = _left;
+ _str.top = _top;
+ _str.right = _right;
+ _str.bottom = _top;
+ _firstChar = false;
+ }
+
+ _vm->markRectAsDirty(vs->number, vsLeft, vsRight, vsTop - vs->topline, vsBottom - vs->topline);
- _vm->markRectAsDirty(vs->number, vsLeft, vsRight, vsTop - vs->topline, vsBottom - vs->topline);
+ if (!ignoreCharsetMask) {
+ _hasMask = true;
+ _textScreenID = vs->number;
}
// Adjust the position, using real screen coordinates
_left += width;
}
+void CharsetRendererMac::setColor(byte color) {
+ _color = color;
+ _enableShadow = false;
+ _shadowColor = 0;
+
+ if (_vm->_game.id == GID_LOOM) {
+ _enableShadow = ((color & 0xF0) != 0);
+ // Anything outside the ordinary palette should be fine.
+ _shadowColor = 255;
+ _color &= 0x0F;
+ }
+}
+
#ifdef ENABLE_SCUMM_7_8
CharsetRendererNut::CharsetRendererNut(ScummEngine *vm)
: CharsetRenderer(vm) {
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index ddb28f0841..8b8b75c65d 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -275,7 +275,7 @@ public:
int getCharWidth(uint16 chr) override { return 8; }
};
-class CharsetRendererMac : public CharsetRenderer {
+class CharsetRendererMac : public CharsetRendererCommon {
protected:
Graphics::MacFONTFont _macFont;
@@ -288,6 +288,7 @@ public:
int getFontHeight() override;
int getCharWidth(uint16 chr) override;
void printChar(int chr, bool ignoreCharsetMask) override;
+ void setColor(byte color) override;
};
#ifdef ENABLE_SCUMM_7_8
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index dd802ba1e9..1ac7196432 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -817,6 +817,24 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
_system->copyRectToScreen(_macScreen->getBasePtr(x * 2, y * 2), _macScreen->pitch, x * 2, y * 2, width * 2, height * 2);
}
+void ScummEngine::mac_restoreCharsetBg() {
+ _nextLeft = _string[0].xpos;
+ _nextTop = _string[0].ypos + _screenTop;
+
+ if (_charset->_hasMask) {
+ _charset->_hasMask = false;
+ _charset->_str.left = -1;
+ _charset->_left = -1;
+
+ _textSurface.fillRect(Common::Rect(_textSurface.w, _textSurface.h), 0);
+ VirtScreen *vs = &_virtscr[_charset->_textScreenID];
+ if (!vs->h)
+ return;
+
+ markRectAsDirty(vs->number, Common::Rect(vs->w, vs->h), USAGE_BIT_RESTORED);
+ }
+}
+
// CGA
// indy3 loom maniac monkey1 zak
//
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 97d52ef1a4..3520ba6124 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -954,6 +954,7 @@ protected:
void updateDirtyScreen(VirtScreenNumber slot);
void drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom);
void mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height);
+ void mac_restoreCharsetBg();
void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
public:
Commit: 27420f78d45c848035418c81faf8bf2761c93b37
https://github.com/scummvm/scummvm/commit/27420f78d45c848035418c81faf8bf2761c93b37
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Simplified Mac font rendering
Instead of trying to keep track of the real Mac screen coordinates in
the _charset data type, use the original 320x200 coordinates and only
scale up at the time of rendering.
Either way, the output is not pixel perfect, and this is much less error
prone.
Now if only text removal worked correctly...
Changed paths:
engines/scumm/charset.cpp
engines/scumm/charset.h
engines/scumm/gfx.cpp
engines/scumm/string.cpp
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index c98d498dad..9efe976d31 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1562,79 +1562,64 @@ CharsetRendererMac::CharsetRendererMac(ScummEngine *vm, const Common::String &fo
}
int CharsetRendererMac::getFontHeight() {
- return _macFont.getFontHeight();
+ return _macFont.getFontHeight() / 2;
}
int CharsetRendererMac::getCharWidth(uint16 chr) {
- return _macFont.getCharWidth(chr);
-}
-
-int CharsetRendererMac::evenDown(int x) {
- if (x & 1)
- x--;
- return x;
-}
-
-int CharsetRendererMac::evenUp(int x) {
- if (x & 1)
- x++;
- return x;
+ return _macFont.getCharWidth(chr) / 2;
}
void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
// Mark the virtual screen as dirty, using downscaled coordinates.
VirtScreen *vs;
- int top = evenDown(_top) / 2;
- if ((vs = _vm->findVirtScreen(top)) == NULL) {
- warning("findVirtScreen(%d) failed, therefore printChar cannot print '%c'", top, chr);
+ if ((vs = _vm->findVirtScreen(_top)) == NULL) {
+ warning("findVirtScreen(%d) failed, therefore printChar cannot print '%c'", _top, chr);
return;
}
if (chr == '@')
return;
+ int macLeft = 2 * _left;
+ int macTop = 2 * _top;
+
if (_enableShadow) {
- _macFont.drawChar(&_vm->_textSurface, chr, _left + 1, _top - 1, _shadowColor);
- _macFont.drawChar(&_vm->_textSurface, chr, _left - 1, _top + 1, _shadowColor);
- _macFont.drawChar(&_vm->_textSurface, chr, _left + 2, _top + 2, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 1, macTop - 1, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft - 1, macTop + 1, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 2, macTop + 2, _shadowColor);
}
- _macFont.drawChar(&_vm->_textSurface, chr, _left, _top, _color);
- int width = _macFont.getCharWidth(chr);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft, macTop, _color);
+ int width = getCharWidth(chr);
int left = _left;
int right = _left + width;
+ int top = _top;
int bottom = _top + _macFont.getFontHeight();
if (_enableShadow) {
left--;
- right += 2;
+ right++;
top--;
bottom++;
}
- int vsLeft = evenDown(left) / 2;
- int vsRight = evenUp(right) / 2;
- int vsTop = evenDown(top) / 2;
- int vsBottom = evenUp(bottom) / 2;
-
if (_firstChar) {
- _str.left = _left;
- _str.top = _top;
- _str.right = _right;
- _str.bottom = _top;
+ _str.left = left;
+ _str.top = top;
+ _str.right = right;
+ _str.bottom = top;
_firstChar = false;
}
- _vm->markRectAsDirty(vs->number, vsLeft, vsRight, vsTop - vs->topline, vsBottom - vs->topline);
+ _vm->markRectAsDirty(vs->number, left, right, top - vs->topline, bottom - vs->topline);
if (!ignoreCharsetMask) {
_hasMask = true;
_textScreenID = vs->number;
}
- // Adjust the position, using real screen coordinates
_left += width;
}
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index 8b8b75c65d..d7a791f05e 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -279,8 +279,6 @@ class CharsetRendererMac : public CharsetRendererCommon {
protected:
Graphics::MacFONTFont _macFont;
- int evenDown(int x);
- int evenUp(int x);
public:
CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile);
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 1ac7196432..f8e377608e 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -827,6 +827,7 @@ void ScummEngine::mac_restoreCharsetBg() {
_charset->_left = -1;
_textSurface.fillRect(Common::Rect(_textSurface.w, _textSurface.h), 0);
+
VirtScreen *vs = &_virtscr[_charset->_textScreenID];
if (!vs->h)
return;
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index 0f5e316294..cedb95bab1 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -652,12 +652,6 @@ void ScummEngine::CHARSET_1() {
_charset->_center = _string[0].center;
_charset->setColor(_charsetColor);
- if (_macScreen) {
- _charset->_top *= 2;
- _charset->_startLeft *= 2;
- _charset->_left *= 2;
- }
-
if (a && a->_charset)
_charset->setCurID(a->_charset);
else
@@ -1028,12 +1022,6 @@ void ScummEngine::drawString(int a, const byte *msg) {
_charset->_disableOffsX = _charset->_firstChar = true;
_charset->setCurID(_string[a].charset);
- if (_macScreen) {
- _charset->_top *= 2;
- _charset->_startLeft *= 2;
- _charset->_left *= 2;
- }
-
// HACK: Correct positions of text in books in Indy3 Mac.
// See also bug #8759.
if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh && a == 1) {
Commit: 85ba3876e4ce735d1b4ab60b8d7e925ac4187eb7
https://github.com/scummvm/scummvm/commit/85ba3876e4ce735d1b4ab60b8d7e925ac4187eb7
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Fix Mac text rendering.
The font renderer now remembers if the previous character ended on an
odd X coordinate, and compensates for that when calculating the next
character's position.
Maybe there's a more elegant way to do it, but it will do for now. The
rendering appears identical to the original, at least for the test case
I'm using.
Changed paths:
engines/scumm/charset.cpp
engines/scumm/charset.h
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 9efe976d31..c84c4291b6 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1515,6 +1515,8 @@ void CharsetRendererPCE::setDrawCharIntern(uint16 chr) {
CharsetRendererMac::CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile)
: CharsetRendererCommon(vm) {
+ _pad = false;
+
// As far as I can tell, Loom uses only font size 13 for in-game text.
// The font is also provided in sizes 9 and 12, and it's possible that
// 12 is used for system messages, e.g. the original pause dialog. We
@@ -1570,7 +1572,12 @@ int CharsetRendererMac::getCharWidth(uint16 chr) {
}
void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
- // Mark the virtual screen as dirty, using downscaled coordinates.
+ // If this is the beginning of a line, assume the position will be
+ // correct without any padding.
+
+ if (_firstChar || _top != _lastTop) {
+ _pad = false;
+ }
VirtScreen *vs;
@@ -1582,27 +1589,41 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
if (chr == '@')
return;
+ // Scale up the virtual coordinates to get the high resolution ones.
+
int macLeft = 2 * _left;
int macTop = 2 * _top;
+ // The last character ended on an odd X coordinate. This information
+ // was lost in the rounding, so we compensate for it here.
+
+ if (_pad) {
+ macLeft++;
+ _pad = false;
+ }
+
if (_enableShadow) {
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 1, macTop - 1, _shadowColor);
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft - 1, macTop + 1, _shadowColor);
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 2, macTop + 2, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 2, macTop, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft, macTop + 2, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 3, macTop + 3, _shadowColor);
}
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft, macTop, _color);
- int width = getCharWidth(chr);
- int left = _left;
- int right = _left + width;
- int top = _top;
- int bottom = _top + _macFont.getFontHeight();
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 1, macTop + 1, _color);
+
+ // Mark the virtual screen as dirty, using downscaled coordinates.
+
+ int left, right, top, bottom;
if (_enableShadow) {
- left--;
- right++;
- top--;
- bottom++;
+ left = macLeft / 2;
+ right = (macLeft + _macFont.getCharWidth(chr) + 3) / 2;
+ top = macTop / 2;
+ bottom = (macTop + _macFont.getFontHeight() + 3) / 2;
+ } else {
+ left = (macLeft + 1) / 2;
+ right = (macLeft + _macFont.getCharWidth(chr) + 1) / 2;
+ top = (macTop + 1) / 2;
+ bottom = (macTop + _macFont.getFontHeight() + 1) / 2;
}
if (_firstChar) {
@@ -1620,7 +1641,15 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
_textScreenID = vs->number;
}
- _left += width;
+ // The next character may have to be adjusted to compensate for
+ // rounding errors.
+
+ macLeft += _macFont.getCharWidth(chr);
+ if (macLeft & 1)
+ _pad = true;
+
+ _left = macLeft / 2;
+ _lastTop = _top;
}
void CharsetRendererMac::setColor(byte color) {
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index d7a791f05e..7be747b5e6 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -278,6 +278,8 @@ public:
class CharsetRendererMac : public CharsetRendererCommon {
protected:
Graphics::MacFONTFont _macFont;
+ bool _pad;
+ int _lastTop;
public:
CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile);
Commit: 6980ddb337d050ac317d6afe15a370f604fab800
https://github.com/scummvm/scummvm/commit/6980ddb337d050ac317d6afe15a370f604fab800
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Add hard-coded Macintosh palette for Loom
I think this is correct. It's based on Basilisk II.
Changed paths:
engines/scumm/palette.cpp
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 8cb13d083f..833c2c5aeb 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -137,6 +137,20 @@ void ScummEngine::resetPalette() {
0xFF, 0x99, 0x99, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x77, 0xFF, 0xFF, 0xFF
};
+ // Theoreticaly, it should be possible to get the palette from the
+ // game's "clut" reosurce. But when I try that, I still get the wrong
+ // colours. This table is based on what Basilisk II draws.
+
+// 6 = brown
+// 11 = bright cyan
+
+ static const byte tableMacPalette[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00, 0xBE, 0x00, 0x00, 0xBE, 0xBE,
+ 0xBE, 0x00, 0x00, 0xBE, 0x00, 0xBE, 0xBE, 0x75, 0x00, 0xBE, 0xBE, 0xBE,
+ 0x75, 0x75, 0x75, 0x75, 0x75, 0xFC, 0x75, 0xFC, 0x75, 0x75, 0xFC, 0xFC,
+ 0xFC, 0x75, 0x75, 0xFC, 0x75, 0xFC, 0xFC, 0xFC, 0x75, 0xFC, 0xFC, 0xFC
+ };
+
static const byte tableEGAPalette[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA,
@@ -239,6 +253,8 @@ void ScummEngine::resetPalette() {
default:
if ((_game.platform == Common::kPlatformAmiga) || (_game.platform == Common::kPlatformAtariST))
setPaletteFromTable(tableAmigaPalette, sizeof(tableAmigaPalette) / 3);
+ else if (_game.id == GID_LOOM && _game.platform == Common::kPlatformMacintosh)
+ setPaletteFromTable(tableMacPalette, sizeof(tableMacPalette) / 3);
else
setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3);
}
Commit: 5c0c64bc5af5e4c9d508fa6378f032be25d404fa
https://github.com/scummvm/scummvm/commit/5c0c64bc5af5e4c9d508fa6378f032be25d404fa
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Fixed black screen after loading savegame.
I misunderstood the purpose of _textSurface. Now text is drawn to the
Mac screen, and a text mask is drawn to the _textSurface. I hope that's
better.
Still no luck with the non-disappearing text at the start of the game
though.
Changed paths:
engines/scumm/charset.cpp
engines/scumm/gfx.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index c84c4291b6..79a33e6f42 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1603,12 +1603,16 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
}
if (_enableShadow) {
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 2, macTop, _shadowColor);
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft, macTop + 2, _shadowColor);
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 3, macTop + 3, _shadowColor);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 2, macTop, 0);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft, macTop + 2, 0);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 3, macTop + 3, 0);
+ _macFont.drawChar(_vm->_macScreen, chr, macLeft + 2, macTop, _shadowColor);
+ _macFont.drawChar(_vm->_macScreen, chr, macLeft, macTop + 2, _shadowColor);
+ _macFont.drawChar(_vm->_macScreen, chr, macLeft + 3, macTop + 3, _shadowColor);
}
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 1, macTop + 1, _color);
+ _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 1, macTop + 1, 0);
+ _macFont.drawChar(_vm->_macScreen, chr, macLeft + 1, macTop + 1, _color);
// Mark the virtual screen as dirty, using downscaled coordinates.
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index f8e377608e..c31d93a536 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -331,10 +331,6 @@ void ScummEngine::initScreens(int b, int h) {
_res->nukeResource(rtBuffer, i + 5);
}
- if (_macScreen) {
- _textSurface.fillRect(Common::Rect(0, 0, _textSurface.w, _textSurface.h), 0);
- }
-
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_townsScreen) {
if (!_townsClearLayerFlag && (h - b != _virtscr[kMainVirtScreen].h))
@@ -790,28 +786,29 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
}
void ScummEngine::mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height) {
- const byte *src1 = vs->getPixels(x, top);
- const byte *src2 = (byte *)_textSurface.getBasePtr(x * 2, y * 2);
- byte *dst = (byte *)_macScreen->getBasePtr(x * 2, y * 2);
+ const byte *pixels = vs->getPixels(x, top);
+ const byte *ts = (byte *)_textSurface.getBasePtr(x * 2, y * 2);
+ byte *mac = (byte *)_macScreen->getBasePtr(x * 2, y * 2);
+
+ int pixelsPitch = vs->pitch;
+ int tsPitch = _textSurface.pitch;
+ int macPitch = _macScreen->pitch;
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
- dst[2 * w] = src1[w];
- dst[2 * w + 1] = src1[w];
+ if (ts[2 * w] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w] = pixels[w];
+ if (ts[2 * w + 1] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w + 1] = pixels[w];
+ if (ts[2 * w + tsPitch] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w + macPitch] = pixels[w];
+ if (ts[2 * w + tsPitch + 1] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w + macPitch + 1] = pixels[w];
}
- src1 += vs->pitch;
- memcpy(dst + _macScreen->pitch, dst, width * 2);
-
- for (int i = 0; i < 2; i++) {
- for (int w = 0; w < width * 2; w++) {
- if (src2[w]) {
- dst[w] = src2[w];
- }
- }
- src2 += _textSurface.pitch;
- dst += _macScreen->pitch;
- }
+ pixels += pixelsPitch;
+ ts += tsPitch * 2;
+ mac += macPitch * 2;
}
_system->copyRectToScreen(_macScreen->getBasePtr(x * 2, y * 2), _macScreen->pitch, x * 2, y * 2, width * 2, height * 2);
@@ -826,7 +823,7 @@ void ScummEngine::mac_restoreCharsetBg() {
_charset->_str.left = -1;
_charset->_left = -1;
- _textSurface.fillRect(Common::Rect(_textSurface.w, _textSurface.h), 0);
+ clearTextSurface();
VirtScreen *vs = &_virtscr[_charset->_textScreenID];
if (!vs->h)
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 3520ba6124..cc38233d7f 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1096,6 +1096,7 @@ public:
*/
Graphics::Surface _textSurface;
int _textSurfaceMultiplier;
+ Graphics::Surface *_macScreen;
protected:
byte _charsetColor;
@@ -1381,7 +1382,6 @@ protected:
byte _townsActiveLayerFlags;
static const uint8 _townsLayer2Mask[];
- Graphics::Surface *_macScreen;
TownsScreen *_townsScreen;
#else
void scrollLeft() { redrawBGStrip(_gdi->_numStrips - 1, 1); }
Commit: ec6f0b1cf3c0a396cedbeead54277ba13068eced
https://github.com/scummvm/scummvm/commit/ec6f0b1cf3c0a396cedbeead54277ba13068eced
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Some fixes for removing text
Drawing boxes and restoring verb backgrounds now also clears the text
surface in Macintosh Loom.
Changed paths:
engines/scumm/gfx.cpp
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index c31d93a536..b57f64d74b 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -1151,6 +1151,11 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) {
}
#endif
+ if (_macScreen) {
+ byte *mask = (byte *)_textSurface.getBasePtr(rect.left * _textSurfaceMultiplier, (rect.top + vs->topline) * _textSurfaceMultiplier);
+ fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel);
+ }
+
if (_game.features & GF_16BIT_COLOR)
fill(screenBuf, vs->pitch, _16BitPalette[backColor], width, height, vs->format.bytesPerPixel);
else
@@ -1450,6 +1455,11 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) {
}
#endif
+ if (_macScreen) {
+ byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop + vs->topline) * _textSurfaceMultiplier);
+ fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel);
+ }
+
fill(backbuff, vs->pitch, color, width, height, vs->format.bytesPerPixel);
}
}
Commit: 93cbb988a69d50a50bb80edf235ebbfbee1b49e1
https://github.com/scummvm/scummvm/commit/93cbb988a69d50a50bb80edf235ebbfbee1b49e1
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Some fixes that I'm not sure exactly what they do
I don't know what these fixes do exactly, but judging by the old code
they should be there.
Changed paths:
engines/scumm/charset.cpp
engines/scumm/saveload.cpp
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 79a33e6f42..adc5f20603 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1636,6 +1636,13 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
_str.right = right;
_str.bottom = top;
_firstChar = false;
+ } else {
+ if (_str.left > left)
+ _str.left = left;
+ if (_str.right < right)
+ _str.right = right;
+ if (_str.bottom < bottom)
+ _str.bottom = bottom;
}
_vm->markRectAsDirty(vs->number, left, right, top - vs->topline, bottom - vs->topline);
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 458b8f87db..81b0ad2799 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -555,6 +555,8 @@ bool ScummEngine::loadState(int slot, bool compat, Common::String &filename) {
// Reset charset mask
_charset->_hasMask = false;
+ if (_macScreen)
+ _macScreen->fillRect(Common::Rect(_macScreen->w, _macScreen->h), 0);
clearTextSurface();
_lastCodePtr = NULL;
Commit: 3ef517d2a1c3976a4455bb5a0806eec404b6df21
https://github.com/scummvm/scummvm/commit/3ef517d2a1c3976a4455bb5a0806eec404b6df21
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Fix some memory leaks
I forgot to free the streams after asking the Mac resource manager for a
resource.
Changed paths:
engines/scumm/charset.cpp
engines/scumm/cursor.cpp
engines/scumm/players/player_v3m.cpp
engines/scumm/players/player_v5m.cpp
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index adc5f20603..15a455752c 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1554,12 +1554,14 @@ CharsetRendererMac::CharsetRendererMac(ScummEngine *vm, const Common::String &fo
}
}
}
+ delete fond;
}
assert(fontId);
Common::SeekableReadStream *font = resource.getResource(MKTAG('F', 'O', 'N', 'T'), fontId);
_macFont.loadFont(*font, &fontFamily, 13, 0);
+ delete font;
}
}
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 13faef70ec..83961ee931 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -605,8 +605,10 @@ void ScummEngine_v5::setBuiltinCursor(int idx) {
Graphics::MacCursor macCursor;
if (macCursor.readFromStream(*curs)) {
CursorMan.replaceCursor(&macCursor);
+ delete curs;
return;
}
+ delete curs;
}
}
diff --git a/engines/scumm/players/player_v3m.cpp b/engines/scumm/players/player_v3m.cpp
index b228440a1a..0fcf6170b4 100644
--- a/engines/scumm/players/player_v3m.cpp
+++ b/engines/scumm/players/player_v3m.cpp
@@ -142,7 +142,9 @@ bool Player_V3M::loadMusic(const byte *ptr) {
if (_channel[i].loadInstrument(stream)) {
debug(6, "Player_V3M::loadMusic: Channel %d - Loaded Instrument %d (%s)", i, instrument, resource.getResName(RES_SND, instrument).c_str());
+ delete stream;
} else {
+ delete stream;
return false;
}
}
diff --git a/engines/scumm/players/player_v5m.cpp b/engines/scumm/players/player_v5m.cpp
index b8529ce823..f40f59fa11 100644
--- a/engines/scumm/players/player_v5m.cpp
+++ b/engines/scumm/players/player_v5m.cpp
@@ -121,9 +121,11 @@ bool Player_V5M::loadMusic(const byte *ptr) {
if (!_channel[i].loadInstrument(stream)) {
resource.close();
+ delete stream;
return false;
}
+ delete stream;
break;
}
}
Commit: 9051349f31ac7306e5947d1ee8de6eb57dffead6
https://github.com/scummvm/scummvm/commit/9051349f31ac7306e5947d1ee8de6eb57dffead6
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Always draw notes and note names with a shadow in Mac Loom
But apparently the shadow for notes is a bit different from what I draw.
I have to figure that one out later.
Changed paths:
engines/scumm/charset.cpp
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 15a455752c..6d26b2f42e 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1604,7 +1604,13 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
_pad = false;
}
- if (_enableShadow) {
+ bool enableShadow = _enableShadow;
+
+ // HACK: Notes and their names shoudl always be drawn with a shadow.
+ if ((chr >= 16 && chr <= 23) || chr == 60 || chr == 95)
+ enableShadow = true;
+
+ if (enableShadow) {
_macFont.drawChar(&_vm->_textSurface, chr, macLeft + 2, macTop, 0);
_macFont.drawChar(&_vm->_textSurface, chr, macLeft, macTop + 2, 0);
_macFont.drawChar(&_vm->_textSurface, chr, macLeft + 3, macTop + 3, 0);
@@ -1620,7 +1626,7 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
int left, right, top, bottom;
- if (_enableShadow) {
+ if (enableShadow) {
left = macLeft / 2;
right = (macLeft + _macFont.getCharWidth(chr) + 3) / 2;
top = macTop / 2;
Commit: 620d885eac8738f38ae02935bc0d459697843f77
https://github.com/scummvm/scummvm/commit/620d885eac8738f38ae02935bc0d459697843f77
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Clarify comment about shadowed text in Mac Loom
Changed paths:
engines/scumm/charset.cpp
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 6d26b2f42e..c23a49d79c 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1606,7 +1606,17 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
bool enableShadow = _enableShadow;
- // HACK: Notes and their names shoudl always be drawn with a shadow.
+ // Shadowing is a bit of guesswork. It doesn't look like it's using
+ // the Mac's built-in form of shadowed text (which, as I recall it,
+ // never looked particularly good anyway). This seems to match the
+ // original look for normal text.
+
+ // HACK: Notes and their names should always be drawn with a shadow.
+ // Actually, this doesn't quite match the original but I can't
+ // figure out what the original does here. The "c" looks like
+ // it's shadowed in the normal way, but everything else looks
+ // kind-of-but-not-quite outlined instead. Weird.
+
if ((chr >= 16 && chr <= 23) || chr == 60 || chr == 95)
enableShadow = true;
Commit: cdfe9b5b4c664bcd3ffe8692e0e2000c4066396f
https://github.com/scummvm/scummvm/commit/cdfe9b5b4c664bcd3ffe8692e0e2000c4066396f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Add practice mode box for Mac Loom
Unlike the PC version, the practice mode box appears to be hard-coded in
the Mac version. The script that draws the box in the PC version just
sets variables in the Mac version. This implementation is based on
screenshots.
To keep things a bit saner, I've split out the Mac-specific drawing to
its own file.
Changed paths:
A engines/scumm/gfx_mac.cpp
engines/scumm/charset.cpp
engines/scumm/charset.h
engines/scumm/gfx.cpp
engines/scumm/module.mk
engines/scumm/script.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index c23a49d79c..4303e65bd6 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1616,6 +1616,10 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
// figure out what the original does here. The "c" looks like
// it's shadowed in the normal way, but everything else looks
// kind-of-but-not-quite outlined instead. Weird.
+ //
+ // Even weirder, I've seen screenshots where there is no
+ // shadowing at all. I'll just keep it like this for now,
+ // because it makes the notes stand out a bit better.
if ((chr >= 16 && chr <= 23) || chr == 60 || chr == 95)
enableShadow = true;
@@ -1681,6 +1685,10 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
_lastTop = _top;
}
+void CharsetRendererMac::drawChar(int chr, Graphics::Surface &s, int x, int y) {
+ _macFont.drawChar(&s, chr, x, y, _color);
+}
+
void CharsetRendererMac::setColor(byte color) {
_color = color;
_enableShadow = false;
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index 7be747b5e6..678d1246da 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -288,6 +288,7 @@ public:
int getFontHeight() override;
int getCharWidth(uint16 chr) override;
void printChar(int chr, bool ignoreCharsetMask) override;
+ void drawChar(int chr, Graphics::Surface &s, int x, int y) override;
void setColor(byte color) override;
};
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index b57f64d74b..d2549dbe1d 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -785,54 +785,6 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
_system->copyRectToScreen(src, pitch, x, y, width, height);
}
- void ScummEngine::mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height) {
- const byte *pixels = vs->getPixels(x, top);
- const byte *ts = (byte *)_textSurface.getBasePtr(x * 2, y * 2);
- byte *mac = (byte *)_macScreen->getBasePtr(x * 2, y * 2);
-
- int pixelsPitch = vs->pitch;
- int tsPitch = _textSurface.pitch;
- int macPitch = _macScreen->pitch;
-
- for (int h = 0; h < height; h++) {
- for (int w = 0; w < width; w++) {
- if (ts[2 * w] == CHARSET_MASK_TRANSPARENCY)
- mac[2 * w] = pixels[w];
- if (ts[2 * w + 1] == CHARSET_MASK_TRANSPARENCY)
- mac[2 * w + 1] = pixels[w];
- if (ts[2 * w + tsPitch] == CHARSET_MASK_TRANSPARENCY)
- mac[2 * w + macPitch] = pixels[w];
- if (ts[2 * w + tsPitch + 1] == CHARSET_MASK_TRANSPARENCY)
- mac[2 * w + macPitch + 1] = pixels[w];
- }
-
- pixels += pixelsPitch;
- ts += tsPitch * 2;
- mac += macPitch * 2;
- }
-
- _system->copyRectToScreen(_macScreen->getBasePtr(x * 2, y * 2), _macScreen->pitch, x * 2, y * 2, width * 2, height * 2);
-}
-
-void ScummEngine::mac_restoreCharsetBg() {
- _nextLeft = _string[0].xpos;
- _nextTop = _string[0].ypos + _screenTop;
-
- if (_charset->_hasMask) {
- _charset->_hasMask = false;
- _charset->_str.left = -1;
- _charset->_left = -1;
-
- clearTextSurface();
-
- VirtScreen *vs = &_virtscr[_charset->_textScreenID];
- if (!vs->h)
- return;
-
- markRectAsDirty(vs->number, Common::Rect(vs->w, vs->h), USAGE_BIT_RESTORED);
- }
-}
-
// CGA
// indy3 loom maniac monkey1 zak
//
diff --git a/engines/scumm/gfx_mac.cpp b/engines/scumm/gfx_mac.cpp
new file mode 100644
index 0000000000..ebab3942f2
--- /dev/null
+++ b/engines/scumm/gfx_mac.cpp
@@ -0,0 +1,121 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "scumm/charset.h"
+#include "scumm/usage_bits.h"
+
+namespace Scumm {
+
+void ScummEngine::mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height) {
+ const byte *pixels = vs->getPixels(x, top);
+ const byte *ts = (byte *)_textSurface.getBasePtr(x * 2, y * 2);
+ byte *mac = (byte *)_macScreen->getBasePtr(x * 2, y * 2);
+
+ int pixelsPitch = vs->pitch;
+ int tsPitch = _textSurface.pitch;
+ int macPitch = _macScreen->pitch;
+
+ for (int h = 0; h < height; h++) {
+ for (int w = 0; w < width; w++) {
+ if (ts[2 * w] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w] = pixels[w];
+ if (ts[2 * w + 1] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w + 1] = pixels[w];
+ if (ts[2 * w + tsPitch] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w + macPitch] = pixels[w];
+ if (ts[2 * w + tsPitch + 1] == CHARSET_MASK_TRANSPARENCY)
+ mac[2 * w + macPitch + 1] = pixels[w];
+ }
+
+ pixels += pixelsPitch;
+ ts += tsPitch * 2;
+ mac += macPitch * 2;
+ }
+
+ _system->copyRectToScreen(_macScreen->getBasePtr(x * 2, y * 2), _macScreen->pitch, x * 2, y * 2, width * 2, height * 2);
+}
+
+void ScummEngine::mac_restoreCharsetBg() {
+ _nextLeft = _string[0].xpos;
+ _nextTop = _string[0].ypos + _screenTop;
+
+ if (_charset->_hasMask) {
+ _charset->_hasMask = false;
+ _charset->_str.left = -1;
+ _charset->_left = -1;
+
+ clearTextSurface();
+
+ VirtScreen *vs = &_virtscr[_charset->_textScreenID];
+ if (!vs->h)
+ return;
+
+ markRectAsDirty(vs->number, Common::Rect(vs->w, vs->h), USAGE_BIT_RESTORED);
+ }
+}
+
+void ScummEngine::mac_drawLoomPracticeMode() {
+ // In practice mode, the game shows the notes as they are being played.
+ // In the DOS version, this is drawn by script 27 but the Mac version
+ // just sets variables 50 and 54. I'm not sure what the difference
+ // between the two is.
+
+ int x = 216;
+ int y = 377;
+ int width = 62;
+ int height = 22;
+ int var = 50;
+
+ byte *ptr = (byte *)_macScreen->getBasePtr(x, y);
+ int pitch = _macScreen->pitch;
+
+ _macScreen->fillRect(Common::Rect(x, y, x + width, y + height), 0);
+
+ if (VAR(var)) {
+ for (int w = 1; w < width - 1; w++) {
+ ptr[w] = 7;
+ ptr[w + pitch * (height - 1)] = 7;
+ }
+
+ for (int h = 1; h < height - 1; h++) {
+ ptr[h * pitch] = 7;
+ ptr[h * pitch + width - 1] = 7;
+ }
+
+ // Draw the notes
+ int colors[] = { 4, 12, 14, 10, 11, 3, 9, 15 };
+
+ for (int i = 0; i < 4; i++) {
+ int note = (VAR(var) >> (4 * i)) & 0x0F;
+
+ if (note >= 2 && note <= 9) {
+ _charset->setColor(colors[note - 2]);
+ _charset->drawChar(14 + note, *_macScreen, i * 13 + x + 8, y + 4);
+ }
+ }
+ }
+
+ _system->copyRectToScreen(ptr, pitch, x, y, width, height);
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 36d7871da8..b5b725ddda 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS := \
dialogs.o \
file.o \
file_nes.o \
+ gfx_mac.o \
gfx_towns.o \
gfx.o \
he/resource_he.o \
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 84d78030a7..723d3f509d 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -651,6 +651,23 @@ void ScummEngine::writeVar(uint var, int value) {
_scummVars[var] = value;
+ // Unlike the PC version, the Macintosh version of Loom appears
+ // to hard-code the drawing of the practice mode box. This is
+ // handled by script 27 in both versions, but wherease the PC
+ // version draws the notes, the the Mac version this just sets
+ // variables 50 and 54.
+ //
+ // In this script, the variables are set to the same value but
+ // it appears that only variable 50 is cleared when the box is
+ // supposed to disappear. I don't know what the purpose of
+ // variable 54 is.
+
+ if (_game.id == GID_LOOM && _game.platform == Common::kPlatformMacintosh) {
+ if (VAR(128) == 0 && var == 50) {
+ mac_drawLoomPracticeMode();
+ }
+ }
+
if ((_varwatch == (int)var || _varwatch == 0) && _currentScript < NUM_SCRIPT_SLOT) {
if (vm.slot[_currentScript].number < 100)
debug(1, "vars[%d] = %d (via script-%d)", var, value, vm.slot[_currentScript].number);
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index cc38233d7f..3c815866a7 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -955,6 +955,8 @@ protected:
void drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom);
void mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height);
void mac_restoreCharsetBg();
+ void mac_drawLoomPracticeMode();
+
void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
public:
Commit: c0c072f4c4a24294ab997a6d191c6c5784d13d68
https://github.com/scummvm/scummvm/commit/c0c072f4c4a24294ab997a6d191c6c5784d13d68
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Add hack against Mac Loom distaff glitch
Here is what I think happens: When text is removed, the text surface is
cleared in its entirety. This means that the next time the screen is
updated, it may redraw the low-resolution background. Since this has no
information about the high-resolution text, any such text is lost.
The distaff notes and note names are drawn in with the high-resolution
font. When using the distaff, only the note name is redrawn, not the
note itself. The way screen updates are handled, a larger area than just
the note name gets redrawn, and then part of the note may be cleared
away.
To get around this, when a note name is drawn on the distaff the text
surface is also updated with the note itself. (There is no need to
redraw the note, since we can assume it's already on screen, and we
don't want to bother with getting the color right.)
The only time the printChar() function prints note names should be on
the distaff. The Practice Mode box is handled by drawChar() instead.
Changed paths:
engines/scumm/charset.cpp
engines/scumm/charset.h
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 4303e65bd6..60ede8a26b 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1624,17 +1624,26 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
if ((chr >= 16 && chr <= 23) || chr == 60 || chr == 95)
enableShadow = true;
- if (enableShadow) {
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 2, macTop, 0);
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft, macTop + 2, 0);
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 3, macTop + 3, 0);
- _macFont.drawChar(_vm->_macScreen, chr, macLeft + 2, macTop, _shadowColor);
- _macFont.drawChar(_vm->_macScreen, chr, macLeft, macTop + 2, _shadowColor);
- _macFont.drawChar(_vm->_macScreen, chr, macLeft + 3, macTop + 3, _shadowColor);
- }
+ printCharInternal(chr, _color, enableShadow, macLeft, macTop);
- _macFont.drawChar(&_vm->_textSurface, chr, macLeft + 1, macTop + 1, 0);
- _macFont.drawChar(_vm->_macScreen, chr, macLeft + 1, macTop + 1, _color);
+ // HACK: The way we combine high and low resolution graphics means
+ // that sometimes, when a note name is drawn on the distaff, the
+ // note itself gets overdrawn by the low-resolution graphics.
+ //
+ // The only workaround I can think of is to force the note to be
+ // redrawn along with its name. It's enough to redraw it on the
+ // text surface. We can assume the correct color is already on
+ // screen.
+ //
+ // Note that this will not affect the Practice Mode box, since
+ // this note names are drawn by drawChar(), not printChar().
+
+ if (chr >= 16 && chr <= 23) {
+ int xOffset[] = { 16, 14, 12, 8, 6, 2, 0, 8 };
+
+ int note = (chr == 23) ? 60 : 95;
+ printCharInternal(note, -1, enableShadow, macLeft + 18, macTop + xOffset[chr - 16]);
+ }
// Mark the virtual screen as dirty, using downscaled coordinates.
@@ -1685,6 +1694,25 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
_lastTop = _top;
}
+void CharsetRendererMac::printCharInternal(int chr, int color, bool shadow, int x, int y) {
+ if (shadow) {
+ _macFont.drawChar(&_vm->_textSurface, chr, x + 2, y, 0);
+ _macFont.drawChar(&_vm->_textSurface, chr, x, y + 2, 0);
+ _macFont.drawChar(&_vm->_textSurface, chr, x + 3, y + 3, 0);
+
+ if (color != -1) {
+ _macFont.drawChar(_vm->_macScreen, chr, x + 2, y, _shadowColor);
+ _macFont.drawChar(_vm->_macScreen, chr, x, y + 2, _shadowColor);
+ _macFont.drawChar(_vm->_macScreen, chr, x + 3, y + 3, _shadowColor);
+ }
+ }
+
+ _macFont.drawChar(&_vm->_textSurface, chr, x + 1, y + 1, 0);
+
+ if (color != -1)
+ _macFont.drawChar(_vm->_macScreen, chr, x + 1, y + 1, color);
+}
+
void CharsetRendererMac::drawChar(int chr, Graphics::Surface &s, int x, int y) {
_macFont.drawChar(&s, chr, x, y, _color);
}
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index 678d1246da..d8dc1c13f9 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -281,6 +281,8 @@ protected:
bool _pad;
int _lastTop;
+ void printCharInternal(int chr, int color, bool shadow, int x, int y);
+
public:
CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile);
Commit: f8c4fe63e33c6bfe8008dd8429121938e335a0b2
https://github.com/scummvm/scummvm/commit/f8c4fe63e33c6bfe8008dd8429121938e335a0b2
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-05-17T18:44:29+02:00
Commit Message:
SCUMM: Hack Mac Loom note names to never be light gray
Note names can be drawn in three different colors: Dark gray for notes
you don't know, light gray for notes you know, and white for notes
you're using.
Or at least, that's how the DOS version does it. But there, notes
automatically go back to light gray once the draft is done. In the Mac
version, that doesn't seem to happen. And judging by how it behaves when
running it in a Mac emulator, known notes are always white.
Changed paths:
engines/scumm/charset.cpp
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 60ede8a26b..af4aae06bd 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1605,6 +1605,7 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
}
bool enableShadow = _enableShadow;
+ int color = _color;
// Shadowing is a bit of guesswork. It doesn't look like it's using
// the Mac's built-in form of shadowed text (which, as I recall it,
@@ -1621,10 +1622,20 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
// shadowing at all. I'll just keep it like this for now,
// because it makes the notes stand out a bit better.
- if ((chr >= 16 && chr <= 23) || chr == 60 || chr == 95)
+ if ((chr >= 16 && chr <= 23) || chr == 60 || chr == 95) {
enableShadow = true;
+ }
+
+ // HACK: Apparently, note names are never drawn in light gray. Only
+ // white for known notes, and dark gray for unknown ones. This
+ // hack ensures that we won't be left with a mix of white and
+ // light gray note names, because apparently the game never
+ // changes them back to light gray once the draft is done?
+
+ if (chr >= 16 && chr <= 23 && _color == 7)
+ color = 15;
- printCharInternal(chr, _color, enableShadow, macLeft, macTop);
+ printCharInternal(chr, color, enableShadow, macLeft, macTop);
// HACK: The way we combine high and low resolution graphics means
// that sometimes, when a note name is drawn on the distaff, the
More information about the Scummvm-git-logs
mailing list