[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