[Scummvm-git-logs] scummvm master -> 27da4fc2a56a6582fd1c410a62cbd76c98e96691
neuromancer
noreply at scummvm.org
Sat Jun 6 13:34:46 UTC 2026
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
72481cb710 SCUMM: RA1: fix perspective for L11 UI
512a0ea6fa SCUMM: RA1: less permissive target detection
daf7775b63 SCUMM: RA1: make L11 much easier to control with mouse
27da4fc2a5 SCUMM: RA1: reduce crazy oscilation when using the mouse in some levels
Commit: 72481cb7106579b7f5d4303ee50300a2b8dfe04e
https://github.com/scummvm/scummvm/commit/72481cb7106579b7f5d4303ee50300a2b8dfe04e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-06T14:28:34+02:00
Commit Message:
SCUMM: RA1: fix perspective for L11 UI
Changed paths:
engines/scumm/insane/rebel1/render.cpp
diff --git a/engines/scumm/insane/rebel1/render.cpp b/engines/scumm/insane/rebel1/render.cpp
index 44b888c2cd1..aafe827bde7 100644
--- a/engines/scumm/insane/rebel1/render.cpp
+++ b/engines/scumm/insane/rebel1/render.cpp
@@ -817,7 +817,7 @@ void InsaneRebel1::procPostRendering(byte *renderBitmap, int32 codecparam, int32
renderLevelHitsOverlay(renderBitmap, pitch, width, height, 0x04, true);
if (_currentLevel == 10)
- renderLevelHitsOverlay(renderBitmap, pitch, width, height, 0x16, false);
+ renderLevelHitsOverlay(renderBitmap, pitch, width, height, 0x16, true);
// Level 8 (Imperial Walkers) â walker-specific state update + UI overlay.
// In the original, RunLevel8Flow runs the walker logic inline in the per-frame
Commit: 512a0ea6fa9b904f26ccbbacca88bf344bd5e04c
https://github.com/scummvm/scummvm/commit/512a0ea6fa9b904f26ccbbacca88bf344bd5e04c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-06T15:03:27+02:00
Commit Message:
SCUMM: RA1: less permissive target detection
Changed paths:
engines/scumm/insane/rebel1/iact.cpp
engines/scumm/insane/rebel1/rebel.cpp
engines/scumm/insane/rebel1/rebel.h
engines/scumm/insane/rebel1/runlevels.cpp
engines/scumm/smush/rebel/smush_player_ra1.cpp
diff --git a/engines/scumm/insane/rebel1/iact.cpp b/engines/scumm/insane/rebel1/iact.cpp
index 61b7a30e28e..8346b350b59 100644
--- a/engines/scumm/insane/rebel1/iact.cpp
+++ b/engines/scumm/insane/rebel1/iact.cpp
@@ -145,6 +145,25 @@ inline bool ra1DispatcherHudOnlyWhenDisabled(uint32 opcode) {
}
}
+inline uint16 ra1PrioritizedFrameOpcode(uint32 opcodeMask) {
+ if (opcodeMask & (1u << 0x1A))
+ return 0x1A;
+ if (opcodeMask & (1u << 0x19))
+ return 0x19;
+ if (opcodeMask & (1u << 0x0B))
+ return 0x0B;
+ if (opcodeMask & (1u << 0x0A))
+ return 0x0A;
+ if (opcodeMask & (1u << 0x09))
+ return 0x09;
+ if (opcodeMask & (1u << 0x08))
+ return 0x08;
+ if (opcodeMask & (1u << 0x07))
+ return 0x07;
+
+ return 0;
+}
+
bool ra1TargetCursorUsesProjection(uint16 opcode) {
switch (opcode) {
// FOBJ target chunks can precede the paired 0x0A GAME chunk, leaving 0x08
@@ -783,34 +802,39 @@ void InsaneRebel1::unprojectGameplayPoint(int16 &x, int16 &y) const {
}
uint16 InsaneRebel1::getEffectiveGameOpcode() const {
- if (hasFrameGameOpcode(0x1A))
- return 0x1A;
- if (hasFrameGameOpcode(0x19))
- return 0x19;
- if (hasFrameGameOpcode(0x0B))
- return 0x0B;
- if (hasFrameGameOpcode(0x0A))
- return 0x0A;
- if (hasFrameGameOpcode(0x09))
- return 0x09;
- if (hasFrameGameOpcode(0x08))
- return 0x08;
- if (hasFrameGameOpcode(0x07))
- return 0x07;
+ const uint16 frameOpcode = ra1PrioritizedFrameOpcode(_frameGameOpcodeMask);
+ if (frameOpcode != 0)
+ return frameOpcode;
+
+ return _activeGameOpcode;
+}
+
+uint16 InsaneRebel1::getTargetHitGameOpcode() const {
+ const uint16 frameOpcode = ra1PrioritizedFrameOpcode(_frameGameOpcodeMask | _frameGameOpcodeHintMask);
+ if (frameOpcode != 0)
+ return frameOpcode;
return _activeGameOpcode;
}
+int16 InsaneRebel1::getGameplayCursorX(uint16 opcode) const {
+ return (opcode == 0x09) ? _flightAimX : _shipPosX;
+}
+
int16 InsaneRebel1::getGameplayCursorX() const {
- return (getEffectiveGameOpcode() == 0x09) ? _flightAimX : _shipPosX;
+ return getGameplayCursorX(getEffectiveGameOpcode());
+}
+
+int16 InsaneRebel1::getGameplayCursorY(uint16 opcode) const {
+ return (opcode == 0x09) ? _flightAimY : _shipPosY;
}
int16 InsaneRebel1::getGameplayCursorY() const {
- return (getEffectiveGameOpcode() == 0x09) ? _flightAimY : _shipPosY;
+ return getGameplayCursorY(getEffectiveGameOpcode());
}
-void InsaneRebel1::setGameplayCursor(int16 x, int16 y) {
- if (getEffectiveGameOpcode() == 0x09) {
+void InsaneRebel1::setGameplayCursor(uint16 opcode, int16 x, int16 y) {
+ if (opcode == 0x09) {
_flightAimX = x;
_flightAimY = y;
} else {
@@ -819,6 +843,10 @@ void InsaneRebel1::setGameplayCursor(int16 x, int16 y) {
}
}
+void InsaneRebel1::setGameplayCursor(int16 x, int16 y) {
+ setGameplayCursor(getEffectiveGameOpcode(), x, y);
+}
+
void InsaneRebel1::updateFlightVariantCursor() {
if (getEffectiveGameOpcode() != 0x09)
return;
@@ -2537,10 +2565,10 @@ void InsaneRebel1::processShot() {
// zones into gameplay-window screen space before comparing against the ship center.
void InsaneRebel1::checkTargetHit(int16 targetIdx, int16 left, int16 top, int16 right, int16 bottom) {
int16 snap = _tuning.snap;
- const uint16 effectiveOpcode = getEffectiveGameOpcode();
+ const uint16 effectiveOpcode = getTargetHitGameOpcode();
const bool screenSpaceCursor = ra1TargetCursorUsesProjection(effectiveOpcode);
- const int16 screenCursorX = getGameplayCursorX();
- const int16 screenCursorY = getGameplayCursorY();
+ const int16 screenCursorX = getGameplayCursorX(effectiveOpcode);
+ const int16 screenCursorY = getGameplayCursorY(effectiveOpcode);
int16 curX = screenCursorX;
int16 curY = screenCursorY;
if (screenSpaceCursor)
@@ -2584,7 +2612,7 @@ void InsaneRebel1::checkTargetHit(int16 targetIdx, int16 left, int16 top, int16
int16 snappedY = (top + bottom) / 2;
if (screenSpaceCursor)
projectGameplayPoint(snappedX, snappedY);
- setGameplayCursor(snappedX, snappedY);
+ setGameplayCursor(effectiveOpcode, snappedX, snappedY);
}
// DOS uses g_recentKillObjectIdPlus1 as a frame-wide latch. Once one
diff --git a/engines/scumm/insane/rebel1/rebel.cpp b/engines/scumm/insane/rebel1/rebel.cpp
index 4327c5e1703..4e981793ec0 100644
--- a/engines/scumm/insane/rebel1/rebel.cpp
+++ b/engines/scumm/insane/rebel1/rebel.cpp
@@ -279,6 +279,7 @@ InsaneRebel1::InsaneRebel1(ScummEngine_v7 *scumm) : Insane(), _vm(scumm) {
_turretEmitterRightX = 0;
_turretEmitterRightY = 0;
_activeGameOpcode = 0;
+ _frameGameOpcodeHintMask = 0;
_frameGameOpcodeMask = 0;
_frameHasGameChunk = false;
_frameDispatchFlags = 0;
diff --git a/engines/scumm/insane/rebel1/rebel.h b/engines/scumm/insane/rebel1/rebel.h
index 041a528e978..a110ab1e295 100644
--- a/engines/scumm/insane/rebel1/rebel.h
+++ b/engines/scumm/insane/rebel1/rebel.h
@@ -117,9 +117,11 @@ public:
int getLevelGameplayPhase() const { return _levelGameplayPhase; }
uint16 getActiveGameOpcode() const { return _activeGameOpcode; }
uint16 getEffectiveGameOpcode() const;
+ uint16 getTargetHitGameOpcode() const;
bool hasFrameGameOpcode(uint16 opcode) const {
return opcode < 32 && (_frameGameOpcodeMask & (1u << opcode)) != 0;
}
+ void setFrameGameOpcodeHintMask(uint32 opcodeMask) { _frameGameOpcodeHintMask = opcodeMask; }
void warpGameplayMouseNow(int x, int y);
int16 getPerspectiveX() const { return _perspectiveX; }
int16 getPerspectiveY() const { return _perspectiveY; }
@@ -127,7 +129,10 @@ public:
void unprojectGameplayPoint(int16 &x, int16 &y) const;
int16 getGameplayCursorX() const;
int16 getGameplayCursorY() const;
+ int16 getGameplayCursorX(uint16 opcode) const;
+ int16 getGameplayCursorY(uint16 opcode) const;
void setGameplayCursor(int16 x, int16 y);
+ void setGameplayCursor(uint16 opcode, int16 x, int16 y);
void updateFlightVariantCursor();
bool handleFrameObjectTarget(int16 objectId, int16 left, int16 top, int16 width, int16 height,
int codec, uint8 &ra1Param);
@@ -441,6 +446,8 @@ private:
// Last per-frame GAME opcode observed in the current playback stream.
// Kept for legacy call sites; frame-accurate dispatch uses _frameGameOpcodeMask.
uint16 _activeGameOpcode;
+ // GAME opcodes pre-scanned from the current frame before FOBJ dispatch.
+ uint32 _frameGameOpcodeHintMask;
uint32 _frameGameOpcodeMask;
bool _frameHasGameChunk;
uint16 _frameDispatchFlags;
diff --git a/engines/scumm/insane/rebel1/runlevels.cpp b/engines/scumm/insane/rebel1/runlevels.cpp
index 92962e9b931..02b741f8a74 100644
--- a/engines/scumm/insane/rebel1/runlevels.cpp
+++ b/engines/scumm/insane/rebel1/runlevels.cpp
@@ -220,6 +220,7 @@ void InsaneRebel1::resetLevelFrameState() {
_currentSmushFrame = 0;
_gameCounter = 0;
_activeGameOpcode = 0;
+ _frameGameOpcodeHintMask = 0;
_gameLatch5D = 0;
_gameLatch5F = 0;
}
diff --git a/engines/scumm/smush/rebel/smush_player_ra1.cpp b/engines/scumm/smush/rebel/smush_player_ra1.cpp
index c2a9fa8bdbb..694e947c881 100644
--- a/engines/scumm/smush/rebel/smush_player_ra1.cpp
+++ b/engines/scumm/smush/rebel/smush_player_ra1.cpp
@@ -717,18 +717,24 @@ void SmushPlayerRebel1::handleFrameObject(int32 subSize, Common::SeekableReadStr
// handleFrame override â RA1 frame parsing with alignment, OBJ chunks, clean frame
// ---------------------------------------------------------------------------
-static bool ra1FrameHasGameChunk(Common::SeekableReadStream &b, int32 frameSize) {
+static bool ra1ScanFrameGameChunks(Common::SeekableReadStream &b, int32 frameSize, uint32 &opcodeMask) {
+ opcodeMask = 0;
const int64 frameStart = b.pos();
int32 remaining = frameSize;
RA1FrameChunkIterator chunks(b, remaining);
RA1AnimChunk chunk;
+ bool hasGameChunk = false;
while (chunks.next(chunk)) {
if (chunk.tag == MKTAG('F', 'R', 'M', 'E'))
break;
if (chunk.tag == MKTAG('G', 'A', 'M', 'E') ||
chunk.tag == MKTAG('G', 'A', 'M', '2')) {
- b.seek(frameStart, SEEK_SET);
- return true;
+ hasGameChunk = true;
+ if (chunks.fits(chunk) && chunk.size >= 4) {
+ const uint32 opcode = b.readUint32BE();
+ if (opcode < 32)
+ opcodeMask |= (1u << opcode);
+ }
}
if (!chunks.fits(chunk))
@@ -737,7 +743,7 @@ static bool ra1FrameHasGameChunk(Common::SeekableReadStream &b, int32 frameSize)
}
b.seek(frameStart, SEEK_SET);
- return false;
+ return hasGameChunk;
}
void SmushPlayerRebel1::ra1HandleFrameAudioChunk(int32 subSize, Common::SeekableReadStream &b) {
@@ -922,8 +928,11 @@ void SmushPlayerRebel1::handleFrame(int32 frameSize, Common::SeekableReadStream
InsaneRebel1 *rebel1 = static_cast<InsaneRebel1 *>(_insane);
rebel1->setCurrentSmushFrame(_frame);
bool interactive = rebel1->isInteractiveVideoActive();
- const bool frameHasGameChunk = interactive && ra1FrameHasGameChunk(b, frameSize);
+ uint32 frameGameOpcodeHintMask = 0;
+ const bool frameHasGameChunk = interactive &&
+ ra1ScanFrameGameChunks(b, frameSize, frameGameOpcodeHintMask);
rebel1->setFrameHasGameChunk(frameHasGameChunk);
+ rebel1->setFrameGameOpcodeHintMask(frameGameOpcodeHintMask);
const uint16 activeOpcode = rebel1->getActiveGameOpcode();
bool forceClear = interactive &&
(activeOpcode == 0x0B ||
Commit: daf7775b633de7894716a1f477051951d3f639b4
https://github.com/scummvm/scummvm/commit/daf7775b633de7894716a1f477051951d3f639b4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-06T15:13:27+02:00
Commit Message:
SCUMM: RA1: make L11 much easier to control with mouse
Changed paths:
engines/scumm/insane/rebel1/iact.cpp
diff --git a/engines/scumm/insane/rebel1/iact.cpp b/engines/scumm/insane/rebel1/iact.cpp
index 8346b350b59..2b9b4a70847 100644
--- a/engines/scumm/insane/rebel1/iact.cpp
+++ b/engines/scumm/insane/rebel1/iact.cpp
@@ -87,6 +87,7 @@ const int kRA1CenteredAxisMax = 127;
const int kRA1Op0BVerticalAxisMax = 100;
const int kRA1EnhancedFlightDirectMaxX = 64;
const int kRA1EnhancedFlightDirectMaxY = 40;
+const int kRA1Op09MouseRollTargetScale = 16;
const int kRA1ControlPadAxisStep = 0x1E;
const int16 kOnFootCenterX = 0xA3; // g_perspectiveX in HandleGameOp19
const int16 kOnFootCenterY = 0x82; // g_perspectiveY in HandleGameOp19
@@ -972,7 +973,9 @@ void InsaneRebel1::preprocessMouseAxes(int16 &inputX, int16 &inputY, bool *usedJ
if (updateGamepadReticleAim(inputX, inputY, usedJoystick))
return;
- const bool directFlightInput = getEffectiveGameOpcode() == 0x07;
+ const uint16 effectiveOpcode = getEffectiveGameOpcode();
+ const bool directFlightInput = effectiveOpcode == 0x07;
+ const bool flightVariantInput = effectiveOpcode == 0x09;
const int16 analogAxisX = applyRebel1AnalogDeadzone(_joystickAxisX);
const int16 analogAxisY = applyRebel1AnalogDeadzone(_joystickAxisY);
@@ -1034,7 +1037,7 @@ void InsaneRebel1::preprocessMouseAxes(int16 &inputX, int16 &inputY, bool *usedJ
int16 logicalX = (int16)CLIP<int>(_vm->_mouse.x, 0, 319);
int16 logicalY = (int16)CLIP<int>(_vm->_mouse.y, 0, 199);
- if (directFlightInput) {
+ if (directFlightInput || flightVariantInput) {
inputX = scaleRebel1CenteredMouseAxis(logicalX, kRA1CenterX, kRA1EnhancedFlightDirectMaxX);
inputY = scaleRebel1CenteredMouseAxis(logicalY, kRA1CenterY, kRA1EnhancedFlightDirectMaxY);
} else {
@@ -1085,6 +1088,7 @@ void InsaneRebel1::updateShipPhysics() {
// --- Step 1: Gameplay axes from FUN_231BE ---
// HandleGameOp07_ShipFlight consumes the preprocessed axes in DAT_756C/756E,
// not raw mouse coordinates. Reuse the same centered-axis law here.
+ const uint16 effectiveOpcode = getEffectiveGameOpcode();
int16 inputX = 0;
int16 inputY = 0;
bool usedJoystick = false;
@@ -1100,8 +1104,15 @@ void InsaneRebel1::updateShipPhysics() {
inputSourceName = "joystick-dpad";
// --- Step 2: Roll accumulator (_74CA) ---
- // Normal mode: accumulate; mode 0x10: snap to input
- _rollAccum += (_tuning.roll * (int32)inputX) >> 5;
+ // Normal mode: accumulate. For ScummVM's absolute mouse in GAME 0x09, steer
+ // toward a bounded roll target so holding the cursor off center does not
+ // continue accelerating the ship until it clamps.
+ if (effectiveOpcode == 0x09 && _activeInputSource == kInputSourceMouse && !usedJoystick) {
+ const int32 targetRoll = (int32)inputX * kRA1Op09MouseRollTargetScale;
+ _rollAccum += (targetRoll - _rollAccum) >> 2;
+ } else {
+ _rollAccum += (_tuning.roll * (int32)inputX) >> 5;
+ }
_rollAccum = CLIP<int32>(_rollAccum, -0x47F, 0x47F);
// --- Step 3: Vertical smoothing (_74CE) ---
Commit: 27da4fc2a56a6582fd1c410a62cbd76c98e96691
https://github.com/scummvm/scummvm/commit/27da4fc2a56a6582fd1c410a62cbd76c98e96691
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-06T15:34:32+02:00
Commit Message:
SCUMM: RA1: reduce crazy oscilation when using the mouse in some levels
Changed paths:
engines/scumm/insane/rebel1/iact.cpp
diff --git a/engines/scumm/insane/rebel1/iact.cpp b/engines/scumm/insane/rebel1/iact.cpp
index 2b9b4a70847..9c96d37650a 100644
--- a/engines/scumm/insane/rebel1/iact.cpp
+++ b/engines/scumm/insane/rebel1/iact.cpp
@@ -87,7 +87,7 @@ const int kRA1CenteredAxisMax = 127;
const int kRA1Op0BVerticalAxisMax = 100;
const int kRA1EnhancedFlightDirectMaxX = 64;
const int kRA1EnhancedFlightDirectMaxY = 40;
-const int kRA1Op09MouseRollTargetScale = 16;
+const int kRA1MouseFlightRollTargetScale = 16;
const int kRA1ControlPadAxisStep = 0x1E;
const int16 kOnFootCenterX = 0xA3; // g_perspectiveX in HandleGameOp19
const int16 kOnFootCenterY = 0x82; // g_perspectiveY in HandleGameOp19
@@ -1104,11 +1104,12 @@ void InsaneRebel1::updateShipPhysics() {
inputSourceName = "joystick-dpad";
// --- Step 2: Roll accumulator (_74CA) ---
- // Normal mode: accumulate. For ScummVM's absolute mouse in GAME 0x09, steer
- // toward a bounded roll target so holding the cursor off center does not
- // continue accelerating the ship until it clamps.
- if (effectiveOpcode == 0x09 && _activeInputSource == kInputSourceMouse && !usedJoystick) {
- const int32 targetRoll = (int32)inputX * kRA1Op09MouseRollTargetScale;
+ // Normal mode: accumulate. For ScummVM's absolute mouse in flight handlers,
+ // steer toward a bounded roll target so holding the cursor off center does
+ // not continue accelerating the ship until it clamps.
+ if ((effectiveOpcode == 0x07 || effectiveOpcode == 0x09) &&
+ _activeInputSource == kInputSourceMouse && !usedJoystick) {
+ const int32 targetRoll = (int32)inputX * kRA1MouseFlightRollTargetScale;
_rollAccum += (targetRoll - _rollAccum) >> 2;
} else {
_rollAccum += (_tuning.roll * (int32)inputX) >> 5;
More information about the Scummvm-git-logs
mailing list