[Scummvm-git-logs] scummvm master -> d54ddce0a104dea45f31e58057b80d9efc700683
athrxx
noreply at scummvm.org
Sat Oct 22 13:37:36 UTC 2022
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
3c459416c3 SCUMM: (FM-TOWNS) - minor gfx performance boost
d54ddce0a1 SCUMM: (IMS/MT32) - reduced delay during device init
Commit: 3c459416c3484e49d2d039dd39d3e9c415874d84
https://github.com/scummvm/scummvm/commit/3c459416c3484e49d2d039dd39d3e9c415874d84
Author: athrxx (athrxx at scummvm.org)
Date: 2022-10-22T15:30:38+02:00
Commit Message:
SCUMM: (FM-TOWNS) - minor gfx performance boost
Changed paths:
engines/scumm/gfx.h
engines/scumm/gfx_towns.cpp
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index b9817dfc6e8..bcc006faeb6 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -490,9 +490,13 @@ public:
void fillLayerRect(int layer, int x, int y, int w, int h, int col);
void addDirtyRect(int x, int y, int w, int h);
void toggleLayers(int flags);
- void scrollLayers(int flags, int offset, bool fast);
+ void scrollLayer(int layer, int offset, int top, int bottom, bool fast);
void update();
- bool isScrolling(int direction, int threshold = 0) const { return (direction == 0) ? _scrollRemainder != threshold : (direction == 1 ? _scrollRemainder > threshold : _scrollRemainder < threshold); }
+ bool isScrolling(int layer, int direction, int threshold = 0) const {
+ return (layer & ~1) ? false :
+ (direction == 0 ? (_layers[layer].scrollRemainder != threshold) :
+ (direction == 1 ? (_layers[layer].scrollRemainder > threshold) : (_layers[layer].scrollRemainder < threshold)));
+ }
uint8 *getLayerPixels(int layer, int x, int y) const;
int getLayerPitch(int layer) const { assert (layer >= 0 && layer < 2); return _layers[layer].pitch; }
@@ -504,21 +508,21 @@ public:
private:
struct TownsScreenLayer {
- uint8 *pixels;
- uint8 *palette;
- int pitch;
- int width;
- int height;
- int bpp;
- int numCol;
- int hScroll;
- uint8 scaleW;
- uint8 scaleH;
- bool onBottom;
- bool enabled;
- bool ready;
-
- uint16 *bltTmpPal;
+ uint8 *pixels = nullptr;
+ uint8 *palette = nullptr;
+ int pitch = 0;
+ int width = 0;
+ int height = 0;
+ int bpp = 0;
+ int numCol = 0;
+ uint16 hScroll = 0;
+ uint8 scaleW = 0;
+ uint8 scaleH = 0;
+ int scrollRemainder = 0;
+ bool onBottom = false;
+ bool enabled = false;
+ bool ready = false;
+ uint16 *bltTmpPal= nullptr;
} _layers[2];
template<typename dstPixelType, typename srcPixelType, int scaleW, int scaleH, bool col4bit> void transferRect(uint8 *dst, TownsScreenLayer *l, int x, int y, int w, int h);
@@ -532,8 +536,6 @@ private:
int _height;
int _width;
int _pitch;
- uint16 _scrollOffset;
- int _scrollRemainder;
bool _semiSmoothScroll;
Graphics::PixelFormat _pixelFormat;
diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp
index e154e77df6b..aa99d621205 100644
--- a/engines/scumm/gfx_towns.cpp
+++ b/engines/scumm/gfx_towns.cpp
@@ -46,7 +46,8 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
uint8 *dst2 = _townsScreen->getLayerPixels(1, dstX * m, dstY * m);
int lw1 = _townsScreen->getLayerWidth(0);
- int dp2 = _townsScreen->getLayerPitch(1) - width * m * _townsScreen->getLayerBpp(1);
+ int lp1 = _townsScreen->getLayerPitch(1);
+ int dp2 = lp1 - width * m * _townsScreen->getLayerBpp(1);
int sp1 = vs->pitch - (width * vs->format.bytesPerPixel);
int sp2 = _textSurface.pitch - width * m;
@@ -84,32 +85,55 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
for (int h = 0; h < height * m; ++h) {
memcpy(dst2, src2, width * m);
src2 += _textSurface.pitch;
- dst2 += _townsScreen->getLayerPitch(1);
+ dst2 += lp1;
}
} else {
dst1 = dst2;
+ uint8 t = 0;
+ uint8 s2 = 0;
+ uint8 s3 = 0;
+
for (int h = 0; h < height; ++h) {
- for (int w = 0; w < width; ++w) {
- uint8 t = (*src1++) & 0x0f;
- memset(dst1, (t << 4) | t, m);
- dst1 += m;
+ if (m == 2) {
+ uint16 *d = reinterpret_cast<uint16*>(dst1);
+ for (int w = 0; w < width; ++w) {
+ t = (*src1++) & 0x0f;
+ t |= (t << 4);
+ *d++ = (t << 8) | t;
+ }
+ } else if (m == 1) {
+ for (int w = 0; w < width; ++w) {
+ t = (*src1++) & 0x0f;
+ *dst1++ = (t << 4) | t;
+ }
+ } else {
+ error ("ScummEngine::towns_drawStripToScreen(): Unexpected text surface multiplier %d", m);
}
dst1 = dst2;
const uint8 *src3 = src2;
if (m == 2) {
- dst2 += _townsScreen->getLayerPitch(1);
- src3 += _townsScreen->getLayerPitch(1);
- }
-
- for (int w = 0; w < width * m; ++w) {
- *dst2++ = (*src3 | (*dst1 & _townsLayer2Mask[*src3]));
- *dst1 = (*src2 | (*dst1 & _townsLayer2Mask[*src2]));
- src2++;
- src3++;
- dst1++;
+ dst2 += lp1;
+ src3 += lp1;
+ for (int w = 0; w < (width << 1); ++w) {
+ t = *dst1;
+ s2 = *src2++;
+ s3 = *src3++;
+ *dst2++ = (s3 | (t & _townsLayer2Mask[s3]));
+ *dst1++ = (s2 | (t & _townsLayer2Mask[s2]));
+ }
+ } else if (m== 1) {
+ dst2 += width;
+ src3 += width;
+ for (int w = 0; w < width; ++w) {
+ t = *dst1;
+ s2 = *src2++;
+ *dst1++ = (s2 | (t & _townsLayer2Mask[s2]));
+ }
+ } else {
+ error ("ScummEngine::towns_drawStripToScreen(): Unexpected text surface multiplier %d", m);
}
src1 += sp1;
@@ -177,7 +201,7 @@ void ScummEngine::requestScroll(int dir) {
}
void ScummEngine::towns_waitForScroll(int waitForDirection, int threshold) {
- while (!shouldQuit() && _townsScreen && (_scrollRequest || _townsScreen->isScrolling(waitForDirection, threshold)))
+ while (!shouldQuit() && _townsScreen && (_scrollRequest || _townsScreen->isScrolling(0, waitForDirection, threshold)))
waitForTimer(0);
}
@@ -199,12 +223,15 @@ void ScummEngine::towns_updateGfx() {
}
if (_enableSmoothScrolling) {
+ int scrlTop = _virtscr[kMainVirtScreen].topline * _textSurfaceMultiplier;
+ int scrlBottom = scrlTop + _virtscr[kMainVirtScreen].h * _textSurfaceMultiplier;
+
while (_scrollTimer <= cur) {
if (!_scrollTimer)
_scrollTimer = cur;
_scrollTimer += 1000 / 60;
- _townsScreen->scrollLayers(1, _scrollRequest, VAR(VAR_TIMER_NEXT) == 0);
- if (_scrollNeedDeltaAdjust && _townsScreen->isScrolling(0))
+ _townsScreen->scrollLayer(0, _scrollRequest, scrlTop, scrlBottom, VAR(VAR_TIMER_NEXT) == 0);
+ if (_scrollNeedDeltaAdjust && _townsScreen->isScrolling(0, 0))
_scrollDeltaAdjust++;
_scrollRequest = 0;
if (!_refreshNeedCatchUp)
@@ -246,12 +273,15 @@ void ScummEngine::towns_scriptScrollEffect(int dir) {
// Wait for opposite direction scroll to finish.
towns_waitForScroll(-dir);
+ int scrlTop = _virtscr[kMainVirtScreen].topline * _textSurfaceMultiplier;
+ int scrlBottom = scrlTop + _virtscr[kMainVirtScreen].h * _textSurfaceMultiplier;
+
for (int x = 0; !shouldQuit() && x < _gdi->_numStrips; ++x) {
_scrollDestOffset = (_scrollDestOffset - (dir << 3)) % layerW;
uint32 nextFrame = _system->getMillis() + 1000 / 60;
// Same as in requestScroll(): This prevents glitches from graphics layer wrapping.
towns_waitForScroll(dir, threshold);
- _townsScreen->scrollLayers(0, dir << 3, false);
+ _townsScreen->scrollLayer(0, dir << 3, scrlTop, scrlBottom, false);
towns_drawStripToScreen(vs, destX << 3, vs->topline, (srcX + (-dir * x)) << 3, 0, stripWidth, vs->h);
waitForTimer(nextFrame - _system->getMillis());
}
@@ -331,10 +361,7 @@ const uint8 ScummEngine::_townsLayer2Mask[] = {
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-TownsScreen::TownsScreen(OSystem *system) : _system(system), _width(0), _height(0), _pitch(0), _pixelFormat(system->getScreenFormat()), _scrollOffset(0), _scrollRemainder(0), _numDirtyRects(0) {
- memset(&_layers[0], 0, sizeof(TownsScreenLayer));
- memset(&_layers[1], 0, sizeof(TownsScreenLayer));
-
+TownsScreen::TownsScreen(OSystem *system) : _system(system), _width(0), _height(0), _pitch(0), _pixelFormat(system->getScreenFormat()), _numDirtyRects(0) {
Graphics::Surface *s = _system->lockScreen();
_width = s->w;
_height = s->h;
@@ -355,7 +382,7 @@ TownsScreen::~TownsScreen() {
}
void TownsScreen::setupLayer(int layer, int width, int height, int scaleW, int scaleH, int numCol, void *pal) {
- if (layer < 0 || layer > 1)
+ if (layer & ~1)
return;
TownsScreenLayer *l = &_layers[layer];
@@ -393,7 +420,7 @@ void TownsScreen::setupLayer(int layer, int width, int height, int scaleW, int s
}
void TownsScreen::clearLayer(int layer) {
- if (layer < 0 || layer > 1)
+ if (layer & ~1)
return;
TownsScreenLayer *l = &_layers[layer];
@@ -407,7 +434,7 @@ void TownsScreen::clearLayer(int layer) {
void TownsScreen::fillLayerRect(int layer, int x, int y, int w, int h, int col) {
- if (layer < 0 || layer > 1 || w <= 0 || h <= 0)
+ if ((layer & ~1) || w <= 0 || h <= 0)
return;
TownsScreenLayer *l = &_layers[layer];
@@ -434,7 +461,7 @@ void TownsScreen::fillLayerRect(int layer, int x, int y, int w, int h, int col)
}
uint8 *TownsScreen::getLayerPixels(int layer, int x, int y) const {
- if (layer < 0 || layer > 1)
+ if (layer & ~1)
return nullptr;
const TownsScreenLayer *l = &_layers[layer];
@@ -505,7 +532,7 @@ void TownsScreen::addDirtyRect(int x, int y, int w, int h) {
}
void TownsScreen::toggleLayers(int flags) {
- if (flags < 0 || flags > 3)
+ if (flags & ~3)
return;
_layers[0].enabled = (flags & 1) ? true : false;
@@ -526,13 +553,20 @@ void TownsScreen::toggleLayers(int flags) {
_system->updateScreen();
}
-void TownsScreen::scrollLayers(int flags, int offset, bool fast) {
+void TownsScreen::scrollLayer(int layer, int offset, int top, int bottom, bool fast) {
+ if (layer & ~1)
+ return;
+
// This actually supports layer 0 only, since this is all we need.
- _scrollRemainder += offset;
- if (!_scrollRemainder)
+ TownsScreenLayer *l = &_layers[layer];
+ if (!l->ready)
+ return;
+
+ l->scrollRemainder += offset;
+ if (!l->scrollRemainder)
return;
- int step = (_scrollRemainder > 0) ? -1 : 1;
+ int step = (l->scrollRemainder > 0) ? -1 : 1;
// Smooth scrolling isn't fast enough to keep up with the fast camera
// movement in the Loom intro. Non-smooth scrolling is eight pixels at
@@ -541,20 +575,14 @@ void TownsScreen::scrollLayers(int flags, int offset, bool fast) {
if (fast && _semiSmoothScroll)
step *= 4;
- _scrollRemainder += step;
- _scrollOffset = (_scrollOffset + step) % _layers[0].width;
+ l->scrollRemainder += step;
+ l->hScroll += step;
+ l->hScroll %= l->width;
- _dirtyRects.clear();
- _dirtyRects.push_back(Common::Rect(_width - 1, _height - 1));
- _numDirtyRects = kFullRedraw;
+ if (top == 0 && bottom == _height - 1)
+ _numDirtyRects = kDirtyRectsMax;
- for (int i = 0; i < 2; ++i) {
- if (!(flags & (1 << i)))
- continue;
- TownsScreenLayer *l = &_layers[i];
- if (l->ready)
- l->hScroll = _scrollOffset % l->width;
- }
+ addDirtyRect(0, top, _width, bottom - top);
}
void TownsScreen::update() {
Commit: d54ddce0a104dea45f31e58057b80d9efc700683
https://github.com/scummvm/scummvm/commit/d54ddce0a104dea45f31e58057b80d9efc700683
Author: athrxx (athrxx at scummvm.org)
Date: 2022-10-22T15:36:19+02:00
Commit Message:
SCUMM: (IMS/MT32) - reduced delay during device init
The delays were way longer than necessary.
Also removed some unnecessary percussion channel code
that caused issues on real hardware.
Changed paths:
engines/scumm/imuse/drivers/midi.cpp
engines/scumm/imuse/drivers/midi.h
diff --git a/engines/scumm/imuse/drivers/midi.cpp b/engines/scumm/imuse/drivers/midi.cpp
index cdb7d09183e..456570785d5 100644
--- a/engines/scumm/imuse/drivers/midi.cpp
+++ b/engines/scumm/imuse/drivers/midi.cpp
@@ -435,11 +435,6 @@ MidiChannel *IMuseDriver_GMidi::getPercussionChannel() {
return nullptr;
IMuseChannel_Midi *ch = getPart(9);
- if (ch) {
- ch->release();
- ch->allocate();
- }
-
return ch;
}
@@ -862,21 +857,29 @@ IMuseDriver_MT32::IMuseDriver_MT32(MidiDriver::DeviceHandle dev, bool newSystem)
}
void IMuseDriver_MT32::initDevice() {
+ // Display a welcome message on MT-32 displays. Compute version string (truncated to 20 chars max.)
+ Common::String infoStr = gScummVMVersion;
+ infoStr = "ScummVM " + infoStr.substr(0, MIN<uint32>(infoStr.findFirstNotOf("0123456789."), 12));
+ for (int i = (20 - (int)infoStr.size()) >> 1; i > 0; --i)
+ infoStr = ' ' + infoStr + ' ';
+ sendMT32Sysex(0x80000, (const byte*)infoStr.c_str(), MIN<uint32>(infoStr.size(), 20));
+
// Reset the MT-32
sendMT32Sysex(0x1FC000, 0, 0);
+
g_system->delayMillis(250);
- // Setup master tune, reverb mode, reverb time, reverb level,
- // channel mapping, partial reserve and master volume
+ // Setup master tune, reverb mode, reverb time, reverb level, channel mapping, partial reserve and master volume
static const char initSysex1[] = "\x40\x00\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x64";
sendMT32Sysex(0x40000, (const byte*)initSysex1, sizeof(initSysex1) - 1);
- g_system->delayMillis(250);
+ g_system->delayMillis(40);
if (!_newSystem) {
// Map percussion to notes 24 - 34 without reverb. It still happens in the DOTT driver, but not in the SAMNMAX one.
- static const char initSysex2[] = "\x40\x64\x07\x00\x4a\x64\x06\x00\x41\x64\x07\x00\x4b\x64\x08\x00\x45\x64\x06\x00\x44\x64\x0b\x00\x51\x64\x05\x00\x43\x64\x08\x00\x50\x64\x07\x00\x42\x64\x03\x00\x4c\x64\x07\x00";
+ static const char initSysex2[] = "\x40\x64\x07\x00\x4a\x64\x06\x00\x41\x64\x07\x00\x4b\x64\x08\x00\x45\x64\x06\x00\x44\x64"
+ "\x0b\x00\x51\x64\x05\x00\x43\x64\x08\x00\x50\x64\x07\x00\x42\x64\x03\x00\x4c\x64\x07\x00";
sendMT32Sysex(0xC090, (const byte*)initSysex2, sizeof(initSysex2) - 1);
- g_system->delayMillis(250);
+ g_system->delayMillis(40);
}
const byte pbRange = 0x10;
@@ -889,16 +892,18 @@ void IMuseDriver_MT32::initDevice() {
send(0x0000C0 | i);
send(0x0040B0 | i);
send(0x007BB0 | i);
+ send(0x3F0AB0 | i);
+ send(0x4000E0 | i);
}
+}
- // Display a welcome message on MT-32 displays. Compute version string (truncated to 20 chars max.)
- Common::String infoStr = gScummVMVersion;
- infoStr = "ScummVM " + infoStr.substr(0, MIN<uint32>(infoStr.findFirstNotOf("0123456789."), 12));
-
- for (int i = (20 - (int)infoStr.size()) >> 1; i > 0; --i)
- infoStr = ' ' + infoStr + ' ';
- sendMT32Sysex(0x80000, (const byte*)infoStr.c_str(), MIN<uint32>(infoStr.size(), 20));
- g_system->delayMillis(1000);
+void IMuseDriver_MT32::deinitDevice() {
+ for (int i = 0; i < 16; ++i) {
+ send(0x0040B0 | i);
+ send(0x007BB0 | i);
+ }
+ // Reset the MT-32
+ sendMT32Sysex(0x1FC000, 0, 0);
}
void IMuseDriver_MT32::createChannels() {
@@ -963,7 +968,8 @@ void IMuseDriver_MT32::sendMT32Sysex(uint32 addr, const byte *data, uint32 dataS
*dst++ = checkSum & 0x7F;
- sysEx(msg, dst - msg);
+ dataSize = dst - msg;
+ sysEx(msg, dataSize);
delete[] msg;
}
diff --git a/engines/scumm/imuse/drivers/midi.h b/engines/scumm/imuse/drivers/midi.h
index 687a746986f..1c072c4dce8 100644
--- a/engines/scumm/imuse/drivers/midi.h
+++ b/engines/scumm/imuse/drivers/midi.h
@@ -93,6 +93,7 @@ public:
private:
void initDevice() override;
+ void deinitDevice() override;
void createChannels() override;
void createParts() override;
void releaseChannels() override;
More information about the Scummvm-git-logs
mailing list