[Scummvm-git-logs] scummvm master -> 0d0dae8ef1274c732c17947a5c265f9ec5468446

bluegr noreply at scummvm.org
Sun Feb 1 09:41:15 UTC 2026


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
0d0dae8ef1 AGOS: Implement font squeezing routine for DOS Personal Nightmare and the Amiga Elvira 1 demo


Commit: 0d0dae8ef1274c732c17947a5c265f9ec5468446
    https://github.com/scummvm/scummvm/commit/0d0dae8ef1274c732c17947a5c265f9ec5468446
Author: Robert Megone (robert.megone at gmail.com)
Date: 2026-02-01T11:41:11+02:00

Commit Message:
AGOS: Implement font squeezing routine for DOS Personal Nightmare and the Amiga Elvira 1 demo

Changed paths:
    engines/agos/agos.h
    engines/agos/charset-fontdata.cpp


diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index fb30efcc2d3..d07229f7480 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -690,6 +690,7 @@ protected:
 	void readGamePcFile(Common::SeekableReadStream *in);
 	void decompressData(const char *srcName, byte *dst, uint32 offset, uint32 srcSize, uint32 dstSize);
 	void decompressPN(Common::Stack<uint32> &dataList, uint8 *&dataOut, int &dataOutSize);
+	void drawPnSqueezedChar(WindowBlock *window, uint x, uint y, byte chr);
 	void loadOffsets(const char *filename, int number, uint32 &file, uint32 &offset, uint32 &compressedSize, uint32 &size);
 	void loadSound(uint16 sound, int16 pan, int16 vol, uint16 type);
 	void playSfx(uint16 sound, uint16 freq, uint16 flags, bool digitalOnly = false, bool midiOnly = false);
@@ -1389,6 +1390,7 @@ public:
 	void setupGame() override;
 	void setupOpcodes() override;
 	void setupVideoOpcodes(VgaOpcodeProc *op) override;
+	void windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) override;
 
 	void executeOpcode(int opcode) override;
 
diff --git a/engines/agos/charset-fontdata.cpp b/engines/agos/charset-fontdata.cpp
index 31af93f93f3..f41f234eba7 100644
--- a/engines/agos/charset-fontdata.cpp
+++ b/engines/agos/charset-fontdata.cpp
@@ -3025,7 +3025,91 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
 	_videoLockOut &= ~0x8000;
 }
 
+static inline byte pnPreserveBit7ShiftLeft1(byte x) {
+	byte shifted = (byte)(x << 1);
+	if (x & 0x80)
+		shifted |= 0x80;
+	return shifted;
+}
+
+static inline byte pnSqueezeRow(byte rawRow, bool anyBit1SetAcrossGlyph) {
+	byte x = pnPreserveBit7ShiftLeft1(rawRow);
+
+	byte hi = (byte)(x & 0xF0);
+	byte lo = (byte)(x & 0x0F);
+
+	if (anyBit1SetAcrossGlyph)
+		lo = (byte)(lo << 1);
+
+	byte combined = (byte)(hi | lo);
+	combined = (byte)(combined & 0xFC);
+	return combined;
+}
+
+static inline void pnSqueezeGlyph8Rows(const byte *src8, byte *dst8) {
+	byte orAll = 0;
+	for (int i = 0; i < 8; i++)
+		orAll = (byte)(orAll | src8[i]);
+
+	const bool anyBit1SetAcrossGlyph = (orAll & 0x02) != 0;
+
+	for (int i = 0; i < 8; i++)
+		dst8[i] = pnSqueezeRow(src8[i], anyBit1SetAcrossGlyph);
+}
+
+void AGOSEngine::drawPnSqueezedChar(WindowBlock *window, uint x, uint y, byte chr) {
+	const byte *src;
+	byte color, *dst;
+	uint dstPitch, h, w, i;
+
+	if (chr < 32 || (chr - 32) > 98)
+		return;
+
+	Graphics::Surface *screen = getBackendSurface();
+
+	dst = (byte *)screen->getPixels();
+	dstPitch = screen->pitch;
+	h = 8;
+	w = 6;
+
+	src = english_pnFont + (chr - 32) * 8;
+
+	byte pnTmp[8];
+	pnSqueezeGlyph8Rows(src, pnTmp);
+	src = pnTmp;
+
+	dst += y * dstPitch + x + window->textColumnOffset;
+
+	color = window->textColor;
+
+	do {
+		int8 b = *src++;
+		i = 0;
+		do {
+			if (b < 0) {
+				dst[i] = color;
+			}
+			b <<= 1;
+		} while (++i != w);
+		dst += dstPitch;
+	} while (--h);
+
+	Common::Rect dirtyRect(x + window->textColumnOffset, y,
+	                       x + window->textColumnOffset + 6, y + 8);
+	updateBackendSurface(&dirtyRect);
+}
+
+void AGOSEngine_PN::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
+	_videoLockOut |= 0x8000;
+	drawPnSqueezedChar(window, x, y, chr);
+	_videoLockOut &= ~0x8000;
+}
+
 void AGOSEngine_Elvira1::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
+	if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_DEMO)) {
+		drawPnSqueezedChar(window, x, y, chr);
+		return;
+	}
 	if (_language != Common::JA_JPN || _forceAscii) {
 		AGOSEngine::windowDrawChar(window, x, y, chr);
 		return;




More information about the Scummvm-git-logs mailing list