[Scummvm-git-logs] scummvm master -> ba2c9670e86606de6c6a33f20bd8f384413af0f3

sev- noreply at scummvm.org
Sun May 31 11:25:18 UTC 2026


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

Summary:
1e3675a52c CHAMBER: Fix EGA detection MD5s and title screen rendering
0399cd4bbe CHAMBER: Fix EGA jaggedZoom transition taking 20s on player death
f1d7f46402 CHAMBER: Fix performance issues and SCR_2D_Wait bug
3325910e6d CHAMBER: Fix mouse click coordinate latching and button state consumption
94d6524459 CHAMBER: Fix cursor hotspot color, selectSpotCursor apply, and door open animation
ba2c9670e8 CHAMBER: Implement EGA script opcode 0x6B (RedrawRoomStatics)


Commit: 1e3675a52c9ff82abec33a1f7b364cf8a6827afe
    https://github.com/scummvm/scummvm/commit/1e3675a52c9ff82abec33a1f7b364cf8a6827afe
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-05-31T13:25:11+02:00

Commit Message:
CHAMBER: Fix EGA detection MD5s and title screen rendering

Use first-5000-byte MD5 hashes (as required by ScummVM's advanced
detector) for PRESCGA.BIN, Kult2.pxi and PRESEGA.EGA. The previous
entries used full-file MD5s which caused game-not-found errors.

Fix the EGA title screen selection to check _videoMode == kRenderEGA
instead of GF_SPLASH_PRESEGA, so it works correctly regardless of
whether the game entry was cached before proper EGA detection existed.

Also ensure the EGA variant is auto-detected as EGA mode when added
fresh, by checking GF_SPLASH_PRESEGA in the video mode selection logic.

Changed paths:
    engines/chamber/chamber.cpp
    engines/chamber/detection.cpp
    engines/chamber/kult.cpp


diff --git a/engines/chamber/chamber.cpp b/engines/chamber/chamber.cpp
index 861addc66b9..a0d0277eaf1 100644
--- a/engines/chamber/chamber.cpp
+++ b/engines/chamber/chamber.cpp
@@ -30,11 +30,13 @@
 #include "common/rendermode.h"
 #include "common/system.h"
 
+#include "engines/advancedDetector.h"
 #include "engines/util.h"
 
 #include "common/gui_options.h"
 
 #include "chamber/chamber.h"
+#include "chamber/detection.h"
 #include "chamber/renderer.h"
 #include "chamber/script.h"
 #include "chamber/resdata.h"
@@ -66,7 +68,8 @@ ChamberEngine::ChamberEngine(OSystem *syst, const ADGameDescription *desc)
 	_renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
 	if (_renderMode == Common::kRenderEGA || _renderMode == Common::kRenderHercG || _renderMode == Common::kRenderHercA)
 		_videoMode = _renderMode;
-	else if (_renderMode == Common::kRenderDefault && Common::checkGameGUIOption(GUIO_RENDEREGA, Common::parseGameGUIOptions(ConfMan.get("guioptions"))))
+	else if (_renderMode == Common::kRenderDefault && ((_gameDescription->flags & GF_SPLASH_PRESEGA) ||
+	         Common::checkGameGUIOption(GUIO_RENDEREGA, Common::parseGameGUIOptions(ConfMan.get("guioptions")))))
 		_videoMode = Common::kRenderEGA;
 	else
 		_videoMode = Common::kRenderCGA;
diff --git a/engines/chamber/detection.cpp b/engines/chamber/detection.cpp
index 58c883fe9ea..b7317a5982b 100644
--- a/engines/chamber/detection.cpp
+++ b/engines/chamber/detection.cpp
@@ -46,7 +46,7 @@ static const ADGameDescription gameDescriptions[] = {
 		"chamber",
 		"",
 		AD_ENTRY2s("kult1.pxi",   "fc0bd31a3c380338f76ff53e421e47b6", 140537,
-		           "PRESCGA.BIN", "664a75a95340bde200a2752f54ba7aa7",   5105),
+		           "PRESCGA.BIN", "346be1f34fa5278e78bec85f3d349dc3",   5105),
 		Common::EN_USA,
 		Common::kPlatformDOS,
 		ADGF_UNSTABLE | GF_SPLASH_PRESCGA,
@@ -56,8 +56,8 @@ static const ADGameDescription gameDescriptions[] = {
 	{
 		"chamber",
 		"EGA",
-		AD_ENTRY2s("Kult2.pxi",   "2f5cea29072e8c16bf4724a0d0a2201d", 142658,
-		           "PRESEGA.EGA", "b0a6474fa95276255f8eb85c12aab031",  32000),
+		AD_ENTRY2s("Kult2.pxi",   "36a9a0a14c1badfff7643ac3fed24b43", 142658,
+		           "PRESEGA.EGA", "c3fb9e55ec789cd6dc67259a48025c4c",  32000),
 		Common::EN_USA,
 		Common::kPlatformDOS,
 		ADGF_UNSTABLE | GF_SPLASH_PRESEGA,
diff --git a/engines/chamber/kult.cpp b/engines/chamber/kult.cpp
index 9eb8b0ceb1d..0cac2fa3689 100644
--- a/engines/chamber/kult.cpp
+++ b/engines/chamber/kult.cpp
@@ -282,7 +282,7 @@ Common::Error ChamberEngine::init() {
 
 	Graphics::Surface *splash = nullptr;
 
-	if (_gameDescription->flags & GF_SPLASH_PRESEGA) {
+	if (_videoMode == Common::RenderMode::kRenderEGA) {
 		/* EGA title screen */
 		splash = ega_loadFond("PRESEGA.EGA");
 		if (!splash) {


Commit: 0399cd4bbe9477060b7103a451f2be0164599e13
    https://github.com/scummvm/scummvm/commit/0399cd4bbe9477060b7103a451f2be0164599e13
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-05-31T13:25:11+02:00

Commit Message:
CHAMBER: Fix EGA jaggedZoom transition taking 20s on player death

EGARenderer::traceLine was calling blitToScreen(0,0,EGA_WIDTH,EGA_HEIGHT)
after each individual line drawn. jaggedZoom traces 16 lines per cycle
and is called twice in the Game Over sequence, resulting in ~3200 full
screen flushes. The caller already issues one waitVBlank (which includes
blitToScreen) per cycle, so the per-line flush was redundant and was
the sole cause of the ~20s stuttering wipe.

Changed paths:
    engines/chamber/ega.cpp


diff --git a/engines/chamber/ega.cpp b/engines/chamber/ega.cpp
index 1c237a959d0..98a093a0004 100644
--- a/engines/chamber/ega.cpp
+++ b/engines/chamber/ega.cpp
@@ -488,8 +488,8 @@ void EGARenderer::traceLine(uint16 sx, uint16 ex, uint16 sy, uint16 ey, byte *so
 		if (e2 > -abh) { err -= abh; x0 += ddx; }
 		if (e2 <  abw) { err += abw; y0 += ddy; }
 	}
-	if (target == SCREENBUFFER)
-		blitToScreen(0, 0, EGA_WIDTH, EGA_HEIGHT);
+	/*Caller (e.g. jaggedZoom) issues one waitVBlank/blitToScreen per cycle;
+	  flushing the whole screen here turned each line into an updateScreen.*/
 }
 
 void EGARenderer::zoomImage(byte *pixels, byte w, byte h, byte /*nw*/, byte /*nh*/, byte *target, uint16 ofs) {


Commit: f1d7f464025856da70b1226aaf5c7dfa25efa381
    https://github.com/scummvm/scummvm/commit/f1d7f464025856da70b1226aaf5c7dfa25efa381
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-05-31T13:25:11+02:00

Commit Message:
CHAMBER: Fix performance issues and SCR_2D_Wait bug

- animDrawSprite: remove artificial per-frame delay loop and redundant
  waitVBlank; screen update happens via copyScreenBlock already
- drawBackground: move background_draw_steps assignment before loop and
  call waitVBlank once after all tiles instead of per-tile
- drawRoomDoor: remove two redundant waitVBlank calls before copyScreenBlock
- animRoomDoorOpen/Close: disable drawRoomDoor inside animation loop to
  prevent crash (door animation is a TODO)
- refreshZone: remove slow tile-by-tile drawBackground(SCREENBUFFER) call;
  backBufferToRealFull handles the single flush
- SCR_2D_Wait: fix bug where seconds parameter was ignored and always
  waited 4 seconds

Changed paths:
    engines/chamber/anim.cpp
    engines/chamber/room.cpp
    engines/chamber/script.cpp


diff --git a/engines/chamber/anim.cpp b/engines/chamber/anim.cpp
index 7cd7aa00311..43119446cba 100644
--- a/engines/chamber/anim.cpp
+++ b/engines/chamber/anim.cpp
@@ -136,7 +136,6 @@ void copyScreenBlockWithDotEffect(byte *source, byte x, byte y, byte width, byte
 }
 
 void animDrawSprite(byte x, byte y, byte sprw, byte sprh, byte *pixels, uint16 pitch) {
-	uint16 delay;
 	byte ex, ey, updx, updy, updw, updh;
 	uint16 ofs = g_vm->_renderer->calcXY_p(x, y);
 	g_vm->_renderer->backupImage(backbuffer, ofs, sprw, sprh, sprit_load_buffer);
@@ -160,11 +159,6 @@ void animDrawSprite(byte x, byte y, byte sprw, byte sprh, byte *pixels, uint16 p
 	updh = ey - updy;
 	ofs = g_vm->_renderer->calcXY_p(updx, updy);
 	/*TODO looks like here was some code before*/
-	for (delay = 0; delay < anim_draw_delay; delay++) {
-		g_system->delayMillis(1000 / 16 / 25);
-	}
-	waitVBlank();
-
 	if (anim_use_dot_effect)
 		copyScreenBlockWithDotEffect(backbuffer, updx, updy, updw, updh, frontbuffer);
 	else {
diff --git a/engines/chamber/room.cpp b/engines/chamber/room.cpp
index 7c1e341b55f..bb98bd079d8 100644
--- a/engines/chamber/room.cpp
+++ b/engines/chamber/room.cpp
@@ -299,18 +299,18 @@ void drawBackground(byte *target, byte vblank) {
 	int16 i;
 	uint16 offs = (2 / 2) * CGA_BYTES_PER_LINE + 8;   /*TODO: calcxy?*/
 	byte *pixels = gauss_data + 0x3C8; /*TODO: better const*/
+	if (g_vm->_videoMode == Common::RenderMode::kRenderCGA) {
+		background_draw_steps = background_draw_steps_cga;
+	} else {
+		background_draw_steps = background_draw_steps_hga;
+	}
 	for (i = 0; i < 53; i++) {
 		/*draw a tile, alternating between two variants*/
 		g_vm->_renderer->blit(pixels + (i & 1 ? 0 : kBgW * kBgH), kBgW, kBgW, kBgH, target, offs);
-		if (vblank)
-			waitVBlank();
-		if (g_vm->_videoMode == Common::RenderMode::kRenderCGA) {
-			background_draw_steps = background_draw_steps_cga;
-		} else {
-			background_draw_steps = background_draw_steps_hga;
-		}
 		offs += background_draw_steps[i];
 	}
+	if (vblank)
+		waitVBlank();
 
 	offs = (182 / 2) * CGA_BYTES_PER_LINE;  /*TODO: calcxy?*/
 	for (i = 0; i < 9; i++) {
@@ -546,8 +546,6 @@ void drawRoomDoor(void) {
 		else
 			g_vm->_renderer->blitSpriteFlip(pixels, pitch, w, h, backbuffer, offs);
 	}
-	waitVBlank();
-	waitVBlank();
 	g_vm->_renderer->copyScreenBlock(backbuffer, info->width, info->height, frontbuffer, info->offs);
 }
 
@@ -568,7 +566,7 @@ void animRoomDoorOpen(byte index) {
 	oldheight = info->layer[1].height;
 
 	for (i = 0; i < oldheight / 2; i++) {
-#if 1
+#if 0
 		drawRoomDoor();
 #endif
 		info->layer[1].height -= 2;
@@ -606,7 +604,7 @@ void animRoomDoorClose(byte index) {
 	info->layer[1].height = 1;
 
 	for (i = 0; i < oldheight / 2; i++) {
-#if 1
+#if 0
 		drawRoomDoor();
 #endif
 		info->layer[1].height += 2;
@@ -1040,9 +1038,6 @@ void refreshZone(void) {
 	popDirtyRects(DirtyRectBubble);
 	popDirtyRects(DirtyRectText);
 
-	if (!skip_zone_transition && !right_button)
-		drawBackground(SCREENBUFFER, 1);
-
 	g_vm->_renderer->backBufferToRealFull();
 
 	in_de_profundis = 0;
diff --git a/engines/chamber/script.cpp b/engines/chamber/script.cpp
index 4ac42031c65..50e39f25ee4 100644
--- a/engines/chamber/script.cpp
+++ b/engines/chamber/script.cpp
@@ -378,14 +378,12 @@ uint16 SCR_2C_Wait4(void) {
 
 /*
 Wait for a specified number of seconds or a keypress
-TODO: Always waits for a 4 seconds due to a bug?
 */
 uint16 SCR_2D_Wait(void) {
 	byte seconds;
 	script_ptr++;
 	seconds = *script_ptr++;
-	(void)seconds;
-	wait(4);    /*TODO: looks like a bug?*/
+	wait(seconds);
 	return 0;
 }
 


Commit: 3325910e6d960eea1407891f57876cf82391c259
    https://github.com/scummvm/scummvm/commit/3325910e6d960eea1407891f57876cf82391c259
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-05-31T13:25:11+02:00

Commit Message:
CHAMBER: Fix mouse click coordinate latching and button state consumption

Changed paths:
    engines/chamber/input.cpp
    engines/chamber/input.h
    engines/chamber/invent.cpp
    engines/chamber/kult.cpp
    engines/chamber/menu.cpp
    engines/chamber/script.cpp


diff --git a/engines/chamber/input.cpp b/engines/chamber/input.cpp
index 13fc7a2c822..0292af36952 100644
--- a/engines/chamber/input.cpp
+++ b/engines/chamber/input.cpp
@@ -233,6 +233,8 @@ void pollInput(void) {
 			break;
 
 		case Common::EVENT_LBUTTONDOWN:
+			cursor_x = event.mouse.x;
+			cursor_y = event.mouse.y;
 			mouseButtons |= 1;
 			break;
 
@@ -241,6 +243,8 @@ void pollInput(void) {
 			break;
 
 		case Common::EVENT_RBUTTONDOWN:
+			cursor_x = event.mouse.x;
+			cursor_y = event.mouse.y;
 			mouseButtons |= 2;
 			break;
 
@@ -256,6 +260,11 @@ void pollInput(void) {
 	setInputButtons(mouseButtons);
 }
 
+void clearButtons(void) {
+	mouseButtons = 0;
+	setInputButtons(0);
+}
+
 void processInput(void) {
 	pollInput();
 	updateCursor();
diff --git a/engines/chamber/input.h b/engines/chamber/input.h
index 46954490d36..0b3cd3a0c87 100644
--- a/engines/chamber/input.h
+++ b/engines/chamber/input.h
@@ -42,6 +42,7 @@ byte pollKeyboard(void);
 void setInputButtons(byte keys);
 
 void pollInput(void);
+void clearButtons(void);
 void processInput(void);
 void pollInputButtonsOnly(void);
 void resetInput(void);
diff --git a/engines/chamber/invent.cpp b/engines/chamber/invent.cpp
index c44785a8cc4..f9f13e3cde6 100644
--- a/engines/chamber/invent.cpp
+++ b/engines/chamber/invent.cpp
@@ -116,6 +116,7 @@ void openInventory(uint16 filtermask, uint16 filtervalue) {
 	if (inv_count != 0) {
 		g_vm->_renderer->selectCursor(CURSOR_FINGER);
 		processInput();
+		clearButtons();
 		do {
 			pollInput();
 			checkInventoryItemHover(inv_count);
diff --git a/engines/chamber/kult.cpp b/engines/chamber/kult.cpp
index 0cac2fa3689..32b9445be78 100644
--- a/engines/chamber/kult.cpp
+++ b/engines/chamber/kult.cpp
@@ -208,6 +208,7 @@ process:
 			updateUndrawCursor(target);
 			refreshSpritesData();
 			uint16 restart = runCommandKeepSp();
+			clearButtons();
 			if (restart == RUNCOMMAND_RESTART && g_vm->_shouldRestart)
 				return;
 			script_byte_vars.used_commands++;
diff --git a/engines/chamber/menu.cpp b/engines/chamber/menu.cpp
index efff10a0273..8f1cfde8e83 100644
--- a/engines/chamber/menu.cpp
+++ b/engines/chamber/menu.cpp
@@ -135,6 +135,7 @@ void actionsMenu(byte **pinfo) {
 
 	g_vm->_renderer->selectCursor(CURSOR_FINGER);
 	processInput();
+	clearButtons();
 
 	choice = 0;
 	act_dot_rects_cur = act_dot_rects;
@@ -181,6 +182,7 @@ void actionsMenu(byte **pinfo) {
 /*TODO: maybe rename to SpotsLoop*/
 void menuLoop(byte spotmask, byte spotvalue) {
 	processInput();
+	clearButtons();
 	do {
 		pollInput();
 		checkHotspots(spotmask, spotvalue);
diff --git a/engines/chamber/script.cpp b/engines/chamber/script.cpp
index 50e39f25ee4..156a5d570d7 100644
--- a/engines/chamber/script.cpp
+++ b/engines/chamber/script.cpp
@@ -3344,6 +3344,7 @@ uint16 CMD_4_EnergyLevel(void) {
 		g_vm->_renderer->blitAndWait(cur_image_pixels, cur_image_size_w, cur_image_size_w, cur_image_size_h, SCREENBUFFER, cur_image_offs);
 	}
 
+	clearButtons();
 	do {
 		IFGM_PlaySample(28);
 		animPortrait(1, anim, 10);


Commit: 94d6524459a2b89bd4228434f61e50dbdd179fb1
    https://github.com/scummvm/scummvm/commit/94d6524459a2b89bd4228434f61e50dbdd179fb1
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-05-31T13:25:11+02:00

Commit Message:
CHAMBER: Fix cursor hotspot color, selectSpotCursor apply, and door open animation

Changed paths:
    engines/chamber/cursor.cpp
    engines/chamber/room.cpp
    engines/chamber/script.cpp


diff --git a/engines/chamber/cursor.cpp b/engines/chamber/cursor.cpp
index 1219bbe2346..7474ed31785 100644
--- a/engines/chamber/cursor.cpp
+++ b/engines/chamber/cursor.cpp
@@ -122,7 +122,7 @@ void EGARenderer::selectCursor(uint16 num) {
 			if (!bitA && !bitB)
 				*dst++ = 255; /*transparent*/
 			else if (bitB)
-				*dst++ = 15;  /*white*/
+				*dst++ = (cursor_color == 0xAA) ? 14 : 15;  /*yellow on hotspot, white otherwise*/
 			else
 				*dst++ = 0;   /*black*/
 		}
diff --git a/engines/chamber/room.cpp b/engines/chamber/room.cpp
index bb98bd079d8..a4d0081ec50 100644
--- a/engines/chamber/room.cpp
+++ b/engines/chamber/room.cpp
@@ -251,6 +251,7 @@ void selectSpotCursor(void) {
 		cursor_shape = souri_data + curs * (CURSOR_WIDTH * CURSOR_HEIGHT / 4);
 	else
 		cursor_shape = souri_data + curs * CURSOR_WIDTH * CURSOR_HEIGHT * 2 / 4;
+	g_vm->_renderer->selectCursor(curs);
 }
 
 #define kBgW 8
@@ -566,9 +567,8 @@ void animRoomDoorOpen(byte index) {
 	oldheight = info->layer[1].height;
 
 	for (i = 0; i < oldheight / 2; i++) {
-#if 0
 		drawRoomDoor();
-#endif
+		waitVBlank();
 		info->layer[1].height -= 2;
 		if (g_vm->_videoMode == Common::kRenderEGA)
 			info->layer[1].pixels += info->layer[1].width * 4 * 2;
@@ -606,6 +606,7 @@ void animRoomDoorClose(byte index) {
 	for (i = 0; i < oldheight / 2; i++) {
 #if 0
 		drawRoomDoor();
+		waitVBlank();
 #endif
 		info->layer[1].height += 2;
 		if (g_vm->_videoMode == Common::kRenderEGA)
diff --git a/engines/chamber/script.cpp b/engines/chamber/script.cpp
index 156a5d570d7..38979d3bca1 100644
--- a/engines/chamber/script.cpp
+++ b/engines/chamber/script.cpp
@@ -1516,6 +1516,7 @@ If go through a door, play door's opening animation
 */
 uint16 SCR_42_LoadZone(void) {
 	byte index;
+	bool door_animated = false;
 
 	script_ptr++;
 	index = *script_ptr++;
@@ -1528,6 +1529,7 @@ uint16 SCR_42_LoadZone(void) {
 			script_byte_vars.last_door = script_byte_vars.cur_spot_flags & 7;
 		else if ((script_byte_vars.cur_spot_flags & ((SPOTFLG_20 | SPOTFLG_10 | SPOTFLG_8))) == SPOTFLG_8) {
 			skip_zone_transition = 1;
+			door_animated = true;
 			animRoomDoorOpen(script_byte_vars.cur_spot_idx);
 			script_byte_vars.last_door = script_byte_vars.cur_spot_flags & 7;
 		} else
@@ -1552,6 +1554,10 @@ uint16 SCR_42_LoadZone(void) {
 	prepareAspirant();
 	drawPersons();
 	script_byte_vars.cur_spot_flags = 0;
+
+	if (door_animated)
+		g_vm->_renderer->backBufferToRealFull();
+
 	return 0;
 }
 


Commit: ba2c9670e86606de6c6a33f20bd8f384413af0f3
    https://github.com/scummvm/scummvm/commit/ba2c9670e86606de6c6a33f20bd8f384413af0f3
Author: Ion Andrei Cristian (lecturatul2017 at gmail.com)
Date: 2026-05-31T13:25:11+02:00

Commit Message:
CHAMBER: Implement EGA script opcode 0x6B (RedrawRoomStatics)

The EGA build (kultega.bin) re-numbers the CGA RedrawRoomStatics
command (0x13) to 0x6B. The opcode was unimplemented, so RunScript
aborted mid-command on hitting it, skipping the static redraw and the
following BackBufferToScreen flush. This left state-swapped statics
(e.g. the snake in The Twins) visually frozen even though their state
updated. Implement 0x6B (identical to SCR_13) and use MAX_SCR_HANDLERS
for the opcode bounds check.

Changed paths:
    engines/chamber/script.cpp


diff --git a/engines/chamber/script.cpp b/engines/chamber/script.cpp
index 38979d3bca1..1468a83e52a 100644
--- a/engines/chamber/script.cpp
+++ b/engines/chamber/script.cpp
@@ -3286,6 +3286,15 @@ uint16 SCR_6A_Unused(void) {
 	return 0;
 }
 
+/*
+EGA-only opcode (kultega.bin): redraw room statics.
+The CGA script (TEMPL.BIN) uses SCR_13 for the same purpose; the EGA build
+re-numbered this command to 0x6B. Behaviour and operand are identical.
+*/
+uint16 SCR_6B_RedrawRoomStatics(void) {
+	return SCR_13_RedrawRoomStatics();
+}
+
 /*
 Open room's items inventory
 */
@@ -4389,6 +4398,7 @@ cmdhandler_t script_handlers[] = {
 	SCR_68_PlaySfx,
 	SCR_69_playSound,
 	SCR_6A_Unused,
+	SCR_6B_RedrawRoomStatics,   /*EGA-only; same as SCR_13*/
 };
 #define MAX_SCR_HANDLERS ARRAYSIZE(script_handlers)
 
@@ -4430,7 +4440,7 @@ uint16 RunScript(byte *code) {
 #endif
 
 
-		if (opcode == 0 || opcode >= 107)
+		if (opcode == 0 || opcode >= MAX_SCR_HANDLERS)
 			break;
 
 		status = script_handlers[opcode]();




More information about the Scummvm-git-logs mailing list