[Scummvm-git-logs] scummvm master -> ccd5a4ecac9740d11e2095da0c26dbe16a0d8746
neuromancer
noreply at scummvm.org
Sat Jun 6 12:21:11 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:
aa8ea34af2 SCUMM: RA1: padding in level names in level selection menu
9bfbce7dd0 SCUMM: RA1: implement damage in L9
ccd5a4ecac SCUMM: RA1: better controls for L9
Commit: aa8ea34af20cbed6d6c16c9ad30afade426f2080
https://github.com/scummvm/scummvm/commit/aa8ea34af20cbed6d6c16c9ad30afade426f2080
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-06T14:03:54+02:00
Commit Message:
SCUMM: RA1: padding in level names in level selection menu
Changed paths:
engines/scumm/insane/rebel1/menu.cpp
diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp
index 7a67f39b3ac..f0613e5c408 100644
--- a/engines/scumm/insane/rebel1/menu.cpp
+++ b/engines/scumm/insane/rebel1/menu.cpp
@@ -1077,39 +1077,45 @@ void InsaneRebel1::renderLevelSelectOverlay(byte *dst, int pitch, int width, int
const int titleW = getFontBankStringWidth("LEVEL SELECT");
drawMenuTitleText(dst, pitch, width, height, getRebel1MenuCenteredX(titleW), 15, "LEVEL SELECT");
- const char *kLevelItems[kRA1LevelSelectItemCount] = {
- " 1 TRAINING",
- " 2 ASTEROIDS",
- " 3 KOLAADOR",
- " 4 STAR DESTR",
- " 5 TATOOINE",
- " 6 AST CHASE",
- " 7 PROBES",
- " 8 WALKERS",
- " 9 TROOPERS",
- "10 TRANSPORT",
- "11 YAVIN",
- "12 TIE ATK",
+ const char *const kLevelItems[kRA1NumLevels] = {
+ "1 TRAINING ",
+ "2 ASTEROIDS ",
+ "3 KOLAADOR ",
+ "4 STAR DESTR",
+ "5 TATOOINE ",
+ "6 AST CHASE ",
+ "7 PROBES ",
+ "8 WALKERS ",
+ "9 TROOPERS ",
+ "10 TRANSPORT ",
+ "11 YAVIN ",
+ "12 TIE ATK ",
"13 DS SURFACE",
- "14 CANNON",
- "15 DS TRENCH",
- "BACK"
+ "14 CANNON ",
+ "15 DS TRENCH "
};
+ const char *const kBackItem = "BACK";
const int menuY = 0x2d;
const int leftFrameX = kRA1LevelSelectLeftX;
const int rightFrameX = kRA1LevelSelectRightX;
const int columnW = kRA1LevelSelectColW;
+ int levelTextW = 0;
+
+ for (int i = 0; i < kRA1NumLevels; i++)
+ levelTextW = MAX(levelTextW, getMenuTalkTextWidth(kLevelItems[i]));
for (int i = 0; i < kRA1LevelSelectItemCount; i++) {
const int col = i / kRA1LevelSelectRowsPerCol;
const int row = i % kRA1LevelSelectRowsPerCol;
const int frameX = (col == 0) ? leftFrameX : rightFrameX;
const int y = menuY + row * kRA1MenuRowH;
- const int textW = getMenuTalkTextWidth(kLevelItems[i]);
+ const bool levelItem = i < kRA1NumLevels;
+ const char *text = levelItem ? kLevelItems[i] : kBackItem;
+ const int textW = levelItem ? levelTextW : getMenuTalkTextWidth(text);
const int textX = frameX + (columnW - textW) / 2;
- drawMenuTalkText(dst, pitch, width, height, textX, y, kLevelItems[i]);
+ drawMenuTalkText(dst, pitch, width, height, textX, y, text);
if (i == _levelSelectSel)
drawRebel1MenuFrame(dst, pitch, width, height,
Commit: 9bfbce7dd0fdca768cf334b41fd473ceb827485d
https://github.com/scummvm/scummvm/commit/9bfbce7dd0fdca768cf334b41fd473ceb827485d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-06T14:03:54+02:00
Commit Message:
SCUMM: RA1: implement damage in L9
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 41232a893bd..614338dd842 100644
--- a/engines/scumm/insane/rebel1/iact.cpp
+++ b/engines/scumm/insane/rebel1/iact.cpp
@@ -1907,9 +1907,11 @@ void InsaneRebel1::updateOnFootSequence() {
_shipDirIndex = 4; // Walk left
}
- // --- Scripted damage latches â damageFlags (matching FUN_1B297 pattern) ---
- // GAME 0x5D/0x5F set latches; convert to damage flags before the check.
- if (_gameLatch5D == 0xFFFF)
+ // --- Scripted damage latches â damageFlags ---
+ // L9 on-foot trooper shots use ordinary 0x5D event ids, gated by the
+ // 0x5D object bitmask handler, then consumed by FUN_1ED95 through 0x74D4.
+ // The ship loops keep narrower level-specific 0x5D damage rules.
+ if (_gameLatch5D != 0)
_damageFlags |= 0x40;
if (_gameLatch5F != 0 &&
_vm->_rnd.getRandomNumber((uint16)(_gameLatch5F - 1)) == 0)
@@ -1919,6 +1921,7 @@ void InsaneRebel1::updateOnFootSequence() {
// On-foot damage uses the same heavy-damage tuning byte as ship shot/collision
// damage in the original, not the miss penalty.
if (_damageFlags != 0 && _damageCooldown == 0 && _health >= 0 && _deathTimer < 1) {
+ const int16 oldHealth = _health;
_health -= _tuning.shot;
if (_health < 0) {
_deathTimer = 15;
@@ -1928,6 +1931,8 @@ void InsaneRebel1::updateOnFootSequence() {
_damageCooldown = 3;
playSfx(kSfxBoom, 127, 0);
_screenFlash = 5;
+ debugC(DEBUG_INSANE, "RA1 on-foot player hit: frame=%u latch=%u flags=0x%02x health=%d->%d",
+ (unsigned)(uint16)_gameCounter, (unsigned)_gameLatch5D, _damageFlags, oldHealth, _health);
}
}
Commit: ccd5a4ecac9740d11e2095da0c26dbe16a0d8746
https://github.com/scummvm/scummvm/commit/ccd5a4ecac9740d11e2095da0c26dbe16a0d8746
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-06T14:03:54+02:00
Commit Message:
SCUMM: RA1: better controls for L9
Changed paths:
engines/scumm/insane/rebel1/iact.cpp
engines/scumm/insane/rebel1/rebel.h
diff --git a/engines/scumm/insane/rebel1/iact.cpp b/engines/scumm/insane/rebel1/iact.cpp
index 614338dd842..61b7a30e28e 100644
--- a/engines/scumm/insane/rebel1/iact.cpp
+++ b/engines/scumm/insane/rebel1/iact.cpp
@@ -88,6 +88,14 @@ const int kRA1Op0BVerticalAxisMax = 100;
const int kRA1EnhancedFlightDirectMaxX = 64;
const int kRA1EnhancedFlightDirectMaxY = 40;
const int kRA1ControlPadAxisStep = 0x1E;
+const int16 kOnFootCenterX = 0xA3; // g_perspectiveX in HandleGameOp19
+const int16 kOnFootCenterY = 0x82; // g_perspectiveY in HandleGameOp19
+const int16 kOnFootCursorBaseY = kOnFootCenterY - 0x32;
+const int16 kOnFootGamepadStep = 7;
+const int16 kOnFootCursorMinX = 0;
+const int16 kOnFootCursorMaxX = 319;
+const int16 kOnFootCursorMinY = 0;
+const int16 kOnFootCursorMaxY = 199;
// Level 15 final approach 0x5D damage/event codes consumed by
// RunLevel1GameLoop. The latch stores the raw GAME parameter; no translation is
@@ -1837,9 +1845,6 @@ bool InsaneRebel1::isTorpedoModeActive() const {
// g_perspectiveX/Y = crosshair center (on-foot targeting)
// Our _perspectiveX/_perspectiveY maps to the camera offset (DAT_000041a0/41a2).
// The crosshair center (0xA3, 0x82) is a separate constant for on-foot mode.
-const int16 kOnFootCenterX = 0xA3; // g_perspectiveX in HandleGameOp19
-const int16 kOnFootCenterY = 0x82; // g_perspectiveY in HandleGameOp19
-
// Port split matching HandleGameOp19_OnFootSequence. The helper name is new to
// this implementation; the original code dispatches the opcode handler directly.
void InsaneRebel1::initOnFootSequence() {
@@ -1861,6 +1866,74 @@ void InsaneRebel1::initOnFootSequence() {
}
}
+void InsaneRebel1::preprocessOnFootAim(int16 &inputX, int16 &inputY, bool *usedJoystick) {
+ if (usedJoystick)
+ *usedJoystick = false;
+
+ const int dpadX =
+ (_vm->getActionState(kScummActionInsaneRight) ? 1 : 0) -
+ (_vm->getActionState(kScummActionInsaneLeft) ? 1 : 0);
+ int dpadY =
+ (_vm->getActionState(kScummActionInsaneDown) ? 1 : 0) -
+ (_vm->getActionState(kScummActionInsaneUp) ? 1 : 0);
+
+ const int16 analogAxisX = applyRebel1AnalogDeadzone(_joystickAxisX);
+ int16 analogAxisY = applyRebel1AnalogDeadzone(_joystickAxisY);
+ if (_optControlsYFlip) {
+ dpadY = -dpadY;
+ analogAxisY = (int16)-analogAxisY;
+ }
+
+ int deltaX = 0;
+ int deltaY = 0;
+ bool activeGamepadAim = false;
+
+ if (dpadX || dpadY) {
+ deltaX = dpadX * kOnFootGamepadStep;
+ deltaY = dpadY * kOnFootGamepadStep;
+ activeGamepadAim = true;
+ } else if (_activeInputSource == kInputSourceJoystickAnalog && (analogAxisX || analogAxisY)) {
+ const int analogX = CLIP<int32>(((int32)analogAxisX * kRA1CenteredAxisMax) / Common::JOYAXIS_MAX,
+ -kRA1CenteredAxisMax, kRA1CenteredAxisMax);
+ const int analogY = CLIP<int32>(((int32)analogAxisY * kRA1CenteredAxisMax) / Common::JOYAXIS_MAX,
+ -kRA1CenteredAxisMax, kRA1CenteredAxisMax);
+ deltaX = stepRebel1Op0BReticleAxis(analogX);
+ deltaY = stepRebel1Op0BReticleAxis(analogY);
+ activeGamepadAim = (deltaX != 0 || deltaY != 0);
+ }
+
+ if (activeGamepadAim) {
+ if (!_gamepadAimActive) {
+ _gamepadAimAxisX = CLIP<int16>(_shipPosX, kOnFootCursorMinX, kOnFootCursorMaxX);
+ _gamepadAimAxisY = CLIP<int16>(_shipPosY, kOnFootCursorMinY, kOnFootCursorMaxY);
+ }
+
+ _gamepadAimAxisX = CLIP<int16>((int16)(_gamepadAimAxisX + deltaX), kOnFootCursorMinX, kOnFootCursorMaxX);
+ _gamepadAimAxisY = CLIP<int16>((int16)(_gamepadAimAxisY + deltaY), kOnFootCursorMinY, kOnFootCursorMaxY);
+ _gamepadAimActive = true;
+
+ if (usedJoystick)
+ *usedJoystick = true;
+ inputX = (int16)(_gamepadAimAxisX - kOnFootCenterX);
+ inputY = (int16)(_gamepadAimAxisY - kOnFootCursorBaseY);
+ return;
+ }
+
+ if (_gamepadAimActive && _activeInputSource != kInputSourceMouse) {
+ if (usedJoystick)
+ *usedJoystick = true;
+ inputX = (int16)(_gamepadAimAxisX - kOnFootCenterX);
+ inputY = (int16)(_gamepadAimAxisY - kOnFootCursorBaseY);
+ return;
+ }
+
+ _gamepadAimActive = false;
+ const int16 logicalX = (int16)CLIP<int>(_vm->_mouse.x, kOnFootCursorMinX, kOnFootCursorMaxX);
+ const int16 logicalY = (int16)CLIP<int>(_vm->_mouse.y, kOnFootCursorMinY, kOnFootCursorMaxY);
+ inputX = (int16)(logicalX - kOnFootCenterX);
+ inputY = (int16)(logicalY - kOnFootCursorBaseY);
+}
+
// Port split matching HandleGameOp19_OnFootSequence. The helper name is new to
// this implementation; the original code dispatches the opcode handler directly.
void InsaneRebel1::updateOnFootSequence() {
@@ -1899,8 +1972,10 @@ void InsaneRebel1::updateOnFootSequence() {
} else {
// Walking based on input direction. The 3DO second held button skips the
// early aim-pose branch above and reaches these walk tests immediately.
- int16 inputX = 0, inputY = 0;
- preprocessMouseAxes(inputX, inputY);
+ int16 inputX = (int16)(_shipPosX - kOnFootCenterX);
+ int16 inputY = (int16)(_shipPosY - kOnFootCursorBaseY);
+ if (!hasFrameGameOpcode(0x1A))
+ preprocessOnFootAim(inputX, inputY);
if (inputX > 0x1E && _onFootCharX < 0x73)
_shipDirIndex = 6; // Walk right
else if (inputX < -0x1E && _onFootCharX > -0x73)
@@ -1940,13 +2015,13 @@ void InsaneRebel1::updateOnFootSequence() {
// this implementation; the original code dispatches the opcode handler directly.
void InsaneRebel1::updateOnFootAimVariant() {
// --- 0x1A: Crosshair positioning (HandleGameOp1A_OnFootVariant) ---
- // shipPosX/Y = mouse_input + crosshair_center + character_offset
+ // DOS used virtual-mouse axes relative to the character offset. ScummVM's
+ // mouse and gamepad reticle are screen-space controls so the cursor remains
+ // able to cross the whole playfield while Luke is standing at either side.
int16 inputX = 0, inputY = 0;
- preprocessMouseAxes(inputX, inputY);
- inputX = CLIP<int16>(inputX, -100, 100);
- int16 inputYNeg = CLIP<int16>((int16)(-inputY), -0x4B, 0x0F);
- _shipPosX = inputX + kOnFootCenterX + _onFootCharX;
- _shipPosY = inputYNeg + kOnFootCenterY + _onFootCharY - 0x32;
+ preprocessOnFootAim(inputX, inputY);
+ _shipPosX = CLIP<int16>((int16)(inputX + kOnFootCenterX), kOnFootCursorMinX, kOnFootCursorMaxX);
+ _shipPosY = CLIP<int16>((int16)(inputY + kOnFootCursorBaseY), kOnFootCursorMinY, kOnFootCursorMaxY);
}
void InsaneRebel1::finishOnFootFrame() {
diff --git a/engines/scumm/insane/rebel1/rebel.h b/engines/scumm/insane/rebel1/rebel.h
index b191854248b..041a528e978 100644
--- a/engines/scumm/insane/rebel1/rebel.h
+++ b/engines/scumm/insane/rebel1/rebel.h
@@ -386,6 +386,7 @@ private:
// 0x19/0x1A on-foot handler (Level 9 Stormtroopers)
void initOnFootSequence();
+ void preprocessOnFootAim(int16 &inputX, int16 &inputY, bool *usedJoystick = nullptr);
void updateOnFootSequence();
void updateOnFootAimVariant();
void finishOnFootFrame();
More information about the Scummvm-git-logs
mailing list