[Scummvm-git-logs] scummvm master -> 6b7d038907e1979a69c427beb47fd5ed31087079
sev-
noreply at scummvm.org
Mon Jun 29 23:10:18 UTC 2026
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
a0231068a0 CHAMBER: Fix EGA spot-backup overflow corrupting backbuffer top
3fd28dcd30 CHAMBER: Fix vort/turkey timer comparison endianness
6b7d038907 CHAMBER: Fix EGA zone scan covering only a quarter of the screen width
Commit: a0231068a0dca75477b40b20f4a600d792cbfac3
https://github.com/scummvm/scummvm/commit/a0231068a0dca75477b40b20f4a600d792cbfac3
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-06-30T01:10:12+02:00
Commit Message:
CHAMBER: Fix EGA spot-backup overflow corrupting backbuffer top
In rooms with animated spots (e.g. "Placating the Powers"), garbage
pixels were stamped into the top rows of the EGA backbuffer.
backupSpotsImages() saves the background under each spot into a region
that starts at scratch_mem1, while lutin sprites load right after it at
scratch_mem2 (scratch_mem1 + 1500). That 1500-byte gap is the original
CGA budget, but EGA stores each backup as CLUT8 (4 bytes per CGA byte),
so the backups need up to 4*1500 = 6000 bytes. They spilled past
scratch_mem2 and were then clobbered by the next lutin load, corrupting
the saved backup headers (bogus offsets with x not aligned to 4), so
blitSpritesToBackBuffer()/restoreImage() re-stamped them at the wrong,
top-of-screen position.
Size the spot-backup gap for the EGA worst case (6000) and grow
scratch_mem1 to gap + EGA lutin worst case (12800) so neither a big
backup nor a big lutin can overrun into the adjacent sprites_list[].
Changed paths:
engines/chamber/room.cpp
engines/chamber/room.h
diff --git a/engines/chamber/room.cpp b/engines/chamber/room.cpp
index 63cdfb33c2d..b2ce4ba5b91 100644
--- a/engines/chamber/room.cpp
+++ b/engines/chamber/room.cpp
@@ -40,13 +40,21 @@
namespace Chamber {
-// 1500-byte spot-backup region, then the lutin/anim scratch (scratch_mem2).
+// Spot-backup region, then the lutin/anim scratch (scratch_mem2).
+// backupSpotsImages() fills the spot-backup region from scratch_mem1 upward.
+// The original CGA budget for it is 1500 bytes, but EGA stores each backup as
+// CLUT8 (4 bytes per CGA byte), so it needs up to 4*1500 = 6000 bytes. With the
+// old 1500-byte gap the EGA backups spilled past scratch_mem2 and were then
+// clobbered by the next lutin load, corrupting the backup headers (garbage
+// stamped into the backbuffer's top rows). Use the EGA worst case for the gap.
+//
// The scratch holds up to four simultaneous lutin slots (see getScratchBuffer).
-// CGA needs 4*1600 = 6400 there; EGA decodes lutins to CLUT8 (4 bytes per CGA
-// byte) so it needs 4*3200 = 12800. Sized for the EGA worst case so a big lutin
-// can't overrun into the adjacent sprites_list[].
-byte scratch_mem1[14400];
-byte *scratch_mem2 = scratch_mem1 + 1500;
+// CGA needs 4*1600 = 6400 there; EGA decodes lutins to CLUT8 so it needs
+// 4*3200 = 12800. Size scratch_mem1 for gap + EGA lutin worst case so neither a
+// big backup nor a big lutin can overrun into the adjacent sprites_list[].
+#define SCRATCH_SPOT_GAP 6000
+byte scratch_mem1[SCRATCH_SPOT_GAP + 12800];
+byte *scratch_mem2 = scratch_mem1 + SCRATCH_SPOT_GAP;
rect_t room_bounds_rect = {0, 0, 0, 0};
byte last_object_hint = 0;
diff --git a/engines/chamber/room.h b/engines/chamber/room.h
index 263e1ea4667..b831a4cc04e 100644
--- a/engines/chamber/room.h
+++ b/engines/chamber/room.h
@@ -90,7 +90,7 @@ typedef struct turkeyanims_t {
animdesc_t field_4;
} turkeyanims_t;
-extern byte scratch_mem1[14400];
+extern byte scratch_mem1[];
extern byte *scratch_mem2;
extern rect_t room_bounds_rect;
Commit: 3fd28dcd3030d9a4c78b9f48a161a940a0c91efe
https://github.com/scummvm/scummvm/commit/3fd28dcd3030d9a4c78b9f48a161a940a0c91efe
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-06-30T01:10:12+02:00
Commit Message:
CHAMBER: Fix vort/turkey timer comparison endianness
next_vorts_ticks/next_turkey_ticks hold plain numeric values, but
timer_ticks2 is stored big-endian. Byteswap the timer side instead so
both operands are numeric; the old comparison fired vort/turkey
commands at the wrong times, popping them in/out of rooms and leaving
visual artifacts.
Changed paths:
engines/chamber/kult.cpp
diff --git a/engines/chamber/kult.cpp b/engines/chamber/kult.cpp
index ef110b3c611..4f133c1c064 100644
--- a/engines/chamber/kult.cpp
+++ b/engines/chamber/kult.cpp
@@ -184,13 +184,19 @@ void gameLoop(byte *target) {
goto process;
}
- if (Swap16(next_vorts_ticks) < script_word_vars.timer_ticks2) { /*TODO: is this ok? ticks2 is BE, ticks3 is LE*/
+ // next_vorts_ticks is a plain numeric value (always set as
+ // Swap16(timer_ticks2) + 5), but timer_ticks2 is stored big-endian.
+ // Byteswap the timer side so both operands are numeric; the old
+ // Swap16(next_vorts_ticks) compared two BE representations, so the
+ // vort command fired at the wrong times (vorts popping in/out of
+ // rooms and leaving artifacts from the interrupted walk anim).
+ if (next_vorts_ticks < Swap16(script_word_vars.timer_ticks2)) {
the_command = next_vorts_cmd;
if (the_command)
goto process;
}
- if (Swap16(next_turkey_ticks) < script_word_vars.timer_ticks2) { /*TODO: is this ok? ticks2 is BE, ticks4 is LE*/
+ if (next_turkey_ticks < Swap16(script_word_vars.timer_ticks2)) {
the_command = next_turkey_cmd;
if (the_command)
goto process;
Commit: 6b7d038907e1979a69c427beb47fd5ed31087079
https://github.com/scummvm/scummvm/commit/6b7d038907e1979a69c427beb47fd5ed31087079
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-06-30T01:10:12+02:00
Commit Message:
CHAMBER: Fix EGA zone scan covering only a quarter of the screen width
room_bounds_rect coords are in 4-pixel blocks. calcXY_p scales the start
offset by 4 in EGA, but the scan-line invert/blit used the block width w
as a byte count. In CGA one byte spans 4 pixels so w bytes cover the full
width; in EGA one byte is one pixel, so w bytes covered only a quarter.
Use w*4 in EGA (widen the loop counter since w*4 exceeds a byte).
Changed paths:
engines/chamber/script.cpp
diff --git a/engines/chamber/script.cpp b/engines/chamber/script.cpp
index 754faf0fc36..e6f77016710 100644
--- a/engines/chamber/script.cpp
+++ b/engines/chamber/script.cpp
@@ -3665,7 +3665,8 @@ uint16 CMD_D_PsiBrainwarp(void) {
uint16 CMD_E_PsiZoneScan(void) {
- byte x, y, w, h;
+ byte y, h;
+ uint16 x, w;
uint16 offs;
if (!ConsumePsiEnergy(1))
@@ -3684,6 +3685,11 @@ uint16 CMD_E_PsiZoneScan(void) {
w = room_bounds_rect.ex - room_bounds_rect.sx;
h = room_bounds_rect.ey - room_bounds_rect.sy;
+ /*room coords are in 4-pixel blocks; EGA is 1 byte/pixel so the scan line
+ spans w*4 bytes, while CGA packs 4 pixels/byte and spans w bytes*/
+ if (g_vm->_videoMode == Common::kRenderEGA)
+ w *= 4;
+
for (y = room_bounds_rect.sy; h; y++, h--) {
spot_t *spot;
for (x = 0; x < w; x++) frontbuffer[offs + x] = ~frontbuffer[offs + x];
More information about the Scummvm-git-logs
mailing list