From noreply at scummvm.org Mon Jun 1 05:06:45 2026 From: noreply at scummvm.org (mgerhardy) Date: Mon, 1 Jun 2026 05:06:45 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm-tools master -> 309b22a7c4958350e5ef1e35dc7bbeee098d04ae Message-ID: <20260601050645.0608A700591@ron.scummvm.net> This automated email contains information about 1 new commit which have been pushed to the 'scummvm-tools' repo located at https://api.github.com/repos/scummvm/scummvm-tools . Summary: 309b22a7c4 MACS2: updated decompiler Commit: 309b22a7c4958350e5ef1e35dc7bbeee098d04ae https://github.com/scummvm/scummvm-tools/commit/309b22a7c4958350e5ef1e35dc7bbeee098d04ae Author: Martin Gerhardy (martin.gerhardy at gmail.com) Date: 2026-05-31T17:32:32+02:00 Commit Message: MACS2: updated decompiler Changed paths: engines/macs2/demacs2.cpp diff --git a/engines/macs2/demacs2.cpp b/engines/macs2/demacs2.cpp index da344f37..099ec06e 100644 --- a/engines/macs2/demacs2.cpp +++ b/engines/macs2/demacs2.cpp @@ -19,7 +19,7 @@ * */ -/* MACS2 Script disassembler */ +/* MACS2 Script decompiler */ #include #include @@ -45,76 +45,36 @@ static uint16_t readWord() { static std::string formatValue() { uint8_t type = readByte(); - uint16_t index = readWord(); + uint16_t val = readWord(); if (type == 0x00) { char buf[32]; - snprintf(buf, sizeof(buf), "%u", index); + snprintf(buf, sizeof(buf), "%u", val); return buf; } else if (type == 0xFF) { - // Special runtime values - const char *name = nullptr; - switch (index) { - case 0x01: name = "interacted_use"; break; - case 0x02: name = "interacted_look"; break; - case 0x03: name = "interacted_talk"; break; - case 0x04: name = "char_area"; break; - case 0x05: name = "noop"; break; - case 0x06: return "1"; - case 0x07: return "0"; - case 0x08: return "0"; - case 0x09: return "0"; - case 0x0A: return "1"; - case 0x0B: name = "repeat_run_flag"; break; - case 0x0C: return "1"; - case 0x0D: name = "chosen_dialogue_option"; break; - case 0x23: name = "path_walkable_result"; break; - case 0x24: name = "actor_x"; break; - case 0x25: name = "actor_y"; break; - case 0x26: name = "is_scene_init"; break; - case 0x27: name = "repeat_char_area"; break; - case 0x28: name = "inventory_check_result"; break; - case 0x29: name = "anim_range_test_result"; break; - case 0x2A: name = "inventory_combine_flag"; break; - case 0x2B: name = "inventory_action_flag"; break; - case 0x2C: name = "interacted_panel_use"; break; - case 0x2D: name = "current_scene"; break; - case 0x2E: return "2"; - case 0x2F: name = "last_scene"; break; - case 0x30: name = "music_enabled"; break; - case 0x31: name = "sound_enabled"; break; + switch (val) { + case 0x01: return "interactedUse"; + case 0x02: return "interactedLook"; + case 0x03: return "interactedTalk"; + case 0x04: return "areaAtActor"; + case 0x0B: return "isRepeatRun"; + case 0x0D: return "dialogueResult"; + case 0x23: return "pathWalkable"; + case 0x24: return "actorX"; + case 0x25: return "actorY"; + case 0x26: return "isSceneInit"; + case 0x28: return "invCheck"; + case 0x2A: return "invCombine"; + case 0x2B: return "invAction"; + case 0x2D: return "curScene"; + case 0x2F: return "prevScene"; default: - if (index >= 0x0E && index <= 0x22) { - char buf[32]; - snprintf(buf, sizeof(buf), "%u", index - 0x0D); - return buf; - } char buf[32]; - snprintf(buf, sizeof(buf), "$special_0x%02x", index); + snprintf(buf, sizeof(buf), "special[0x%02x]", val); return buf; } - return std::string("$") + name; - } else { - char buf[32]; - snprintf(buf, sizeof(buf), "var[%u]", index); - return buf; } -} - -// Read a value but return both words as "val" (for 32-bit context) -static std::string formatValue32() { - return formatValue(); -} - -static std::string formatObjectId() { - std::string v = formatValue(); - return v + " - 0x400"; -} - -static std::string formatSaveTarget() { - readByte(); // type (ignored for save target) - uint16_t index = readWord(); char buf[32]; - snprintf(buf, sizeof(buf), "var[%u]", index); + snprintf(buf, sizeof(buf), "var[%u]", val); return buf; } @@ -126,7 +86,7 @@ static const char *cmpOpName(uint8_t op) { case 0x04: return ">"; case 0x05: return "<="; case 0x06: return ">="; - default: return "??"; + default: return "?"; } } @@ -141,490 +101,472 @@ static void disassemble() { uint8_t length = readByte(); uint32_t endPos = pos + length; - // Adjust indent before printing for block-end opcodes + // Adjust indent for block-end opcodes if (opcode == 0x07 && indent > 0) indent--; + if (opcode == 0x08 && indent > 0) indent--; - // Print indent for (int i = 0; i < indent; i++) printf(" "); - printf("[%04X] ", instrAddr); + printf("%04x: ", instrAddr); switch (opcode) { - case 0x01: { - readByte(); // padding + case 0x01: { // setVar + readByte(); uint16_t varIdx = readWord(); std::string val = formatValue(); - printf("SET var[%u] = %s\n", varIdx, val.c_str()); + printf("setVar var[%u] = %s\n", varIdx, val.c_str()); break; } - case 0x02: { - readByte(); // padding + case 0x02: { // setVarOr + readByte(); uint16_t varIdx = readWord(); - std::string val1 = formatValue(); - std::string val2 = formatValue(); - printf("SET_OR var[%u] = %s | %s\n", varIdx, val1.c_str(), val2.c_str()); + std::string val = formatValue(); + printf("setVarOr var[%u] = %s\n", varIdx, val.c_str()); break; } - case 0x03: { + case 0x03: { // ifTrue std::string val = formatValue(); - printf("IF_TRUE %s THEN SKIP {\n", val.c_str()); + printf("ifTrue (%s)\n", val.c_str()); indent++; break; } - case 0x04: { + case 0x04: { // ifFalse std::string val = formatValue(); - printf("IF_FALSE %s THEN SKIP {\n", val.c_str()); + printf("ifFalse (%s)\n", val.c_str()); indent++; break; } - case 0x05: { + case 0x05: { // compare uint8_t cmpOp = readByte(); - std::string v1 = formatValue(); - std::string v2 = formatValue(); - printf("IF %s %s %s {\n", v1.c_str(), cmpOpName(cmpOp), v2.c_str()); + std::string a = formatValue(); + std::string b = formatValue(); + printf("compare (%s %s %s)\n", a.c_str(), cmpOpName(cmpOp), b.c_str()); indent++; break; } - case 0x06: { + case 0x06: { // ifInteraction uint8_t subOp = readByte(); - std::string obj1 = formatValue(); - std::string obj2 = formatValue(); - std::string cmp1 = formatValue(); - std::string cmp2 = formatValue(); - if (subOp == 0x01) - printf("IF_USE_ON (%s, %s) MATCHES (%s, %s) {\n", obj1.c_str(), obj2.c_str(), cmp1.c_str(), cmp2.c_str()); - else - printf("IF_USE_ON (%s, %s) NOT_MATCHES (%s, %s) {\n", obj1.c_str(), obj2.c_str(), cmp1.c_str(), cmp2.c_str()); + std::string i = formatValue(); + std::string a = formatValue(); + std::string b = formatValue(); + printf("ifInteraction %s(%s, %s, %s)\n", subOp == 2 ? "NOT " : "", i.c_str(), a.c_str(), b.c_str()); indent++; break; } - case 0x07: { - printf("}\n"); + case 0x07: { // endIf + printf("endIf\n"); break; } - case 0x08: { - printf("} ELSE {\n"); + case 0x08: { // else + printf("else\n"); + indent++; break; } - case 0x0A: { + case 0x0A: { // printString std::string x = formatValue(); std::string y = formatValue(); uint16_t strOffset = readWord(); uint16_t numLines = readWord(); - printf("PRINT_STRING pos=(%s, %s) strOffset=%u numLines=%u\n", x.c_str(), y.c_str(), strOffset, numLines); + printf("printString pos=(%s, %s) strOffset=%u numLines=%u\n", x.c_str(), y.c_str(), strOffset, numLines); break; } - case 0x0B: { - std::string objId = formatObjectId(); + case 0x0B: { // moveObject + std::string obj = formatValue(); std::string scene = formatValue(); std::string x = formatValue(); std::string y = formatValue(); - printf("MOVE_OBJECT obj=%s toScene=%s pos=(%s, %s)\n", objId.c_str(), scene.c_str(), x.c_str(), y.c_str()); + printf("moveObject obj=%s scene=%s pos=(%s, %s)\n", obj.c_str(), scene.c_str(), x.c_str(), y.c_str()); break; } - case 0x0C: { - std::string scene = formatValue32(); + case 0x0C: { // changeScene + std::string scene = formatValue(); std::string mode = formatValue(); std::string speed = formatValue(); - printf("CHANGE_SCENE scene=%s mode=%s speed=%s\n", scene.c_str(), mode.c_str(), speed.c_str()); + printf("changeScene scene=%s mode=%s speed=%s\n", scene.c_str(), mode.c_str(), speed.c_str()); break; } - case 0x0D: { - std::string objId = formatObjectId(); + case 0x0D: { // showDialogue + std::string obj = formatValue(); std::string x = formatValue(); std::string y = formatValue(); std::string side = formatValue(); uint16_t strOffset = readWord(); uint16_t numLines = readWord(); - printf("DIALOGUE speaker=%s pos=(%s, %s) side=%s strOffset=%u numLines=%u\n", - objId.c_str(), x.c_str(), y.c_str(), side.c_str(), strOffset, numLines); + printf("showDialogue obj=%s pos=(%s, %s) side=%s strOffset=%u numLines=%u\n", + obj.c_str(), x.c_str(), y.c_str(), side.c_str(), strOffset, numLines); break; } - case 0x0E: { - std::string id = formatValue32(); - std::string frame = formatValue(); - printf("CHANGE_ANIM id=%s frame=%s\n", id.c_str(), frame.c_str()); + case 0x0E: { // changeAnim + printf("changeAnim\n"); break; } - case 0x0F: { - std::string duration = formatValue(); - printf("WAIT_FRAMES %s\n", duration.c_str()); + case 0x0F: { // frameWait + std::string val = formatValue(); + printf("frameWait %s\n", val.c_str()); break; } - case 0x10: { - std::string objId = formatObjectId(); + case 0x10: { // walkTo + std::string obj = formatValue(); std::string x = formatValue(); std::string y = formatValue(); - printf("WALK_TO obj=%s pos=(%s, %s)\n", objId.c_str(), x.c_str(), y.c_str()); + printf("walkTo obj=%s pos=(%s, %s)\n", obj.c_str(), x.c_str(), y.c_str()); break; } - case 0x11: { - std::string objId = formatObjectId(); - printf("WAIT_WALK obj=%s\n", objId.c_str()); + case 0x11: { // waitForWalk + std::string obj = formatValue(); + printf("waitForWalk obj=%s\n", obj.c_str()); break; } - case 0x12: { + case 0x12: { // setPathOverride std::string area = formatValue(); std::string active = formatValue(); - std::string override_val = formatValue(); - printf("SET_PATHFINDING area=%s active=%s override=%s\n", area.c_str(), active.c_str(), override_val.c_str()); + std::string val = formatValue(); + printf("setPathOverride area=%s active=%s val=%s\n", area.c_str(), active.c_str(), val.c_str()); break; } - case 0x13: { - uint16_t tag = readWord(); - printf("GOTO_TAG 0x%04X\n", tag); + case 0x13: { // loadAnim + printf("loadAnim\n"); break; } - case 0x14: { - uint16_t tag = readWord(); - printf("TAG 0x%04X\n", tag); + case 0x14: { // skipWord + uint16_t w = readWord(); + printf("skipWord 0x%04x\n", w); break; } - case 0x15: { - printf("DIALOGUE_CHOICES_BEGIN\n"); + case 0x15: { // clearDialogueChoices + printf("clearDialogueChoices\n"); break; } - case 0x16: { + case 0x16: { // addDialogueChoice std::string idx = formatValue(); uint16_t strOffset = readWord(); uint16_t numLines = readWord(); - printf("DIALOGUE_CHOICE index=%s strOffset=%u numLines=%u\n", idx.c_str(), strOffset, numLines); + printf("addDialogueChoice idx=%s strOffset=%u numLines=%u\n", idx.c_str(), strOffset, numLines); break; } - case 0x17: { - std::string x = formatValue32(); - std::string y = formatValue32(); + case 0x17: { // showDialogueChoice + std::string obj = formatValue(); + std::string x = formatValue(); + std::string y = formatValue(); std::string side = formatValue(); - printf("DIALOGUE_CHOICES_SHOW pos=(%s, %s) side=%s\n", x.c_str(), y.c_str(), side.c_str()); + printf("showDialogueChoice obj=%s pos=(%s, %s) side=%s\n", obj.c_str(), x.c_str(), y.c_str(), side.c_str()); break; } - case 0x18: { - printf("END_SCRIPT\n"); + case 0x18: { // dismissPanel + printf("dismissPanel\n"); break; } - case 0x19: { - std::string actor = formatObjectId(); - std::string target = formatObjectId(); - printf("PICKUP actor=%s target=%s\n", actor.c_str(), target.c_str()); + case 0x19: { // walkToAndPickup + std::string actor = formatValue(); + std::string obj = formatValue(); + printf("walkToAndPickup actor=%s obj=%s\n", actor.c_str(), obj.c_str()); break; } - case 0x1A: { - std::string objId = formatObjectId(); - std::string val217 = formatValue(); - std::string val219 = formatValue(); - printf("SET_OBJECT_RUNTIME obj=%s val217=%s val219=%s\n", objId.c_str(), val217.c_str(), val219.c_str()); + case 0x1A: { // setPickupFrames + std::string obj = formatValue(); + std::string start = formatValue(); + std::string end = formatValue(); + printf("setPickupFrames obj=%s start=%s end=%s\n", obj.c_str(), start.c_str(), end.c_str()); break; } - case 0x1B: { - std::string objId = formatObjectId(); + case 0x1B: { // setAnimSpeed + std::string obj = formatValue(); std::string slot = formatValue(); - std::string val = formatValue(); - printf("SET_OBJECT_SLOT obj=%s slot=%s value=%s\n", objId.c_str(), slot.c_str(), val.c_str()); + std::string speed = formatValue(); + printf("setAnimSpeed obj=%s slot=%s speed=%s\n", obj.c_str(), slot.c_str(), speed.c_str()); break; } - case 0x1C: { - printf("SKIPPABLE_BEGIN\n"); + case 0x1C: { // setSkippable + printf("setSkippable\n"); break; } - case 0x1D: { - printf("SKIPPABLE_END\n"); + case 0x1D: { // clearSkippable + printf("clearSkippable\n"); break; } - case 0x1E: { - std::string objId = formatObjectId(); + case 0x1E: { // loadAnimBlob + std::string obj = formatValue(); std::string slot = formatValue(); std::string frame = formatValue(); - printf("PLAY_ANIM obj=%s slot=%s frame=%s\n", objId.c_str(), slot.c_str(), frame.c_str()); + printf("loadAnimBlob obj=%s slot=%s frame=%s\n", obj.c_str(), slot.c_str(), frame.c_str()); break; } - case 0x1F: { - std::string objId = formatObjectId(); - std::string x = formatValue32(); - std::string y = formatValue32(); - printf("TEST_PATH_WALKABLE obj=%s to=(%s, %s)\n", objId.c_str(), x.c_str(), y.c_str()); + case 0x1F: { // setPosition + std::string obj = formatValue(); + std::string x = formatValue(); + std::string y = formatValue(); + printf("setPosition obj=%s pos=(%s, %s)\n", obj.c_str(), x.c_str(), y.c_str()); break; } - case 0x20: { - std::string objId = formatObjectId(); + case 0x20: { // setVerticalOffset + std::string obj = formatValue(); std::string offset = formatValue(); - printf("SET_Y_OFFSET obj=%s offset=%s\n", objId.c_str(), offset.c_str()); + printf("setVerticalOffset obj=%s offset=%s\n", obj.c_str(), offset.c_str()); break; } - case 0x21: { - std::string objId = formatObjectId(); + case 0x21: { // setMotion + std::string obj = formatValue(); std::string target = formatValue(); std::string delta = formatValue(); std::string dist = formatValue(); - printf("SET_MOTION obj=%s targetOffset=%s delta=%s distance=%s\n", objId.c_str(), target.c_str(), delta.c_str(), dist.c_str()); + printf("setMotion obj=%s target=%s delta=%s dist=%s\n", obj.c_str(), target.c_str(), delta.c_str(), dist.c_str()); break; } - case 0x22: { - std::string objId = formatObjectId(); - std::string orient = formatValue(); - printf("SET_ORIENTATION obj=%s orientation=%s\n", objId.c_str(), orient.c_str()); + case 0x22: { // setAnimIndex + std::string obj = formatValue(); + std::string anim = formatValue(); + printf("setAnimIndex obj=%s anim=%s\n", obj.c_str(), anim.c_str()); break; } - case 0x23: { - std::string objId = formatObjectId(); - std::string x = formatValue32(); - std::string y = formatValue32(); - std::string targetOffset = formatValue(); - printf("MOVE_TO_POSITION obj=%s pos=(%s, %s) targetOffset=%s\n", objId.c_str(), x.c_str(), y.c_str(), targetOffset.c_str()); + case 0x23: { // moveToPosition + std::string obj = formatValue(); + std::string x = formatValue(); + std::string y = formatValue(); + std::string voff = formatValue(); + printf("moveToPosition obj=%s pos=(%s, %s) voff=%s\n", obj.c_str(), x.c_str(), y.c_str(), voff.c_str()); break; } - case 0x24: { - std::string a = formatValue32(); - std::string b = formatValue32(); - // The save target is embedded in the first value's position - // We can't perfectly reconstruct it without re-reading, so show the operands - printf("ADD %s + %s -> (save to first operand var)\n", a.c_str(), b.c_str()); + case 0x24: { // add + std::string a = formatValue(); + std::string b = formatValue(); + printf("add %s, %s\n", a.c_str(), b.c_str()); break; } - case 0x25: { - std::string a = formatValue32(); - std::string b = formatValue32(); - printf("SUB %s - %s -> (save to first operand var)\n", a.c_str(), b.c_str()); + case 0x25: { // subtract + std::string a = formatValue(); + std::string b = formatValue(); + printf("subtract %s, %s\n", a.c_str(), b.c_str()); break; } - case 0x26: { - std::string objId = formatObjectId(); - std::string val = formatValue(); - uint8_t animId = readByte(); - printf("LOAD_SPECIAL_ANIM obj=%s val=%s animId=%u\n", objId.c_str(), val.c_str(), animId); + case 0x26: { // setAnimSlot + std::string obj = formatValue(); + formatValue(); // unused + uint8_t animIdx = readByte(); + printf("setAnimSlot obj=%s anim=%u\n", obj.c_str(), animIdx); break; } - case 0x27: { - std::string charId = formatValue(); - std::string val = formatValue(); - printf("SET_DIRECTION charId=%s value=%s\n", charId.c_str(), val.c_str()); + case 0x27: { // setMaxAnimFrame + std::string obj = formatValue(); + std::string maxFrame = formatValue(); + printf("setMaxAnimFrame obj=%s maxFrame=%s\n", obj.c_str(), maxFrame.c_str()); break; } - case 0x28: { - std::string objId = formatObjectId(); - printf("STOP_ANIM obj=%s\n", objId.c_str()); + case 0x28: { // nop28 + printf("nop28\n"); break; } - case 0x29: { - std::string objId = formatObjectId(); - printf("OPEN_INVENTORY source=%s\n", objId.c_str()); + case 0x29: { // loadSong + std::string obj = formatValue(); + printf("loadSong obj=%s\n", obj.c_str()); break; } - case 0x2A: { - std::string objId = formatObjectId(); + case 0x2A: { // loadAnimFromScene + std::string obj = formatValue(); std::string slot = formatValue(); std::string decode = formatValue(); - uint8_t arrayIdx = readByte(); - printf("LOAD_ANIM obj=%s slot=%s decode=%s arrayIdx=%u\n", objId.c_str(), slot.c_str(), decode.c_str(), arrayIdx); + uint8_t idx = readByte(); + printf("loadAnimFromScene obj=%s slot=%s decode=%s idx=%u\n", obj.c_str(), slot.c_str(), decode.c_str(), idx); break; } - case 0x2B: { - std::string objId = formatValue(); - printf("REFRESH_OBJECT obj=%s\n", objId.c_str()); + case 0x2B: { // setShading + std::string obj = formatValue(); + printf("setShading obj=%s\n", obj.c_str()); break; } - case 0x2C: { - std::string objId = formatValue(); - std::string parentId = formatValue(); - printf("CHECK_INVENTORY obj=%s parent=%s\n", objId.c_str(), parentId.c_str()); + case 0x2C: { // setParent + std::string obj = formatValue(); + std::string val = formatValue(); + printf("setParent obj=%s val=%s\n", obj.c_str(), val.c_str()); break; } - case 0x2D: { - std::string objId = formatValue(); - std::string enabled = formatValue(); - printf("SET_RUNTIME_FLAG obj=%s enabled=%s\n", objId.c_str(), enabled.c_str()); + case 0x2D: { // setScaling + std::string obj = formatValue(); + std::string val = formatValue(); + printf("setScaling obj=%s val=%s\n", obj.c_str(), val.c_str()); break; } - case 0x2E: { - std::string animIdx = formatValue32(); - std::string minFrame = formatValue32(); - std::string maxFrame = formatValue32(); - printf("TEST_SCENE_ANIM_FRAME animIdx=%s min=%s max=%s\n", animIdx.c_str(), minFrame.c_str(), maxFrame.c_str()); + case 0x2E: { // checkAnimRange + std::string anim = formatValue(); + std::string lo = formatValue(); + std::string hi = formatValue(); + printf("checkAnimRange anim=%s range=[%s, %s]\n", anim.c_str(), lo.c_str(), hi.c_str()); break; } - case 0x2F: { - std::string objId = formatObjectId(); + case 0x2F: { // checkBlobRange + std::string obj = formatValue(); std::string slot = formatValue(); - std::string minFrame = formatValue(); - std::string maxFrame = formatValue(); - printf("TEST_OBJECT_ANIM_FRAME obj=%s slot=%s min=%s max=%s\n", objId.c_str(), slot.c_str(), minFrame.c_str(), maxFrame.c_str()); + std::string lo = formatValue(); + std::string hi = formatValue(); + printf("checkBlobRange obj=%s slot=%s range=[%s, %s]\n", obj.c_str(), slot.c_str(), lo.c_str(), hi.c_str()); break; } - case 0x30: { - std::string x = formatValue(); - std::string y = formatValue(); - uint16_t strOffset = readWord(); - uint16_t numLines = readWord(); - printf("PRINT_STRING_RIGHT pos=(%s, %s) strOffset=%u numLines=%u\n", x.c_str(), y.c_str(), strOffset, numLines); + case 0x30: { // nop30 + printf("nop30\n"); break; } - case 0x31: { + case 0x31: { // setMusicVolume std::string vol = formatValue(); - printf("SET_VOLUME %s\n", vol.c_str()); + printf("setMusicVolume %s\n", vol.c_str()); break; } - case 0x32: { - std::string objId = formatValue(); - std::string clickable = formatValue(); - printf("SET_CLICKABLE obj=%s clickable=%s\n", objId.c_str(), clickable.c_str()); + case 0x32: { // setClickable + std::string obj = formatValue(); + std::string val = formatValue(); + printf("setClickable obj=%s val=%s\n", obj.c_str(), val.c_str()); break; } - case 0x33: { - std::string objId = formatValue(); - std::string visible = formatValue(); - printf("SET_VISIBLE obj=%s visible=%s\n", objId.c_str(), visible.c_str()); + case 0x33: { // setVisible + std::string obj = formatValue(); + std::string val = formatValue(); + printf("setVisible obj=%s val=%s\n", obj.c_str(), val.c_str()); break; } - case 0x34: { - std::string v1 = formatValue(); - std::string v2 = formatValue(); - printf("SET_HOTSPOT_OVERRIDE %s -> %s\n", v1.c_str(), v2.c_str()); + case 0x34: { // setHotspotRemap + std::string a = formatValue(); + std::string b = formatValue(); + printf("setHotspotRemap %s -> %s\n", a.c_str(), b.c_str()); break; } - case 0x35: { - std::string objId = formatValue(); - std::string otherId = formatValue(); - std::string val1 = formatValue(); - std::string val2 = formatValue(); - std::string val3 = formatValue(); - printf("SET_BOUNDS_ATTACHMENT obj=%s other=%s v1=%s v2=%s v3=%s\n", - objId.c_str(), otherId.c_str(), val1.c_str(), val2.c_str(), val3.c_str()); + case 0x35: { // setBoundsAttach + std::string obj = formatValue(); + std::string parent = formatValue(); + std::string a = formatValue(); + std::string b = formatValue(); + std::string c = formatValue(); + printf("setBoundsAttach obj=%s parent=%s (%s, %s, %s)\n", + obj.c_str(), parent.c_str(), a.c_str(), b.c_str(), c.c_str()); break; } - case 0x36: { - printf("DISMISS_PANEL\n"); + case 0x36: { // dismissAllPanels + printf("dismissAllPanels\n"); break; } - case 0x37: { - printf("RESET_TO_SCENE_SCRIPT\n"); + case 0x37: { // resetScript + printf("resetScript\n"); break; } - case 0x38: { + case 0x38: { // loadOverlayFont uint8_t resIdx = readByte(); - printf("LOAD_OVERLAY_FONT resource=%u\n", resIdx); + printf("loadOverlayFont res=%u\n", resIdx); break; } - case 0x39: { - printf("END_OVERLAY_TEXT\n"); + case 0x39: { // endOverlayText + printf("endOverlayText\n"); break; } - case 0x3A: { + case 0x3A: { // addOverlayEntry std::string x = formatValue(); std::string y = formatValue(); std::string align = formatValue(); uint16_t strOffset = readWord(); uint16_t entryType = readWord(); - printf("OVERLAY_TEXT_ENTRY pos=(%s, %s) align=%s strOffset=%u type=%u\n", + printf("addOverlayEntry pos=(%s, %s) align=%s str=%u type=%u\n", x.c_str(), y.c_str(), align.c_str(), strOffset, entryType); break; } - case 0x3B: { - printf("CLEAR_OVERLAY_TEXT\n"); + case 0x3B: { // clearOverlayEntries + printf("clearOverlayEntries\n"); break; } - case 0x3C: { + case 0x3C: { // fadeToBlack std::string speed = formatValue(); - printf("FADE_TO_BLACK speed=%s\n", speed.c_str()); + printf("fadeToBlack %s\n", speed.c_str()); break; } - case 0x3D: { + case 0x3D: { // fadeFromBlack std::string speed = formatValue(); - printf("FADE_IN speed=%s\n", speed.c_str()); + printf("fadeFromBlack %s\n", speed.c_str()); break; } - case 0x3E: { + case 0x3E: { // loadSoundRes uint8_t resIdx = readByte(); - printf("LOAD_SOUND resource=%u\n", resIdx); + printf("loadSoundRes res=%u\n", resIdx); break; } - case 0x3F: { - printf("STOP_SOUND\n"); + case 0x3F: { // clearSound + printf("clearSound\n"); break; } - case 0x40: { - printf("PLAY_SOUND\n"); + case 0x40: { // playSound + printf("playSound\n"); break; } - case 0x41: { - printf("WAIT_SOUND\n"); + case 0x41: { // waitForSound + printf("waitForSound\n"); break; } - case 0x42: { - printf("STOP_CURRENT_SOUND\n"); + case 0x42: { // stopSound + printf("stopSound\n"); break; } - case 0x43: { + case 0x43: { // loadMusicSlot std::string slot = formatValue(); uint8_t resIdx = readByte(); - printf("LOAD_MUSIC slot=%s resource=%u\n", slot.c_str(), resIdx); + printf("loadMusicSlot slot=%s res=%u\n", slot.c_str(), resIdx); break; } - case 0x44: { + case 0x44: { // playMusic std::string slot = formatValue(); - std::string startMuted = formatValue(); - std::string fadeParam = formatValue(); - printf("PLAY_MUSIC slot=%s startMuted=%s fade=%s\n", slot.c_str(), startMuted.c_str(), fadeParam.c_str()); + std::string a = formatValue(); + std::string b = formatValue(); + printf("playMusic slot=%s %s %s\n", slot.c_str(), a.c_str(), b.c_str()); break; } - case 0x45: { + case 0x45: { // stopMusic std::string slot = formatValue(); - std::string immediate = formatValue(); - std::string fadeParam = formatValue(); - printf("STOP_MUSIC slot=%s immediate=%s fade=%s\n", slot.c_str(), immediate.c_str(), fadeParam.c_str()); + std::string a = formatValue(); + std::string b = formatValue(); + printf("stopMusic slot=%s %s %s\n", slot.c_str(), a.c_str(), b.c_str()); break; } - case 0x46: { + case 0x46: { // freeMusic std::string slot = formatValue(); - printf("FREE_MUSIC slot=%s\n", slot.c_str()); + printf("freeMusic slot=%s\n", slot.c_str()); break; } - case 0x47: { - printf("WAIT_MUSIC\n"); + case 0x47: { // waitForMusic + printf("waitForMusic\n"); break; } - case 0x48: { - std::string objId = formatObjectId(); - std::string target = formatSaveTarget(); - printf("GET_OBJECT_X obj=%s -> %s\n", objId.c_str(), target.c_str()); + case 0x48: { // getObjectX + std::string obj = formatValue(); + printf("getObjectX obj=%s\n", obj.c_str()); break; } - case 0x49: { - std::string objId = formatObjectId(); - std::string target = formatSaveTarget(); - printf("GET_OBJECT_Y obj=%s -> %s\n", objId.c_str(), target.c_str()); + case 0x49: { // getObjectY + std::string obj = formatValue(); + printf("getObjectY obj=%s\n", obj.c_str()); break; } - case 0x4A: { - std::string objId = formatObjectId(); - std::string target = formatSaveTarget(); - printf("GET_OBJECT_FIELD obj=%s -> %s\n", objId.c_str(), target.c_str()); + case 0x4A: { // getObjectField + std::string obj = formatValue(); + printf("getObjectField obj=%s\n", obj.c_str()); break; } - case 0x4B: { - std::string objId = formatObjectId(); - std::string target = formatSaveTarget(); - printf("GET_OBJECT_ORIENTATION obj=%s -> %s\n", objId.c_str(), target.c_str()); + case 0x4B: { // getObjectOrient + std::string obj = formatValue(); + printf("getObjectOrient obj=%s\n", obj.c_str()); break; } - case 0x4C: { - printf("CLEAR_INVENTORY\n"); + case 0x4C: { // clearActorItems + printf("clearActorItems\n"); break; } - case 0x4D: { - std::string src = formatValue(); - std::string dst = formatValue(); - printf("SET_AREA_REMAP %s -> %s\n", src.c_str(), dst.c_str()); + case 0x4D: { // setAreaRemap + std::string a = formatValue(); + std::string b = formatValue(); + printf("setAreaRemap %s -> %s\n", a.c_str(), b.c_str()); break; } - case 0x4E: { - printf("WAIT_ADLIB_READY\n"); + case 0x4E: { // waitForAdlib + printf("waitForAdlib\n"); break; } default: { - printf("UNKNOWN_OPCODE 0x%02X (len=%u)\n", opcode, length); + printf("??? opcode=0x%02x len=%u\n", opcode, length); break; } } - // Ensure we advance to the correct position regardless of parsing if (pos != endPos) { pos = endPos; } @@ -632,23 +574,20 @@ static void disassemble() { } static void printHelp(const char *bin) { - printf("MACS2 Script Disassembler\n\n"); + printf("MACS2 Script Decompiler\n\n"); printf("Usage: %s [scene_index]\n\n", bin); printf(" game_data_file - The main game data file\n"); - printf(" scene_index - Scene number to disassemble (1-based)\n"); - printf(" If omitted, disassembles all scenes\n\n"); - printf("The disassembled script will be written to stdout.\n"); + printf(" scene_index - Scene number to decompile (1-based)\n"); + printf(" If omitted, decompiles all scenes\n\n"); + printf("The decompiled script will be written to stdout.\n"); } static bool loadSceneScript(FILE *f, uint16_t sceneIndex) { - // Calculate offset: sceneIndex * 0xC + 0xC + 0x4 - 0x8 uint32_t offset = (uint32_t)sceneIndex * 0xC + 0xC + 0x4 - 0x8; fseek(f, offset, SEEK_SET); uint32_t sceneDataOffset; if (fread(&sceneDataOffset, 4, 1, f) != 1) return false; - // Little-endian conversion (assuming host is LE for simplicity) - // For portability we should do proper byte swapping but this matches the game's target fseek(f, sceneDataOffset + 0x80, SEEK_SET); @@ -690,36 +629,30 @@ int main(int argc, char **argv) { startScene = atoi(argv[2]); endScene = startScene; } else { - // Try all scenes from 1 to 512 startScene = 1; endScene = 512; } printf("; MACS2 Script Runtime Variables (type 0xFF, read-only)\n"); printf("; These are computed by the engine at read-time, not stored in script data.\n"); - printf("; $interacted_use (FF:01) Object ID interacted with via Use/UseInventory cursor\n"); - printf("; $interacted_look (FF:02) Object ID interacted with via Look cursor\n"); - printf("; $interacted_talk (FF:03) Object ID interacted with via Talk cursor\n"); - printf("; $char_area (FF:04) Area ID at protagonist's current position\n"); - printf("; $repeat_run_flag (FF:0B) 1 during repeat/object script pass, 0 otherwise\n"); - printf("; $chosen_dialogue_option (FF:0D) Index of last chosen dialogue option\n"); - printf("; $path_walkable_result (FF:23) 1 if last TEST_PATH_WALKABLE succeeded\n"); - printf("; $actor_x (FF:24) Protagonist X position\n"); - printf("; $actor_y (FF:25) Protagonist Y position\n"); - printf("; $is_scene_init (FF:26) 1 during scene initialization pass\n"); - printf("; $repeat_char_area (FF:27) Area at char position (only during repeat run)\n"); - printf("; $inventory_check_result (FF:28) 1 if last CHECK_INVENTORY matched\n"); - printf("; $anim_range_test_result (FF:29) 1 if last TEST_*_ANIM_FRAME matched\n"); - printf("; $inventory_combine_flag (FF:2A) 1 if inventory combine pending (no UI open)\n"); - printf("; $inventory_action_flag (FF:2B) 1 if inventory action pending (no UI open)\n"); - printf("; $interacted_panel_use (FF:2C) Object ID interacted with via PanelUse cursor\n"); - printf("; $current_scene (FF:2D) Current scene index\n"); - printf("; $last_scene (FF:2F) Previous scene index\n"); - printf("; $music_enabled (FF:30) 1 if music enabled and sound system active\n"); - printf("; $sound_enabled (FF:31) 1 if sound enabled and sound system active\n"); + printf("; interactedUse (FF:01) Object ID interacted with via Use/UseInventory cursor\n"); + printf("; interactedLook (FF:02) Object ID interacted with via Look cursor\n"); + printf("; interactedTalk (FF:03) Object ID interacted with via Talk cursor\n"); + printf("; areaAtActor (FF:04) Area ID at protagonist's current position\n"); + printf("; isRepeatRun (FF:0B) 1 during repeat/object script pass, 0 otherwise\n"); + printf("; dialogueResult (FF:0D) Index of last chosen dialogue option\n"); + printf("; pathWalkable (FF:23) 1 if last setPosition path test succeeded\n"); + printf("; actorX (FF:24) Protagonist X position\n"); + printf("; actorY (FF:25) Protagonist Y position\n"); + printf("; isSceneInit (FF:26) 1 during scene initialization pass\n"); + printf("; invCheck (FF:28) 1 if last setParent inventory check matched\n"); + printf("; invCombine (FF:2A) 1 if inventory combine pending (no UI open)\n"); + printf("; invAction (FF:2B) 1 if inventory action pending (no UI open)\n"); + printf("; curScene (FF:2D) Current scene index\n"); + printf("; prevScene (FF:2F) Previous scene index\n"); printf(";\n"); - printf("; Script variables: var[1]..var[2048] (read/write, all zeroed on scene load)\n"); - printf("; Object IDs: raw value - 0x400 = object index (1..512)\n"); + printf("; Script variables: var[N] (read/write, all zeroed on scene load)\n"); + printf("; Object IDs in moveObject/etc.: raw value - 0x400 = object index\n"); printf(";\n\n"); for (int scene = startScene; scene <= endScene; scene++) { From noreply at scummvm.org Mon Jun 1 07:44:05 2026 From: noreply at scummvm.org (neuromancer) Date: Mon, 1 Jun 2026 07:44:05 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> e44a371ebd858f7fb84d427b2c478bafefd1fa4e Message-ID: <20260601074405.D0ECB700591@ron.scummvm.net> 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: 892b4a95d5 SCUMM: RA1: clean-up of debug statements bc9e07470d SCUMM: RA2: clean-up of debug statements f046a35f78 SCUMM: RA2: removed expensive non-zero pixel counter used for debug a36e9516b1 SCUMM: RA1: use DEBUG_INSANE for debug statements 912e8b3bf4 SCUMM: RA: improve debug statements with class/function names e44a371ebd SCUMM: RA: removed some redundant/useless debug statement Commit: 892b4a95d5e9735999dd87ded09d3f83a2a51a54 https://github.com/scummvm/scummvm/commit/892b4a95d5e9735999dd87ded09d3f83a2a51a54 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T08:35:35+02:00 Commit Message: SCUMM: RA1: clean-up of debug statements Changed paths: engines/scumm/insane/rebel1/audio.cpp engines/scumm/insane/rebel1/iact.cpp engines/scumm/insane/rebel1/menu.cpp engines/scumm/insane/rebel1/render.cpp engines/scumm/smush/rebel/smush_player_ra1.cpp diff --git a/engines/scumm/insane/rebel1/audio.cpp b/engines/scumm/insane/rebel1/audio.cpp index bb807f9df2d..64cc5e095f2 100644 --- a/engines/scumm/insane/rebel1/audio.cpp +++ b/engines/scumm/insane/rebel1/audio.cpp @@ -75,14 +75,14 @@ void InsaneRebel1::loadSfx() { ScummFile *file = _vm->instantiateScummFile(); _vm->openFile(*file, kRA1SfxFiles[i]); if (!file->isOpen()) { - debug("InsaneRebel1::loadSfx: could not open %s", kRA1SfxFiles[i]); + debugC(DEBUG_INSANE, "InsaneRebel1::loadSfx: could not open %s", kRA1SfxFiles[i]); delete file; continue; } const uint32 fileSize = file->size(); if (fileSize < 16) { - debug("InsaneRebel1::loadSfx: %s too small (%u bytes)", kRA1SfxFiles[i], fileSize); + debugC(DEBUG_INSANE, "InsaneRebel1::loadSfx: %s too small (%u bytes)", kRA1SfxFiles[i], fileSize); file->close(); delete file; continue; @@ -90,7 +90,7 @@ void InsaneRebel1::loadSfx() { const uint32 tag = file->readUint32BE(); if (tag != MKTAG('S', 'A', 'U', 'D')) { - debug("InsaneRebel1::loadSfx: %s not a SAUD file (tag=0x%08x)", kRA1SfxFiles[i], tag); + debugC(DEBUG_INSANE, "InsaneRebel1::loadSfx: %s not a SAUD file (tag=0x%08x)", kRA1SfxFiles[i], tag); file->close(); delete file; continue; @@ -108,7 +108,7 @@ void InsaneRebel1::loadSfx() { file->read(pcm, pcmSize); _sfxData[i] = pcm; _sfxSize[i] = pcmSize; - debug("InsaneRebel1::loadSfx: loaded %s (%u bytes PCM)", kRA1SfxFiles[i], pcmSize); + debugC(DEBUG_INSANE, "InsaneRebel1::loadSfx: loaded %s (%u bytes PCM)", kRA1SfxFiles[i], pcmSize); } foundSdat = true; break; @@ -117,7 +117,7 @@ void InsaneRebel1::loadSfx() { } if (!foundSdat) - debug("InsaneRebel1::loadSfx: no SDAT chunk in %s", kRA1SfxFiles[i]); + debugC(DEBUG_INSANE, "InsaneRebel1::loadSfx: no SDAT chunk in %s", kRA1SfxFiles[i]); file->close(); delete file; diff --git a/engines/scumm/insane/rebel1/iact.cpp b/engines/scumm/insane/rebel1/iact.cpp index c89961c50a4..a6f94915ecb 100644 --- a/engines/scumm/insane/rebel1/iact.cpp +++ b/engines/scumm/insane/rebel1/iact.cpp @@ -781,11 +781,9 @@ void InsaneRebel1::updateFlightVariantCursor() { _flightAimY = CLIP(shipBaseY + ((liftTerm * kRA1Op09AimYScale[bucket]) >> 8), kRA1MinY, kRA1MaxY); - if (_currentLevel == 4) { - debug(1, "RA1 op09 cursor: frame=%d shipBase=(%d,%d) shipPos=(%d,%d) aim=(%d,%d) roll=%d lift=%d bucket=%d dir=%d persp=(%d,%d)", - _gameCounter, shipBaseX, shipBaseY, _shipPosX, _shipPosY, _flightAimX, _flightAimY, - _rollAccum, _liftSmooth, bucket, _shipDirIndex, _perspectiveX, _perspectiveY); - } + debugC(DEBUG_INSANE, "RA1 op09 cursor: frame=%d shipBase=(%d,%d) shipPos=(%d,%d) aim=(%d,%d) roll=%d lift=%d bucket=%d dir=%d persp=(%d,%d)", + _gameCounter, shipBaseX, shipBaseY, _shipPosX, _shipPosY, _flightAimX, _flightAimY, + _rollAccum, _liftSmooth, bucket, _shipDirIndex, _perspectiveX, _perspectiveY); } // preprocessMouseAxes ??? FUN_231BE (0x231BE) centered-axis output law, adapted to @@ -1132,7 +1130,7 @@ void InsaneRebel1::updateShipPhysics() { if (_shipBank.numSprites > 0) _shipDirIndex = CLIP((int16)(vComponent + hComponent), 0, _shipBank.numSprites - 1); - debug(1, "RA1 ship input: frame=%d source=%s controls=%s turbulence=%d usedJoystick=%d raw=(%d,%d) clipped=(%d,%d) storedAxis=(%d,%d) actionState(L,R,U,D)=(%d,%d,%d,%d) roll=%d lift=%d pos=(%d,%d) view=(%d,%d) dir=%d level=%d mode=%d opcode=0x%X", + debugC(DEBUG_INSANE, "RA1 ship input: frame=%d source=%s controls=%s turbulence=%d usedJoystick=%d raw=(%d,%d) clipped=(%d,%d) storedAxis=(%d,%d) actionState(L,R,U,D)=(%d,%d,%d,%d) roll=%d lift=%d pos=(%d,%d) view=(%d,%d) dir=%d level=%d mode=%d opcode=0x%X", _gameCounter, inputSourceName, _optEnhancedControls ? "enhanced" : "original", originalTurbulence, usedJoystick, rawInputX, rawInputY, inputX, inputY, @@ -1373,7 +1371,7 @@ void InsaneRebel1::updateTurretPhysics() { inputY /= 2; } - debug("RA1 turret input: source=%s controls=%s mouse=(%d,%d) actions(L,R,U,D)=(%d,%d,%d,%d) raw=(%d,%d) final=(%d,%d) level=%d mode=%d opcode=0x%X", + debugC(DEBUG_INSANE, "RA1 turret input: source=%s controls=%s mouse=(%d,%d) actions(L,R,U,D)=(%d,%d,%d,%d) raw=(%d,%d) final=(%d,%d) level=%d mode=%d opcode=0x%X", usedJoystick ? "joystick-actions" : "mouse-path", _optEnhancedControls ? "enhanced" : "original", _vm->_mouse.x, _vm->_mouse.y, @@ -1621,7 +1619,7 @@ void InsaneRebel1::updateGameOp0BPhysics() { } _inputAxisDeltaX = inputX; - debug("RA1 GAME 0x0B input: frame=%d source=%s controls=%s window=%d view=(%d,%d) health=%d prevFlags=0x%02x axis=(%d,%d) mouse=(%d,%d) actions(L,R,U,D)=(%d,%d,%d,%d) raw=(%d,%d) final=(%d,%d) level=%d opcode=0x%X", + debugC(DEBUG_INSANE, "RA1 GAME 0x0B input: frame=%d source=%s controls=%s window=%d view=(%d,%d) health=%d prevFlags=0x%02x axis=(%d,%d) mouse=(%d,%d) actions(L,R,U,D)=(%d,%d,%d,%d) raw=(%d,%d) final=(%d,%d) level=%d opcode=0x%X", _gameCounter, inputSourceName, _optEnhancedControls ? "enhanced" : "original", @@ -2260,8 +2258,8 @@ void InsaneRebel1::handleGameCounterOpcode(uint32 opcode, int32 subSize, Common: uint32 param2 = b.readUint32BE(); uint32 param3 = b.readUint32BE(); uint32 param4 = b.readUint32BE(); - if (opcode == 0x09 && _currentLevel == 4) { - debug(1, "RA1 GAME 0x09: counter=%d params=(%d,%d,%d) opcodeMask=0x%08x", + if (opcode == 0x09) { + debugC(DEBUG_INSANE, "RA1 GAME 0x09: counter=%d params=(%d,%d,%d) opcodeMask=0x%08x", _gameCounter, param2, param3, param4, _frameGameOpcodeMask); } else { debug(5, "RA1 GAME 0x%02x: counter=%d params=(%d,%d,%d)", @@ -2477,7 +2475,7 @@ void InsaneRebel1::checkTargetHit(int16 targetIdx, int16 left, int16 top, int16 _killCount++; applyFrameObjectHitState(targetIdx); - if (_currentLevel == 7) { + if (debugChannelSet(-1, DEBUG_INSANE)) { Common::String damagedState; Common::String hiddenState; for (int objectId = 20; objectId <= 43; objectId++) { @@ -2498,7 +2496,7 @@ void InsaneRebel1::checkTargetHit(int16 targetIdx, int16 left, int16 top, int16 damagedState += Common::String::format("%d,", objectId); } - debug(1, "RA1 L8 armor: hitObject=%d damaged=[%s] hidden=[%s]", + debugC(DEBUG_INSANE, "RA1 L8 armor: hitObject=%d damaged=[%s] hidden=[%s]", targetIdx + 1, damagedState.c_str(), hiddenState.c_str()); } diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp index 43f7c341a06..bcd73aff0de 100644 --- a/engines/scumm/insane/rebel1/menu.cpp +++ b/engines/scumm/insane/rebel1/menu.cpp @@ -509,7 +509,7 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { if (event.type == Common::EVENT_JOYAXIS_MOTION) { _lastJoystickAxisEventTime = _vm->_system->getMillis(); - debug(1, "RA1 input raw-joy-axis: axis=%d pos=%d menu=%d gameplay=%d storedAxis=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input raw-joy-axis: axis=%d pos=%d menu=%d gameplay=%d storedAxis=(%d,%d)", event.joystick.axis, event.joystick.position, _menuActive, _interactiveVideoActive && !_menuActive, _joystickAxisX, _joystickAxisY); @@ -532,12 +532,12 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { switch (event.customType) { case kScummBackendActionRebel1AxisUp: if (event.joystick.position == 0 && _joystickAxisY > 0) { - debug(1, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", getRebel1BackendAxisName(event.customType), _joystickAxisX, _joystickAxisY); return true; } _joystickAxisY = -axisPosition; - debug(1, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", + debugC(DEBUG_INSANE, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", getRebel1BackendAxisName(event.customType), axisPosition, event.joystick.position, oldAxisX, oldAxisY, _joystickAxisX, _joystickAxisY, _menuActive, _interactiveVideoActive && !_menuActive); @@ -546,12 +546,12 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { return true; case kScummBackendActionRebel1AxisDown: if (event.joystick.position == 0 && _joystickAxisY < 0) { - debug(1, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", getRebel1BackendAxisName(event.customType), _joystickAxisX, _joystickAxisY); return true; } _joystickAxisY = axisPosition; - debug(1, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", + debugC(DEBUG_INSANE, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", getRebel1BackendAxisName(event.customType), axisPosition, event.joystick.position, oldAxisX, oldAxisY, _joystickAxisX, _joystickAxisY, _menuActive, _interactiveVideoActive && !_menuActive); @@ -560,12 +560,12 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { return true; case kScummBackendActionRebel1AxisLeft: if (event.joystick.position == 0 && _joystickAxisX > 0) { - debug(1, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", getRebel1BackendAxisName(event.customType), _joystickAxisX, _joystickAxisY); return true; } _joystickAxisX = -axisPosition; - debug(1, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", + debugC(DEBUG_INSANE, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", getRebel1BackendAxisName(event.customType), axisPosition, event.joystick.position, oldAxisX, oldAxisY, _joystickAxisX, _joystickAxisY, _menuActive, _interactiveVideoActive && !_menuActive); @@ -574,12 +574,12 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { return true; case kScummBackendActionRebel1AxisRight: if (event.joystick.position == 0 && _joystickAxisX < 0) { - debug(1, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input mapped-axis ignored-reset: %s pos=0 current=(%d,%d)", getRebel1BackendAxisName(event.customType), _joystickAxisX, _joystickAxisY); return true; } _joystickAxisX = axisPosition; - debug(1, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", + debugC(DEBUG_INSANE, "RA1 input mapped-axis: %s pos=%d rawPos=%d old=(%d,%d) new=(%d,%d) menu=%d gameplay=%d", getRebel1BackendAxisName(event.customType), axisPosition, event.joystick.position, oldAxisX, oldAxisY, _joystickAxisX, _joystickAxisY, _menuActive, _interactiveVideoActive && !_menuActive); @@ -676,7 +676,7 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { return true; } - debug("Rebel1: ESC pressed during gameplay - opening ScummVM menu"); + debugC(DEBUG_INSANE, "Rebel1: ESC pressed during gameplay - opening ScummVM menu"); const bool wasPaused = _player->_paused; if (!wasPaused) _player->pause(); @@ -689,13 +689,13 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { if (_interactiveVideoActive && !_menuActive && event.kbd.keycode == Common::KEYCODE_s && event.kbd.hasFlags(Common::KBD_SHIFT)) { - debug("Rebel1: Shift+S pressed - skipping gameplay section"); + debugC(DEBUG_INSANE, "Rebel1: Shift+S pressed - skipping gameplay section"); _vm->_smushVideoShouldFinish = true; return true; } if (!_interactiveVideoActive && event.kbd.keycode == Common::KEYCODE_ESCAPE) { - debug("Rebel1: ESC pressed - skipping cinematic"); + debugC(DEBUG_INSANE, "Rebel1: ESC pressed - skipping cinematic"); _vm->_smushVideoShouldFinish = true; return true; } diff --git a/engines/scumm/insane/rebel1/render.cpp b/engines/scumm/insane/rebel1/render.cpp index c5397079d76..ae7f90294a6 100644 --- a/engines/scumm/insane/rebel1/render.cpp +++ b/engines/scumm/insane/rebel1/render.cpp @@ -1254,12 +1254,10 @@ void InsaneRebel1::renderLaserShots(byte *dst, int pitch, int width, int height) const int start1Y = shipBaseY + emit.y1; const int start2X = shipBaseX + emit.x2; const int start2Y = shipBaseY + emit.y2; - if (_currentLevel == 4) { - debug(1, "RA1 op09 shotRender: frame=%d timer=%d shipBase=(%d,%d) target=(%d,%d) emit1=(%d,%d) emit2=(%d,%d) dir=%d variant=%d mode=%d", - _gameCounter, timer, shipBaseX, shipBaseY, targetX, targetY, - start1X, start1Y, start2X, start2Y, _shipDirIndex, - _shotSlots[i].variant, _flyControlMode); - } + debugC(DEBUG_INSANE, "RA1 op09 shotRender: frame=%d timer=%d shipBase=(%d,%d) target=(%d,%d) emit1=(%d,%d) emit2=(%d,%d) dir=%d variant=%d mode=%d", + _gameCounter, timer, shipBaseX, shipBaseY, targetX, targetY, + start1X, start1Y, start2X, start2Y, _shipDirIndex, + _shotSlots[i].variant, _flyControlMode); renderAimedShotPair(dst, pitch, width, height, _laserBank, start1X, start1Y, start2X, start2Y, targetX, targetY, lerp); diff --git a/engines/scumm/smush/rebel/smush_player_ra1.cpp b/engines/scumm/smush/rebel/smush_player_ra1.cpp index d04d673155f..de6aad330bf 100644 --- a/engines/scumm/smush/rebel/smush_player_ra1.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra1.cpp @@ -260,13 +260,13 @@ bool SmushPlayerRebel1::handleGameFetch(int32 subSize, Common::SeekableReadStrea } } - debug("RA1 FTCH: frame=%d id=0x%08x pos=(%d,%d) using stored FOBJ codec=%d size=%dx%d", + debugC(DEBUG_SMUSH, "RA1 FTCH: frame=%d id=0x%08x pos=(%d,%d) using stored FOBJ codec=%d size=%dx%d", _frame, fetchId, left, top, storedCodec, _storedFobjWidth, _storedFobjHeight); decodeFrameObject(storedCodec, _storedFobjData, left, top, _storedFobjWidth, _storedFobjHeight, _storedFobjDataSize, storedParam, _storedFobjParm2); } else { - debug("RA1 FTCH: frame=%d id=0x%08x with no stored FOBJ data", _frame, fetchId); + debugC(DEBUG_SMUSH, "RA1 FTCH: frame=%d id=0x%08x with no stored FOBJ data", _frame, fetchId); } return true; @@ -283,7 +283,7 @@ void SmushPlayerRebel1::ra1HandleGost(int32 subSize, Common::SeekableReadStream const int32 ghostY = b.readSint32BE(); if (!_hasFrameFobjForGost || _lastFobjData == nullptr || _lastFobjDataSize <= 0) { - debug("RA1 GOST: frame=%d ignored type=0x%08x pos=(%d,%d) (no current-frame FOBJ cached)", + debugC(DEBUG_SMUSH, "RA1 GOST: frame=%d ignored type=0x%08x pos=(%d,%d) (no current-frame FOBJ cached)", _frame, ghostType, ghostX, ghostY); return; } @@ -300,12 +300,12 @@ void SmushPlayerRebel1::ra1HandleGost(int32 subSize, Common::SeekableReadStream priorityFlags = 0x6000; break; default: - debug("RA1 GOST: frame=%d ignored unknown type=0x%08x pos=(%d,%d)", + debugC(DEBUG_SMUSH, "RA1 GOST: frame=%d ignored unknown type=0x%08x pos=(%d,%d)", _frame, ghostType, ghostX, ghostY); return; } - debug("RA1 GOST: frame=%d type=0x%08x flags=0x%04x pos=(%d,%d) size=%dx%d codec=%d", + debugC(DEBUG_SMUSH, "RA1 GOST: frame=%d type=0x%08x flags=0x%04x pos=(%d,%d) size=%dx%d codec=%d", _frame, ghostType, priorityFlags, ghostX, ghostY, _lastFobjWidth, _lastFobjHeight, _lastFobjCodec); @@ -593,7 +593,7 @@ bool SmushPlayerRebel1::handleGameStoreFrame() { } void SmushPlayerRebel1::handleGameFrameObjectPre(int codec, int left, int top, int width, int height, int dataSize) { - debug("RA1 FOBJ: frame=%d codec=%d pos=(%d,%d) size=%dx%d dataSize=%d storeFrame=%d", + debugC(DEBUG_SMUSH, "RA1 FOBJ: frame=%d codec=%d pos=(%d,%d) size=%dx%d dataSize=%d storeFrame=%d", _frame, codec, left, top, width, height, dataSize, _storeFrame); } Commit: bc9e07470d7f2a02e390caf1530cde95cc700122 https://github.com/scummvm/scummvm/commit/bc9e07470d7f2a02e390caf1530cde95cc700122 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T08:39:25+02:00 Commit Message: SCUMM: RA2: clean-up of debug statements Changed paths: engines/scumm/smush/rebel/smush_player_ra2.cpp diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp index fe8165bde42..0d6a8b0e663 100644 --- a/engines/scumm/smush/rebel/smush_player_ra2.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp @@ -122,12 +122,14 @@ void SmushPlayerRebel2::initGameVideoState() { memset(_dst, 0, vs->w * vs->h); } else { // Gameplay mode (flags 0x28) - do nothing, preserve existing screen content - int nonZero = 0; - for (int i = 0; i < vs->w * vs->h; i++) { - if (_dst[i] != 0) nonZero++; + if (debugChannelSet(-1, DEBUG_SMUSH)) { + int nonZero = 0; + for (int i = 0; i < vs->w * vs->h; i++) { + if (_dst[i] != 0) nonZero++; + } + debugC(DEBUG_SMUSH, "SmushPlayer::init: Preserving screen for gameplay video (%dx%d, %d%% non-zero)", + vs->w, vs->h, (nonZero * 100) / (vs->w * vs->h)); } - debug("SmushPlayer::init: Preserving screen for gameplay video (%dx%d, %d%% non-zero)", - vs->w, vs->h, (nonZero * 100) / (vs->w * vs->h)); } } } @@ -159,7 +161,7 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea int16 ftchX = b.readSint16LE(); int16 ftchY = b.readSint16LE(); - debug("SmushPlayer::handleFetch: frame=%d unknown=%d x=%d y=%d", + debugC(DEBUG_SMUSH, "SmushPlayer::handleFetch: frame=%d unknown=%d x=%d y=%d", _frame, ftchUnknown, ftchX, ftchY); // For Handler 25, skip FTCH because the frame buffer only contains the @@ -169,14 +171,14 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea InsaneRebel2 *rebel2 = static_cast(_insane); int handler = rebel2->getHandler(); if (handler == 25) { - debug("SmushPlayer::handleFetch: Skipping FTCH for Handler 25 - preserving overlays"); + debugC(DEBUG_SMUSH, "SmushPlayer::handleFetch: Skipping FTCH for Handler 25 - preserving overlays"); return true; } } // Re-decode stored FOBJ data with current offsets (matching original FUN_004246d0). if (_storedFobjData != nullptr) { - debug("SmushPlayer FTCH: Re-decoding stored FOBJ codec=%d pos=(%d,%d) size=%dx%d dataSize=%d", + debugC(DEBUG_SMUSH, "SmushPlayer FTCH: Re-decoding stored FOBJ codec=%d pos=(%d,%d) size=%dx%d dataSize=%d", _storedFobjCodec, _storedFobjLeft, _storedFobjTop, _storedFobjWidth, _storedFobjHeight, _storedFobjDataSize); decodeFrameObject(_storedFobjCodec, _storedFobjData, @@ -184,7 +186,7 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea _storedFobjWidth, _storedFobjHeight, _storedFobjDataSize); } else { - debug("SmushPlayer FTCH: No stored FOBJ data! (frame=%d)", _frame); + debugC(DEBUG_SMUSH, "SmushPlayer FTCH: No stored FOBJ data! (frame=%d)", _frame); } return true; @@ -399,7 +401,7 @@ bool SmushPlayerRebel2::handleGameAnimHeader(byte *headerContent) { if (width == 0 && height == 0) { _width = _vm->_screenWidth; _height = _vm->_screenHeight; - debug("SmushPlayer::handleAnimHeader: RA2 AHDR has 0x0 dims - using screen size %dx%d", _width, _height); + debugC(DEBUG_SMUSH, "SmushPlayer::handleAnimHeader: RA2 AHDR has 0x0 dims - using screen size %dx%d", _width, _height); } else { _width = width; _height = height; @@ -497,7 +499,7 @@ void SmushPlayerRebel2::ra2HandleTextResource(const char *str, int fontId, int c ensureMultiFont(); _multiFont->setDefaultFont(fontId); - debug("SmushPlayer::handleTextResource: RA2 TRES frame=%d fontId=%d color=%d flags=0x%x flg=%d pos=(%d,%d) clip=(%d,%d,%d,%d) str=\"%.40s\"", + debugC(DEBUG_SMUSH, "SmushPlayer::handleTextResource: RA2 TRES frame=%d fontId=%d color=%d flags=0x%x flg=%d pos=(%d,%d) clip=(%d,%d,%d,%d) str=\"%.40s\"", _frame, fontId, color, (int)flg, (int)flg, pos_x, pos_y, left, top, width, height, str); if (flg & kStyleWordWrap) { @@ -528,24 +530,24 @@ void SmushPlayerRebel2::ra2SelectFrameBuffer(int width, int height) { _height = height; // Zero-fill the new buffer to avoid garbage in areas not written by FOBJ codec memset(_specialBuffer, 0, bufSize); - debug("SmushPlayer: Allocated new _specialBuffer %dx%d (%d bytes)", width, height, bufSize); + debugC(DEBUG_SMUSH, "SmushPlayer: Allocated new _specialBuffer %dx%d (%d bytes)", width, height, bufSize); } } if (bufSize > _vm->_screenWidth * _vm->_screenHeight && _specialBuffer != nullptr && _specialBufferSize >= bufSize) { _dst = _specialBuffer; - debug("SmushPlayer: Using _specialBuffer for oversized FOBJ %dx%d", width, height); + debugC(DEBUG_SMUSH, "SmushPlayer: Using _specialBuffer for oversized FOBJ %dx%d", width, height); } else { if (_specialBuffer == nullptr) { VirtScreen *vs = &_vm->_virtscr[kMainVirtScreen]; _dst = vs->getPixels(0, 0); - debug("SmushPlayer: Reset _dst to virtual screen for FOBJ %dx%d at (%d,%d) _dst=%p", + debugC(DEBUG_SMUSH, "SmushPlayer: Reset _dst to virtual screen for FOBJ %dx%d at (%d,%d) _dst=%p", width, height, 0, 0, (void*)_dst); } else { // Large frame was in this video, use _specialBuffer for compositing _dst = _specialBuffer; - debug("SmushPlayer: Using _specialBuffer for small FOBJ %dx%d (compositing with large frame)", + debugC(DEBUG_SMUSH, "SmushPlayer: Using _specialBuffer for small FOBJ %dx%d (compositing with large frame)", width, height); } } @@ -612,7 +614,7 @@ void SmushPlayerRebel2::ra2HandleGost(int32 subSize, Common::SeekableReadStream int16 ghostY = b.readSint16LE(); if (!_hasFrameFobjForGost || _lastFobjData == nullptr || _lastFobjDataSize <= 0) { - debug("SmushPlayer GOST: frame=%d ignored (no current-frame FOBJ cached)", _frame); + debugC(DEBUG_SMUSH, "SmushPlayer GOST: frame=%d ignored (no current-frame FOBJ cached)", _frame); return; } @@ -630,7 +632,7 @@ void SmushPlayerRebel2::ra2HandleGost(int32 subSize, Common::SeekableReadStream int left = _lastFobjLeft + ghostX; int top = _lastFobjTop + ghostY; - debug("SmushPlayer GOST: frame=%d type=%d flags=0x%04x gostPos=(%d,%d) basePos=(%d,%d) finalPos=(%d,%d) size=%dx%d codec=%d", + debugC(DEBUG_SMUSH, "SmushPlayer GOST: frame=%d type=%d flags=0x%04x gostPos=(%d,%d) basePos=(%d,%d) finalPos=(%d,%d) size=%dx%d codec=%d", _frame, ghostType, priorityFlags, ghostX, ghostY, _lastFobjLeft, _lastFobjTop, left, top, _lastFobjWidth, _lastFobjHeight, _lastFobjCodec); @@ -698,7 +700,7 @@ bool SmushPlayerRebel2::handleGameStoreFrame() { } void SmushPlayerRebel2::handleGameFrameObjectPre(int codec, int left, int top, int width, int height, int dataSize) { - debug("SmushPlayer FOBJ: frame=%d codec=%d pos=(%d,%d) size=%dx%d dataSize=%d storeFrame=%d _width=%d _height=%d", + debugC(DEBUG_SMUSH, "SmushPlayer FOBJ: frame=%d codec=%d pos=(%d,%d) size=%dx%d dataSize=%d storeFrame=%d _width=%d _height=%d", _frame, codec, left, top, width, height, dataSize, _storeFrame, _width, _height); } Commit: f046a35f7809212b8b895e7b38e5af505f82bb96 https://github.com/scummvm/scummvm/commit/f046a35f7809212b8b895e7b38e5af505f82bb96 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T08:41:48+02:00 Commit Message: SCUMM: RA2: removed expensive non-zero pixel counter used for debug Changed paths: engines/scumm/smush/rebel/smush_player_ra2.cpp diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp index 0d6a8b0e663..53afda31784 100644 --- a/engines/scumm/smush/rebel/smush_player_ra2.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp @@ -120,17 +120,8 @@ void SmushPlayerRebel2::initGameVideoState() { if ((_curVideoFlags & 0x08) == 0) { // Cinematic mode (flags 0x20) - clear buffer for fresh video memset(_dst, 0, vs->w * vs->h); - } else { - // Gameplay mode (flags 0x28) - do nothing, preserve existing screen content - if (debugChannelSet(-1, DEBUG_SMUSH)) { - int nonZero = 0; - for (int i = 0; i < vs->w * vs->h; i++) { - if (_dst[i] != 0) nonZero++; - } - debugC(DEBUG_SMUSH, "SmushPlayer::init: Preserving screen for gameplay video (%dx%d, %d%% non-zero)", - vs->w, vs->h, (nonZero * 100) / (vs->w * vs->h)); - } } + // Gameplay mode (flags 0x28): no-op, the existing screen content is preserved. } } Commit: a36e9516b199c7249c24697b2ba1e9871096f1f8 https://github.com/scummvm/scummvm/commit/a36e9516b199c7249c24697b2ba1e9871096f1f8 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T09:02:32+02:00 Commit Message: SCUMM: RA1: use DEBUG_INSANE for debug statements Changed paths: engines/scumm/insane/rebel1/iact.cpp engines/scumm/insane/rebel1/levels.cpp engines/scumm/insane/rebel1/menu.cpp engines/scumm/insane/rebel1/rebel.cpp engines/scumm/insane/rebel1/render.cpp engines/scumm/insane/rebel1/runlevels.cpp engines/scumm/insane/rebel1/saveload.cpp diff --git a/engines/scumm/insane/rebel1/iact.cpp b/engines/scumm/insane/rebel1/iact.cpp index a6f94915ecb..68b0e2afac4 100644 --- a/engines/scumm/insane/rebel1/iact.cpp +++ b/engines/scumm/insane/rebel1/iact.cpp @@ -639,7 +639,7 @@ void InsaneRebel1::checkDynamicLevelBranch(int32 curFrame) { _vm->_smushVideoShouldFinish = true; const int32 resumeFrame = (_currentLevel == 6 && _pendingRouteStartFrame < 0) ? 0 : _pendingRouteStartFrame; - debug(1, "RA1 L%d cutover: route=%d -> %d at %s=%u (resumeFrame=%d)", + debugC(DEBUG_INSANE, "RA1 L%d cutover: route=%d -> %d at %s=%u (resumeFrame=%d)", _currentLevel + 1, _levelRouteIndex, _pendingRouteIndex, _currentLevel == 6 ? "localFrame" : "frame", (unsigned)routeFrame, (int)resumeFrame); @@ -681,7 +681,7 @@ void InsaneRebel1::checkDynamicLevelBranch(int32 curFrame) { : (branchX < kLevel7BranchThreshold[nextRoute]); if (!takeBranch) { if (routeFrame == decisionFrame) - debug(1, "RA1 L7 branch miss: route=%d candidate=%d localFrame=%u gameFrame=%d shipX=%d dir=%d threshold=%d", + debugC(DEBUG_INSANE, "RA1 L7 branch miss: route=%d candidate=%d localFrame=%u gameFrame=%d shipX=%d dir=%d threshold=%d", route, nextRoute, (unsigned)routeFrame, (int)_gameCounter, branchX, kLevel7BranchDir[nextRoute], kLevel7BranchThreshold[nextRoute]); continue; @@ -692,7 +692,7 @@ void InsaneRebel1::checkDynamicLevelBranch(int32 curFrame) { _pendingRouteStartFrame = (int32)routeFrame; _pendingRouteVideoStartFrame = 1 + (_pendingRouteCutoverFrame - _pendingRouteStartFrame); _level7WarningFrames = 0; - debug(1, "RA1 L7 branch: route=%d -> %d at localFrame=%u gameFrame=%d decisionFrame=%u shipX=%d resumeSourceFrame=%d cutoverFrame=%d destFrame=%d", + debugC(DEBUG_INSANE, "RA1 L7 branch: route=%d -> %d at localFrame=%u gameFrame=%d decisionFrame=%u shipX=%d resumeSourceFrame=%d cutoverFrame=%d destFrame=%d", route, nextRoute, (unsigned)routeFrame, (int)_gameCounter, (unsigned)decisionFrame, branchX, (int)_pendingRouteStartFrame, (int)_pendingRouteCutoverFrame, (int)_pendingRouteVideoStartFrame); @@ -1213,9 +1213,9 @@ void InsaneRebel1::updateShipPhysics() { if (_shipPosX > kRA1CenterX) { _rightPathSelected = true; _vm->_smushVideoShouldFinish = true; - debug(1, "RA1: Right path selected (counter=%d, shipX=%d)", _gameCounter, _shipPosX); + debugC(DEBUG_INSANE, "RA1: Right path selected (counter=%d, shipX=%d)", _gameCounter, _shipPosX); } else { - debug(1, "RA1: Left path retained (counter=%d, shipX=%d)", _gameCounter, _shipPosX); + debugC(DEBUG_INSANE, "RA1: Left path retained (counter=%d, shipX=%d)", _gameCounter, _shipPosX); } _pathBranchEnabled = false; } @@ -1552,13 +1552,13 @@ void InsaneRebel1::updateGameOp0BPhysics() { // FUN_1CDA7 dispatches g_sfxDamageHit, initialized from SYS/BOOM.SAD. playSfx(kSfxBoom, 127, 0); if (_currentLevel == 1) { - debug(1, "RA1 L2 player hit: frame=%u view=(%d,%d) latch=%u asteroid=%d flags=0x%02x health=%d->%d", + debugC(DEBUG_INSANE, "RA1 L2 player hit: frame=%u view=(%d,%d) latch=%u asteroid=%d flags=0x%02x health=%d->%d", (unsigned)(uint16)_gameCounter, _perspectiveX, _perspectiveY, (unsigned)_gameLatch5D, level2AsteroidHit ? 1 : 0, appliedDamageFlags, oldHealth, _health); } if (level8WalkerPlayerHit) { - debug(1, "RA1 L8 player hit by walker: route=%d frame=%u view=(%d,%d) flags=0x%02x health=%d->%d", + debugC(DEBUG_INSANE, "RA1 L8 player hit by walker: route=%d frame=%u view=(%d,%d) flags=0x%02x health=%d->%d", CLIP(_levelRouteIndex, 0, 2), (unsigned)(uint16)_gameCounter, _perspectiveX, _perspectiveY, appliedDamageFlags, oldHealth, _health); } @@ -1691,7 +1691,7 @@ void InsaneRebel1::updateGameOp0BPhysics() { const bool target215Destroyed = isFrameObjectPrimarySet(215); if (!target211Destroyed || !target213Destroyed || !target215Destroyed) { _levelGameplayPhase = 1; - debug(1, "RA1 L12 retry armed: frame=0x%04x targets=(%d,%d,%d)", + debugC(DEBUG_INSANE, "RA1 L12 retry armed: frame=0x%04x targets=(%d,%d,%d)", _frameCounter, target211Destroyed ? 1 : 0, target213Destroyed ? 1 : 0, @@ -2135,7 +2135,7 @@ void InsaneRebel1::handleGameOpcode0DCorridor(int32 subSize, Common::SeekableRea } } if ((_damageFlags & 0x0F) != oldDirectionalFlags) { - debug(1, "RA1 0x0D hit: ship=(%d,%d) corridor=[%d,%d]-[%d,%d] flags=0x%02x zoneSuppressed=%d", + debugC(DEBUG_INSANE, "RA1 0x0D hit: ship=(%d,%d) corridor=[%d,%d]-[%d,%d] flags=0x%02x zoneSuppressed=%d", collisionShipX, collisionShipY, _corridorLeftX, _corridorTopY, _corridorRightX, _corridorBottomY, _damageFlags, suppressDirectionalDamage ? 1 : 0); @@ -2177,7 +2177,7 @@ void InsaneRebel1::handleGameOpcode0EZone(int32 subSize, Common::SeekableReadStr collisionShipX > zoneLeft && collisionShipX < zoneRight && collisionShipY > zoneTop && collisionShipY < zoneBottom) { _damageFlags |= 0x10; - debug(1, "RA1 0x0E hit: ship=(%d,%d) zone=[%d,%d]-[%d,%d] raw=[%d,%d]+(%d,%d) cam=(%d,%d) flags=0x%02x", + debugC(DEBUG_INSANE, "RA1 0x0E hit: ship=(%d,%d) zone=[%d,%d]-[%d,%d] raw=[%d,%d]+(%d,%d) cam=(%d,%d) flags=0x%02x", collisionShipX, collisionShipY, zoneLeft, zoneTop, zoneRight, zoneBottom, rawZoneLeft, rawZoneTop, zoneWidth, zoneHeight, _perspectiveX, _perspectiveY, _damageFlags); @@ -2203,7 +2203,7 @@ void InsaneRebel1::handleGameOpcode0BFirstPerson(int32 subSize, Common::Seekable if (_interactiveVideoActive && maxFrames > 0 && _gameCounter >= (int32)maxFrames - 1) { _vm->_smushVideoShouldFinish = true; - debug(1, "RA1: finishing 0x0B interactive video at counter=%d/%u", _gameCounter, maxFrames); + debugC(DEBUG_INSANE, "RA1: finishing 0x0B interactive video at counter=%d/%u", _gameCounter, maxFrames); } } debug(7, "RA1 GAME 0x0B: counter=%d", _gameCounter); @@ -2397,7 +2397,7 @@ void InsaneRebel1::processShot() { playSfx(torpedoMode ? kSfxAlert : kSfxLaserShot, 127, 0); if (effectiveOpcode == 0x09 || _currentLevel == 4) { - debug(1, "RA1 shot: opcode=0x%02x frame=%d slot=%d cursor=(%d,%d) origin=(%d,%d) dir=%d mode=%d", + debugC(DEBUG_INSANE, "RA1 shot: opcode=0x%02x frame=%d slot=%d cursor=(%d,%d) origin=(%d,%d) dir=%d mode=%d", effectiveOpcode, _gameCounter, slot, cursorX, cursorY, originX, originY, _shipDirIndex, _flyControlMode); } else { diff --git a/engines/scumm/insane/rebel1/levels.cpp b/engines/scumm/insane/rebel1/levels.cpp index f32b598aee8..5e050f17d8c 100644 --- a/engines/scumm/insane/rebel1/levels.cpp +++ b/engines/scumm/insane/rebel1/levels.cpp @@ -156,7 +156,7 @@ bool InsaneRebel1::loadRA1Nut(const char *filename, RA1SpriteBank &bank) { free(fobjOffsets); free(data); - debug(1, "InsaneRebel1::loadRA1Nut('%s'): expected=%d found=%d decoded=%d bytes", + debugC(DEBUG_INSANE, "InsaneRebel1::loadRA1Nut('%s'): expected=%d found=%d decoded=%d bytes", filename, expectedSprites, foundSprites, decodedSize); return true; } @@ -169,14 +169,14 @@ void InsaneRebel1::loadLevelSprites(int level) { if (!loadRA1Nut(legacyBankFile.c_str(), _shipBank)) { Common::String pilotFile = Common::String::format("LVL%d/L%dPILOT.NUT", level, level); if (!loadRA1Nut(pilotFile.c_str(), _shipBank)) - debug(1, "InsaneRebel1: No BANK1/BANK/PILOT for level %d", level); + debugC(DEBUG_INSANE, "InsaneRebel1: No BANK1/BANK/PILOT for level %d", level); } } // Secondary ship bank used by some level-specific handlers (e.g. LVL1 mode-2). Common::String bankFileAlt = Common::String::format("LVL%d/L%dBANK2.NUT", level, level); if (!loadRA1Nut(bankFileAlt.c_str(), _shipBankAlt)) { - debug(1, "InsaneRebel1: No BANK2 for level %d", level); + debugC(DEBUG_INSANE, "InsaneRebel1: No BANK2 for level %d", level); } loadRA1Nut("SYS/DISPLAY.NUT", _displayBank); diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp index bcd73aff0de..42c09914d77 100644 --- a/engines/scumm/insane/rebel1/menu.cpp +++ b/engines/scumm/insane/rebel1/menu.cpp @@ -516,7 +516,7 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { } if (event.type == Common::EVENT_JOYBUTTON_DOWN || event.type == Common::EVENT_JOYBUTTON_UP) { - debug(1, "RA1 input raw-joy-button: button=%d pressed=%d menu=%d gameplay=%d storedAxis=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input raw-joy-button: button=%d pressed=%d menu=%d gameplay=%d storedAxis=(%d,%d)", event.joystick.button, event.type == Common::EVENT_JOYBUTTON_DOWN, _menuActive, _interactiveVideoActive && !_menuActive, _joystickAxisX, _joystickAxisY); @@ -595,7 +595,7 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) { const bool pressed = (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START); - debug(1, "RA1 input mapped-action: action=%s custom=%u pressed=%d menu=%d gameplay=%d storedAxis=(%d,%d) actionState(L,R,U,D)=(%d,%d,%d,%d)", + debugC(DEBUG_INSANE, "RA1 input mapped-action: action=%s custom=%u pressed=%d menu=%d gameplay=%d storedAxis=(%d,%d) actionState(L,R,U,D)=(%d,%d,%d,%d)", getRebel1ActionName(event.customType), event.customType, pressed, _menuActive, _interactiveVideoActive && !_menuActive, _joystickAxisX, _joystickAxisY, @@ -655,10 +655,10 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { if (event.type == Common::EVENT_MAINMENU && _interactiveVideoActive && !_menuActive) { const uint32 now = _vm->_system->getMillis(); const uint32 elapsedSinceAxis = _lastJoystickAxisEventTime ? now - _lastJoystickAxisEventTime : 0xffffffffu; - debug(1, "RA1 input mainmenu-event: gameplay=1 elapsedSinceAxis=%u storedAxis=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input mainmenu-event: gameplay=1 elapsedSinceAxis=%u storedAxis=(%d,%d)", elapsedSinceAxis, _joystickAxisX, _joystickAxisY); if (elapsedSinceAxis <= kRA1JoystickAxisEscGuardMs) { - debug(1, "RA1 input ignored mainmenu event after recent joystick axis movement (%u ms)", elapsedSinceAxis); + debugC(DEBUG_INSANE, "RA1 input ignored mainmenu event after recent joystick axis movement (%u ms)", elapsedSinceAxis); return true; } } @@ -668,11 +668,11 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { event.kbd.keycode == Common::KEYCODE_ESCAPE) { const uint32 now = _vm->_system->getMillis(); const uint32 elapsedSinceAxis = _lastJoystickAxisEventTime ? now - _lastJoystickAxisEventTime : 0xffffffffu; - debug(1, "RA1 input keydown-escape: gameplay=1 ascii=%d flags=0x%x repeat=%d elapsedSinceAxis=%u storedAxis=(%d,%d)", + debugC(DEBUG_INSANE, "RA1 input keydown-escape: gameplay=1 ascii=%d flags=0x%x repeat=%d elapsedSinceAxis=%u storedAxis=(%d,%d)", event.kbd.ascii, event.kbd.flags, event.kbdRepeat, elapsedSinceAxis, _joystickAxisX, _joystickAxisY); if (elapsedSinceAxis <= kRA1JoystickAxisEscGuardMs) { - debug(1, "RA1 input ignored ESC after recent joystick axis movement (%u ms)", elapsedSinceAxis); + debugC(DEBUG_INSANE, "RA1 input ignored ESC after recent joystick axis movement (%u ms)", elapsedSinceAxis); return true; } @@ -929,7 +929,7 @@ bool InsaneRebel1::runTextEntryMenuLoop() { } int InsaneRebel1::runMainMenu() { - debug(1, "InsaneRebel1: Main menu"); + debugC(DEBUG_INSANE, "InsaneRebel1: Main menu"); _menuSelection = 0; while (!shouldAbortGameFlow()) { @@ -962,13 +962,13 @@ int InsaneRebel1::runPasscodeEntryDialog() { _maxChapterUnlocked = MAX(_maxChapterUnlocked, i); if (targetLevel <= kRA1NumLevels) _startLevel = targetLevel; - debug(1, "RA1 passcode accepted: slot=%d password=%s difficulty=%d target=%d", + debugC(DEBUG_INSANE, "RA1 passcode accepted: slot=%d password=%s difficulty=%d target=%d", i, password, _difficulty, targetLevel); return targetLevel; } } - debug(1, "RA1 passcode rejected: '%s'", _textEntryBuffer); + debugC(DEBUG_INSANE, "RA1 passcode rejected: '%s'", _textEntryBuffer); return 0; } @@ -995,7 +995,7 @@ bool InsaneRebel1::runHighScoreNameEntry() { Common::strlcpy(_highScores[slot].name, storedName.c_str(), sizeof(_highScores[slot].name)); _highScores[slot].difficulty = _difficulty; _highScoreEntryIndex = -1; - debug(1, "RA1 high score inserted: slot=%d name=%s score=%ld difficulty=%d", + debugC(DEBUG_INSANE, "RA1 high score inserted: slot=%d name=%s score=%ld difficulty=%d", slot, _highScores[slot].name, (long)_highScores[slot].score, _highScores[slot].difficulty); return true; } diff --git a/engines/scumm/insane/rebel1/rebel.cpp b/engines/scumm/insane/rebel1/rebel.cpp index 875a305541e..6ebd1efd8e8 100644 --- a/engines/scumm/insane/rebel1/rebel.cpp +++ b/engines/scumm/insane/rebel1/rebel.cpp @@ -192,7 +192,7 @@ void InsaneRebel1::loadTuningForLevel(int level) { _protectedTargetA = 0; _protectedTargetB = 0; - debug(1, "RA1: Loaded tuning level=%d diff=%d: roll=%d lift=%d slide=%d drift=%d snap=%d " + debugC(DEBUG_INSANE, "RA1: Loaded tuning level=%d diff=%d: roll=%d lift=%d slide=%d drift=%d snap=%d " "miss=%d wham=%d shot=%d kill=%d time=%d levelPts=%d bonus=%d flags=0x%x", level, d, _tuning.roll, _tuning.lift, _tuning.slide, _tuning.drift, _tuning.snap, _tuning.miss, _tuning.wham, _tuning.shot, _tuning.kill, @@ -404,17 +404,17 @@ InsaneRebel1::InsaneRebel1(ScummEngine_v7 *scumm) : Insane(), _vm(scumm) { resetFrameObjectState(); if (loadRA1Nut("SYS/TALKFONT.NUT", _hudFontBank)) { - debug(1, "InsaneRebel1: HUD/menu glyph font loaded from SYS/TALKFONT.NUT (%d chars)", _hudFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1: HUD/menu glyph font loaded from SYS/TALKFONT.NUT (%d chars)", _hudFontBank.numSprites); } else if (loadRA1Nut("SYS/TECHFONT.NUT", _hudFontBank)) { - debug(1, "InsaneRebel1: HUD/menu glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _hudFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1: HUD/menu glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _hudFontBank.numSprites); } else { warning("InsaneRebel1: failed to load RA1 HUD font bank (TECHFONT/TALKFONT)"); } if (loadRA1Nut("SYS/TITLFONT.NUT", _titleFontBank)) { - debug(1, "InsaneRebel1: title glyph font loaded from SYS/TITLFONT.NUT (%d chars)", _titleFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1: title glyph font loaded from SYS/TITLFONT.NUT (%d chars)", _titleFontBank.numSprites); } else if (loadRA1Nut("SYS/TALKFONT.NUT", _titleFontBank)) { - debug(1, "InsaneRebel1: title glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _titleFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1: title glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _titleFontBank.numSprites); } else { warning("InsaneRebel1: failed to load title font bank (TITLFONT/TALKFONT)"); } @@ -422,9 +422,9 @@ InsaneRebel1::InsaneRebel1(ScummEngine_v7 *scumm) : Insane(), _vm(scumm) { // FUN_1CB22 uses "<<" layer markers that resolve to TECHFONT in the original. // Keep a dedicated TECH font bank for targeting markers/lock indicators. if (loadRA1Nut("SYS/TECHFONT.NUT", _techFontBank)) { - debug(1, "InsaneRebel1: targeting glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _techFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1: targeting glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _techFontBank.numSprites); } else if (loadRA1Nut("SYS/TALKFONT.NUT", _techFontBank)) { - debug(1, "InsaneRebel1: targeting glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _techFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1: targeting glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _techFontBank.numSprites); } else { warning("InsaneRebel1: failed to load targeting font bank (TECHFONT/TALKFONT)"); } diff --git a/engines/scumm/insane/rebel1/render.cpp b/engines/scumm/insane/rebel1/render.cpp index ae7f90294a6..110c3911e43 100644 --- a/engines/scumm/insane/rebel1/render.cpp +++ b/engines/scumm/insane/rebel1/render.cpp @@ -1908,7 +1908,7 @@ void InsaneRebel1::updateLevel8WalkerState() { _pendingRouteIndex = newRoute; _pendingRouteCutoverFrame = _gameCounter + 7; _pendingRouteStartFrame = _pendingRouteCutoverFrame; - debug(1, "RA1 L8 branch: route=%d -> %d at frame=%u shipX=%d resumeTimelineFrame=%d cutoverFrame=%d", + debugC(DEBUG_INSANE, "RA1 L8 branch: route=%d -> %d at frame=%u shipX=%d resumeTimelineFrame=%d cutoverFrame=%d", route, newRoute, (unsigned)_gameCounter, _shipPosX, (int)_pendingRouteStartFrame, (int)_pendingRouteCutoverFrame); } diff --git a/engines/scumm/insane/rebel1/runlevels.cpp b/engines/scumm/insane/rebel1/runlevels.cpp index 8dffb1c5a27..62c35eaf205 100644 --- a/engines/scumm/insane/rebel1/runlevels.cpp +++ b/engines/scumm/insane/rebel1/runlevels.cpp @@ -147,7 +147,7 @@ static int calculateThresholdBonus(int kills, int perfectThreshold, int perKillT // Reuses RA2's pattern: reset handler, set cinematic flags, play video. // startFrame > 0: fast-forward (decode without display/audio) to that frame. void InsaneRebel1::playCinematic(const char *filename, int32 startFrame) { - debug(1, "InsaneRebel1::playCinematic('%s', startFrame=%d)", filename, startFrame); + debugC(DEBUG_INSANE, "InsaneRebel1::playCinematic('%s', startFrame=%d)", filename, startFrame); if (shouldAbortGameFlow()) return; @@ -315,7 +315,7 @@ void InsaneRebel1::clearVideoBuffer() { // 1. O1LOGO.ANM ??? LucasArts logo // 2. O1OPEN.ANM ??? Star Wars opening crawl void InsaneRebel1::playIntroSequence() { - debug(1, "InsaneRebel1: Playing intro sequence"); + debugC(DEBUG_INSANE, "InsaneRebel1: Playing intro sequence"); // LucasArts logo (original: PUSH 0x57cc, CALL FUN_1BA32 with flags 0x0420) playCinematic("OPEN/O1LOGO.ANM"); @@ -347,7 +347,7 @@ void InsaneRebel1::playIntroSequence() { // lives==0: L1DEATH ??? return to menu bool InsaneRebel1::runLevel1() { - debug(1, "InsaneRebel1: Running level 1"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 1"); _currentLevel = 0; loadTuningForLevel(0); @@ -448,7 +448,7 @@ bool InsaneRebel1::runLevel1() { } bool InsaneRebel1::runLevel2() { - debug(1, "InsaneRebel1: Running level 2"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 2"); _currentLevel = 1; loadLevelSprites(2); @@ -489,7 +489,7 @@ bool InsaneRebel1::runLevel2() { } bool InsaneRebel1::runLevel3() { - debug(1, "InsaneRebel1: Running level 3"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 3"); _currentLevel = 2; loadLevelSprites(3); @@ -530,7 +530,7 @@ bool InsaneRebel1::runLevel3() { } bool InsaneRebel1::runLevel4() { - debug(1, "InsaneRebel1: Running level 4"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 4"); _currentLevel = 3; loadLevelSprites(4); @@ -600,7 +600,7 @@ bool InsaneRebel1::runLevel4() { } bool InsaneRebel1::runLevel5() { - debug(1, "InsaneRebel1: Running level 5"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 5"); _currentLevel = 4; loadLevelSprites(5); @@ -682,7 +682,7 @@ bool InsaneRebel1::runLevel5() { } bool InsaneRebel1::runLevel6() { - debug(1, "InsaneRebel1: Running level 6"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 6"); _currentLevel = 5; loadLevelSprites(6); @@ -727,7 +727,7 @@ bool InsaneRebel1::runLevel6() { } bool InsaneRebel1::runLevel7() { - debug(1, "InsaneRebel1: Running level 7"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 7"); const char *const kLevel7Segments[] = { "LVL7/L7PLAY1.ANM", @@ -811,7 +811,7 @@ bool InsaneRebel1::runLevel7() { } bool InsaneRebel1::runLevel8() { - debug(1, "InsaneRebel1: Running level 8"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 8"); const char *const kLevel8Routes[] = { "LVL8/L8PLAY.ANM", @@ -887,7 +887,7 @@ bool InsaneRebel1::runLevel8() { } bool InsaneRebel1::runLevel9() { - debug(1, "InsaneRebel1: Running level 9"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 9"); // DOS RunLevel9Flow calls RandScaleByte(2) three times before the intro. // That helper advances a byte seed with seed = seed * 9 + 0x35 and returns @@ -921,7 +921,7 @@ bool InsaneRebel1::runLevel9() { if (_killCount > 0) return (_shipPosX < kRA1CenterX) ? 0 : 1; - debug(1, "RA1 L9 selector '%s' ended without target hit; replaying", filename); + debugC(DEBUG_INSANE, "RA1 L9 selector '%s' ended without target hit; replaying", filename); } return -1; }; @@ -1077,7 +1077,7 @@ bool InsaneRebel1::runLevel9() { } bool InsaneRebel1::runLevel10() { - debug(1, "InsaneRebel1: Running level 10"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 10"); _currentLevel = 9; loadLevelSprites(10); @@ -1118,7 +1118,7 @@ bool InsaneRebel1::runLevel10() { // Turret-style level. Single interactive phase with kill-count retry. // Original: L11INTRO ??? L11PLAY (turret, killCount>4 to pass) ??? L11RETRY ??? retry/L11END bool InsaneRebel1::runLevel11() { - debug(1, "InsaneRebel1: Running level 11"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 11"); _currentLevel = 10; loadLevelSprites(11); @@ -1175,7 +1175,7 @@ bool InsaneRebel1::runLevel11() { // Single interactive phase with mid-level retry mechanism. // Original: L12INTRO ??? L12PLAY ??? (retry at specific frame) ??? L12END bool InsaneRebel1::runLevel12() { - debug(1, "InsaneRebel1: Running level 12"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 12"); _currentLevel = 11; loadLevelSprites(12); @@ -1238,7 +1238,7 @@ bool InsaneRebel1::runLevel12() { // Flight level with enemy projectile system (original has 5-slot projectile tracking). // Original: L13INTRO ??? L13PLAY ??? L13END/L13NEW/L13DEATH bool InsaneRebel1::runLevel13() { - debug(1, "InsaneRebel1: Running level 13"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 13"); _currentLevel = 12; loadLevelSprites(13); @@ -1281,7 +1281,7 @@ bool InsaneRebel1::runLevel13() { // Original: L14INTRO ??? L14PLAY ??? L14PLAY2 ??? optional L14PLY2B splice // ??? L14END/L14NEW/L14DEATH bool InsaneRebel1::runLevel14() { - debug(1, "InsaneRebel1: Running level 14"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 14"); _currentLevel = 13; loadLevelSprites(14); @@ -1355,7 +1355,7 @@ bool InsaneRebel1::runLevel14() { // Original: L15INTRO ??? L15PLAY1 (trench run) ??? L15INTR2 (torpedo lock cutscene) // ??? L15PLAY2 (final approach + torpedo) ??? L15END1/L15NEW/L15DEATH bool InsaneRebel1::runLevel15() { - debug(1, "InsaneRebel1: Running level 15"); + debugC(DEBUG_INSANE, "InsaneRebel1: Running level 15"); _currentLevel = 14; loadLevelSprites(15); @@ -1401,7 +1401,7 @@ bool InsaneRebel1::runLevel15() { } if (_health >= 0 && !_torpedoFired) { - debug(1, "InsaneRebel1: Level 15 torpedo run ended without exhaust-port hit"); + debugC(DEBUG_INSANE, "InsaneRebel1: Level 15 torpedo run ended without exhaust-port hit"); return false; } @@ -1625,30 +1625,30 @@ void InsaneRebel1::resolveSeek(const char *filename, int32 startFrame, int32 &vi _pendingRouteVideoStartFrame : 1; videoOffset = findAnimFrameChunkOffset(_vm, filename, videoStartFrame); if (videoOffset < 0) { - debug(1, "RA1 L7 route switch: route=%d destinationFrame=%d offset lookup failed", + debugC(DEBUG_INSANE, "RA1 L7 route switch: route=%d destinationFrame=%d offset lookup failed", _levelRouteIndex, (int)videoStartFrame); videoStartFrame = 0; videoOffset = 0; } else { - debug(1, "RA1 L7 route switch: route=%d decisionLocalFrame=%d opens destination at localFrame=%d offset=0x%x", + debugC(DEBUG_INSANE, "RA1 L7 route switch: route=%d decisionLocalFrame=%d opens destination at localFrame=%d offset=0x%x", _levelRouteIndex, (int)_pendingRouteStartFrame, (int)videoStartFrame, (unsigned)videoOffset); } } else if (_currentLevel == 7 && resumingRoute) { videoOffset = findAnimFrameChunkOffsetByGameCounter(_vm, filename, startFrame, videoStartFrame); if (videoOffset < 0) { - debug(1, "RA1 L8 resume: route=%d timelineFrame=%d GAME counter lookup failed", + debugC(DEBUG_INSANE, "RA1 L8 resume: route=%d timelineFrame=%d GAME counter lookup failed", _levelRouteIndex, (int)startFrame); videoStartFrame = startFrame; videoOffset = findAnimFrameChunkOffset(_vm, filename, videoStartFrame); } if (videoOffset < 0) { - debug(1, "RA1 L8 resume: route=%d timelineFrame=%d localFrame=%d offset lookup failed", + debugC(DEBUG_INSANE, "RA1 L8 resume: route=%d timelineFrame=%d localFrame=%d offset lookup failed", _levelRouteIndex, (int)startFrame, (int)videoStartFrame); videoStartFrame = 0; videoOffset = 0; } else { - debug(1, "RA1 L8 resume: route=%d timelineFrame=%d -> localFrame=%d offset=0x%x", + debugC(DEBUG_INSANE, "RA1 L8 resume: route=%d timelineFrame=%d -> localFrame=%d offset=0x%x", _levelRouteIndex, (int)startFrame, (int)videoStartFrame, (unsigned)videoOffset); } } else if (_currentLevel == 13 && resumingRoute) { @@ -1656,7 +1656,7 @@ void InsaneRebel1::resolveSeek(const char *filename, int32 startFrame, int32 &vi // oldMaxFrame-0x0F, 1, -1). That frame number belongs to L14PLAY2's // timeline; L14PLY2B is already the continuation clip and starts at its // matching lead-in frame. Preserve the current state, but do not seek. - debug(1, "RA1 L14 splice: L14PLAY2 timelineFrame=%d -> L14PLY2B frame 0", + debugC(DEBUG_INSANE, "RA1 L14 splice: L14PLAY2 timelineFrame=%d -> L14PLY2B frame 0", (int)startFrame); } } @@ -1690,7 +1690,7 @@ void InsaneRebel1::playInteractiveVideoFile(const char *filename, int32 videoOff // Play interactive gameplay video (with ship physics + HUD). void InsaneRebel1::playInteractiveVideo(const char *filename, int32 startFrame) { - debug(1, "InsaneRebel1::playInteractiveVideo('%s', startFrame=%d)", filename, startFrame); + debugC(DEBUG_INSANE, "InsaneRebel1::playInteractiveVideo('%s', startFrame=%d)", filename, startFrame); if (shouldAbortGameFlow()) return; diff --git a/engines/scumm/insane/rebel1/saveload.cpp b/engines/scumm/insane/rebel1/saveload.cpp index 06849925a7f..09335106b4d 100644 --- a/engines/scumm/insane/rebel1/saveload.cpp +++ b/engines/scumm/insane/rebel1/saveload.cpp @@ -115,7 +115,7 @@ Common::Error InsaneRebel1::writeSaveState(int slot, const Common::String &desc, return Common::kWritingFailed; } - debug(1, "RA1: saved slot=%d level=%d lives=%d score=%d desc='%s'", + debugC(DEBUG_INSANE, "RA1: saved slot=%d level=%d lives=%d score=%d desc='%s'", slot, state.resumeLevel, state.lives, state.score, desc.c_str()); return Common::kNoError; } @@ -219,7 +219,7 @@ Common::Error InsaneRebel1::loadGameState(int slot, bool startupLoad) { _vm->_smushVideoShouldFinish = true; } - debug(1, "RA1: loaded slot=%d level=%d lives=%d score=%d", slot, _resumeLevel, _lives, _score); + debugC(DEBUG_INSANE, "RA1: loaded slot=%d level=%d lives=%d score=%d", slot, _resumeLevel, _lives, _score); return Common::kNoError; } @@ -238,7 +238,7 @@ void InsaneRebel1::autosaveProgress() { if (readSaveState(slot, oldState, &oldDesc)) { if (oldState.resumeLevel > state.resumeLevel || (oldState.resumeLevel == state.resumeLevel && oldState.lives >= state.lives)) { - debug(1, "RA1: skipping autosave slot=%d level=%d lives=%d; existing level=%d lives=%d", + debugC(DEBUG_INSANE, "RA1: skipping autosave slot=%d level=%d lives=%d; existing level=%d lives=%d", slot, state.resumeLevel, state.lives, oldState.resumeLevel, oldState.lives); return; } Commit: 912e8b3bf4d05644c64d0a5df38a942d90bf29bb https://github.com/scummvm/scummvm/commit/912e8b3bf4d05644c64d0a5df38a942d90bf29bb Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T09:31:15+02:00 Commit Message: SCUMM: RA: improve debug statements with class/function names Changed paths: engines/scumm/insane/rebel1/levels.cpp engines/scumm/insane/rebel1/menu.cpp engines/scumm/insane/rebel1/rebel.cpp engines/scumm/insane/rebel1/runlevels.cpp engines/scumm/smush/rebel/codec_ra2.cpp engines/scumm/smush/rebel/smush_player_ra1.cpp engines/scumm/smush/rebel/smush_player_ra2.cpp diff --git a/engines/scumm/insane/rebel1/levels.cpp b/engines/scumm/insane/rebel1/levels.cpp index 5e050f17d8c..b24fb5b85d0 100644 --- a/engines/scumm/insane/rebel1/levels.cpp +++ b/engines/scumm/insane/rebel1/levels.cpp @@ -169,14 +169,14 @@ void InsaneRebel1::loadLevelSprites(int level) { if (!loadRA1Nut(legacyBankFile.c_str(), _shipBank)) { Common::String pilotFile = Common::String::format("LVL%d/L%dPILOT.NUT", level, level); if (!loadRA1Nut(pilotFile.c_str(), _shipBank)) - debugC(DEBUG_INSANE, "InsaneRebel1: No BANK1/BANK/PILOT for level %d", level); + debugC(DEBUG_INSANE, "InsaneRebel1::loadLevelSprites: No BANK1/BANK/PILOT for level %d", level); } } // Secondary ship bank used by some level-specific handlers (e.g. LVL1 mode-2). Common::String bankFileAlt = Common::String::format("LVL%d/L%dBANK2.NUT", level, level); if (!loadRA1Nut(bankFileAlt.c_str(), _shipBankAlt)) { - debugC(DEBUG_INSANE, "InsaneRebel1: No BANK2 for level %d", level); + debugC(DEBUG_INSANE, "InsaneRebel1::loadLevelSprites: No BANK2 for level %d", level); } loadRA1Nut("SYS/DISPLAY.NUT", _displayBank); diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp index 42c09914d77..3ded18a95d8 100644 --- a/engines/scumm/insane/rebel1/menu.cpp +++ b/engines/scumm/insane/rebel1/menu.cpp @@ -676,7 +676,7 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { return true; } - debugC(DEBUG_INSANE, "Rebel1: ESC pressed during gameplay - opening ScummVM menu"); + debugC(DEBUG_INSANE, "InsaneRebel1::notifyEvent: ESC pressed during gameplay - opening ScummVM menu"); const bool wasPaused = _player->_paused; if (!wasPaused) _player->pause(); @@ -689,13 +689,13 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { if (_interactiveVideoActive && !_menuActive && event.kbd.keycode == Common::KEYCODE_s && event.kbd.hasFlags(Common::KBD_SHIFT)) { - debugC(DEBUG_INSANE, "Rebel1: Shift+S pressed - skipping gameplay section"); + debugC(DEBUG_INSANE, "InsaneRebel1::notifyEvent: Shift+S pressed - skipping gameplay section"); _vm->_smushVideoShouldFinish = true; return true; } if (!_interactiveVideoActive && event.kbd.keycode == Common::KEYCODE_ESCAPE) { - debugC(DEBUG_INSANE, "Rebel1: ESC pressed - skipping cinematic"); + debugC(DEBUG_INSANE, "InsaneRebel1::notifyEvent: ESC pressed - skipping cinematic"); _vm->_smushVideoShouldFinish = true; return true; } @@ -929,7 +929,7 @@ bool InsaneRebel1::runTextEntryMenuLoop() { } int InsaneRebel1::runMainMenu() { - debugC(DEBUG_INSANE, "InsaneRebel1: Main menu"); + debugC(DEBUG_INSANE, "InsaneRebel1::runMainMenu: Main menu"); _menuSelection = 0; while (!shouldAbortGameFlow()) { diff --git a/engines/scumm/insane/rebel1/rebel.cpp b/engines/scumm/insane/rebel1/rebel.cpp index 6ebd1efd8e8..af3ecab61c7 100644 --- a/engines/scumm/insane/rebel1/rebel.cpp +++ b/engines/scumm/insane/rebel1/rebel.cpp @@ -404,29 +404,29 @@ InsaneRebel1::InsaneRebel1(ScummEngine_v7 *scumm) : Insane(), _vm(scumm) { resetFrameObjectState(); if (loadRA1Nut("SYS/TALKFONT.NUT", _hudFontBank)) { - debugC(DEBUG_INSANE, "InsaneRebel1: HUD/menu glyph font loaded from SYS/TALKFONT.NUT (%d chars)", _hudFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1::InsaneRebel1(): HUD/menu glyph font loaded from SYS/TALKFONT.NUT (%d chars)", _hudFontBank.numSprites); } else if (loadRA1Nut("SYS/TECHFONT.NUT", _hudFontBank)) { - debugC(DEBUG_INSANE, "InsaneRebel1: HUD/menu glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _hudFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1::InsaneRebel1(): HUD/menu glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _hudFontBank.numSprites); } else { - warning("InsaneRebel1: failed to load RA1 HUD font bank (TECHFONT/TALKFONT)"); + warning("InsaneRebel1::InsaneRebel1(): failed to load RA1 HUD font bank (TECHFONT/TALKFONT)"); } if (loadRA1Nut("SYS/TITLFONT.NUT", _titleFontBank)) { - debugC(DEBUG_INSANE, "InsaneRebel1: title glyph font loaded from SYS/TITLFONT.NUT (%d chars)", _titleFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1::InsaneRebel1(): title glyph font loaded from SYS/TITLFONT.NUT (%d chars)", _titleFontBank.numSprites); } else if (loadRA1Nut("SYS/TALKFONT.NUT", _titleFontBank)) { - debugC(DEBUG_INSANE, "InsaneRebel1: title glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _titleFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1::InsaneRebel1(): title glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _titleFontBank.numSprites); } else { - warning("InsaneRebel1: failed to load title font bank (TITLFONT/TALKFONT)"); + warning("InsaneRebel1::InsaneRebel1(): failed to load title font bank (TITLFONT/TALKFONT)"); } // FUN_1CB22 uses "<<" layer markers that resolve to TECHFONT in the original. // Keep a dedicated TECH font bank for targeting markers/lock indicators. if (loadRA1Nut("SYS/TECHFONT.NUT", _techFontBank)) { - debugC(DEBUG_INSANE, "InsaneRebel1: targeting glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _techFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1::InsaneRebel1(): targeting glyph font loaded from SYS/TECHFONT.NUT (%d chars)", _techFontBank.numSprites); } else if (loadRA1Nut("SYS/TALKFONT.NUT", _techFontBank)) { - debugC(DEBUG_INSANE, "InsaneRebel1: targeting glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _techFontBank.numSprites); + debugC(DEBUG_INSANE, "InsaneRebel1::InsaneRebel1(): targeting glyph font fallback loaded from SYS/TALKFONT.NUT (%d chars)", _techFontBank.numSprites); } else { - warning("InsaneRebel1: failed to load targeting font bank (TECHFONT/TALKFONT)"); + warning("InsaneRebel1::InsaneRebel1(): failed to load targeting font bank (TECHFONT/TALKFONT)"); } // Audio diff --git a/engines/scumm/insane/rebel1/runlevels.cpp b/engines/scumm/insane/rebel1/runlevels.cpp index 62c35eaf205..0e9f86c23c0 100644 --- a/engines/scumm/insane/rebel1/runlevels.cpp +++ b/engines/scumm/insane/rebel1/runlevels.cpp @@ -315,7 +315,7 @@ void InsaneRebel1::clearVideoBuffer() { // 1. O1LOGO.ANM ??? LucasArts logo // 2. O1OPEN.ANM ??? Star Wars opening crawl void InsaneRebel1::playIntroSequence() { - debugC(DEBUG_INSANE, "InsaneRebel1: Playing intro sequence"); + debugC(DEBUG_INSANE, "InsaneRebel1::playIntroSequence: Playing intro sequence"); // LucasArts logo (original: PUSH 0x57cc, CALL FUN_1BA32 with flags 0x0420) playCinematic("OPEN/O1LOGO.ANM"); @@ -347,7 +347,7 @@ void InsaneRebel1::playIntroSequence() { // lives==0: L1DEATH ??? return to menu bool InsaneRebel1::runLevel1() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 1"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel1: Running level 1"); _currentLevel = 0; loadTuningForLevel(0); @@ -448,7 +448,7 @@ bool InsaneRebel1::runLevel1() { } bool InsaneRebel1::runLevel2() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 2"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel2: Running level 2"); _currentLevel = 1; loadLevelSprites(2); @@ -489,7 +489,7 @@ bool InsaneRebel1::runLevel2() { } bool InsaneRebel1::runLevel3() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 3"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel3: Running level 3"); _currentLevel = 2; loadLevelSprites(3); @@ -530,7 +530,7 @@ bool InsaneRebel1::runLevel3() { } bool InsaneRebel1::runLevel4() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 4"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel4: Running level 4"); _currentLevel = 3; loadLevelSprites(4); @@ -600,7 +600,7 @@ bool InsaneRebel1::runLevel4() { } bool InsaneRebel1::runLevel5() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 5"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel5: Running level 5"); _currentLevel = 4; loadLevelSprites(5); @@ -682,7 +682,7 @@ bool InsaneRebel1::runLevel5() { } bool InsaneRebel1::runLevel6() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 6"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel6: Running level 6"); _currentLevel = 5; loadLevelSprites(6); @@ -727,7 +727,7 @@ bool InsaneRebel1::runLevel6() { } bool InsaneRebel1::runLevel7() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 7"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel7: Running level 7"); const char *const kLevel7Segments[] = { "LVL7/L7PLAY1.ANM", @@ -811,7 +811,7 @@ bool InsaneRebel1::runLevel7() { } bool InsaneRebel1::runLevel8() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 8"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel8: Running level 8"); const char *const kLevel8Routes[] = { "LVL8/L8PLAY.ANM", @@ -887,7 +887,7 @@ bool InsaneRebel1::runLevel8() { } bool InsaneRebel1::runLevel9() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 9"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel9: Running level 9"); // DOS RunLevel9Flow calls RandScaleByte(2) three times before the intro. // That helper advances a byte seed with seed = seed * 9 + 0x35 and returns @@ -1077,7 +1077,7 @@ bool InsaneRebel1::runLevel9() { } bool InsaneRebel1::runLevel10() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 10"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel10: Running level 10"); _currentLevel = 9; loadLevelSprites(10); @@ -1118,7 +1118,7 @@ bool InsaneRebel1::runLevel10() { // Turret-style level. Single interactive phase with kill-count retry. // Original: L11INTRO ??? L11PLAY (turret, killCount>4 to pass) ??? L11RETRY ??? retry/L11END bool InsaneRebel1::runLevel11() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 11"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel11: Running level 11"); _currentLevel = 10; loadLevelSprites(11); @@ -1175,7 +1175,7 @@ bool InsaneRebel1::runLevel11() { // Single interactive phase with mid-level retry mechanism. // Original: L12INTRO ??? L12PLAY ??? (retry at specific frame) ??? L12END bool InsaneRebel1::runLevel12() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 12"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel12: Running level 12"); _currentLevel = 11; loadLevelSprites(12); @@ -1238,7 +1238,7 @@ bool InsaneRebel1::runLevel12() { // Flight level with enemy projectile system (original has 5-slot projectile tracking). // Original: L13INTRO ??? L13PLAY ??? L13END/L13NEW/L13DEATH bool InsaneRebel1::runLevel13() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 13"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel13: Running level 13"); _currentLevel = 12; loadLevelSprites(13); @@ -1281,7 +1281,7 @@ bool InsaneRebel1::runLevel13() { // Original: L14INTRO ??? L14PLAY ??? L14PLAY2 ??? optional L14PLY2B splice // ??? L14END/L14NEW/L14DEATH bool InsaneRebel1::runLevel14() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 14"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel14: Running level 14"); _currentLevel = 13; loadLevelSprites(14); @@ -1355,7 +1355,7 @@ bool InsaneRebel1::runLevel14() { // Original: L15INTRO ??? L15PLAY1 (trench run) ??? L15INTR2 (torpedo lock cutscene) // ??? L15PLAY2 (final approach + torpedo) ??? L15END1/L15NEW/L15DEATH bool InsaneRebel1::runLevel15() { - debugC(DEBUG_INSANE, "InsaneRebel1: Running level 15"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel15: Running level 15"); _currentLevel = 14; loadLevelSprites(15); @@ -1401,7 +1401,7 @@ bool InsaneRebel1::runLevel15() { } if (_health >= 0 && !_torpedoFired) { - debugC(DEBUG_INSANE, "InsaneRebel1: Level 15 torpedo run ended without exhaust-port hit"); + debugC(DEBUG_INSANE, "InsaneRebel1::runLevel15: Level 15 torpedo run ended without exhaust-port hit"); return false; } diff --git a/engines/scumm/smush/rebel/codec_ra2.cpp b/engines/scumm/smush/rebel/codec_ra2.cpp index 7ca7dd2e0d1..44f454f88b4 100644 --- a/engines/scumm/smush/rebel/codec_ra2.cpp +++ b/engines/scumm/smush/rebel/codec_ra2.cpp @@ -274,7 +274,7 @@ void smushDecodeRA2Bomp(byte *dst, const byte *src, int left, int top, int width } if (!foundValidOffset) { - warning("Rebel2: Codec 45 couldn't find valid RLE offset, using offset 0"); + warning("smushDecodeRA2Bomp: Codec 45 couldn't find valid RLE offset, using offset 0"); } src += headerSkip; diff --git a/engines/scumm/smush/rebel/smush_player_ra1.cpp b/engines/scumm/smush/rebel/smush_player_ra1.cpp index de6aad330bf..6c6712b787c 100644 --- a/engines/scumm/smush/rebel/smush_player_ra1.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra1.cpp @@ -581,7 +581,7 @@ bool SmushPlayerRebel1::handleGameCodecDecode(int codec, const uint8 *src, int l return true; } default: - debugC(DEBUG_SMUSH, "SmushPlayer::decodeFrameObject: Skipping unknown codec %d (left=%d, top=%d, %dx%d)", + debugC(DEBUG_SMUSH, "SmushPlayerRebel1::handleGameCodecDecode: Skipping unknown codec %d (left=%d, top=%d, %dx%d)", codec, left, top, width, height); return true; } diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp index 53afda31784..6b3da4f7524 100644 --- a/engines/scumm/smush/rebel/smush_player_ra2.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp @@ -152,7 +152,7 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea int16 ftchX = b.readSint16LE(); int16 ftchY = b.readSint16LE(); - debugC(DEBUG_SMUSH, "SmushPlayer::handleFetch: frame=%d unknown=%d x=%d y=%d", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameFetch: frame=%d unknown=%d x=%d y=%d", _frame, ftchUnknown, ftchX, ftchY); // For Handler 25, skip FTCH because the frame buffer only contains the @@ -162,14 +162,14 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea InsaneRebel2 *rebel2 = static_cast(_insane); int handler = rebel2->getHandler(); if (handler == 25) { - debugC(DEBUG_SMUSH, "SmushPlayer::handleFetch: Skipping FTCH for Handler 25 - preserving overlays"); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameFetch: Skipping FTCH for Handler 25 - preserving overlays"); return true; } } // Re-decode stored FOBJ data with current offsets (matching original FUN_004246d0). if (_storedFobjData != nullptr) { - debugC(DEBUG_SMUSH, "SmushPlayer FTCH: Re-decoding stored FOBJ codec=%d pos=(%d,%d) size=%dx%d dataSize=%d", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameFetch FTCH: Re-decoding stored FOBJ codec=%d pos=(%d,%d) size=%dx%d dataSize=%d", _storedFobjCodec, _storedFobjLeft, _storedFobjTop, _storedFobjWidth, _storedFobjHeight, _storedFobjDataSize); decodeFrameObject(_storedFobjCodec, _storedFobjData, @@ -177,7 +177,7 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea _storedFobjWidth, _storedFobjHeight, _storedFobjDataSize); } else { - debugC(DEBUG_SMUSH, "SmushPlayer FTCH: No stored FOBJ data! (frame=%d)", _frame); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameFetch FTCH: No stored FOBJ data! (frame=%d)", _frame); } return true; @@ -210,7 +210,7 @@ SmushFont *SmushPlayerRebel2::getGameFont(int font) { if (font >= 0 && font < numFonts) { _sf[font] = new SmushFont(_vm, ra2_fonts[font], true); } else { - debugC(DEBUG_SMUSH, "SmushPlayer::getFont: RA2 unknown font %d, using TALKFONT", font); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::getGameFont: RA2 unknown font %d, using TALKFONT", font); _sf[font] = new SmushFont(_vm, ra2_fonts[0], true); } return _sf[font]; @@ -392,7 +392,7 @@ bool SmushPlayerRebel2::handleGameAnimHeader(byte *headerContent) { if (width == 0 && height == 0) { _width = _vm->_screenWidth; _height = _vm->_screenHeight; - debugC(DEBUG_SMUSH, "SmushPlayer::handleAnimHeader: RA2 AHDR has 0x0 dims - using screen size %dx%d", _width, _height); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameAnimHeader: RA2 AHDR has 0x0 dims - using screen size %dx%d", _width, _height); } else { _width = width; _height = height; @@ -415,10 +415,10 @@ void SmushPlayerRebel2::handleGameLoad(int32 subSize, Common::SeekableReadStream * The data is accumulated in a buffer and consumed by the audio system. */ void SmushPlayerRebel2::handleLoad(int32 subSize, Common::SeekableReadStream &b) { - debugC(DEBUG_SMUSH, "SmushPlayer::handleLoad()"); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleLoad()"); if (subSize < 10) { - warning("SmushPlayer::handleLoad: chunk too small (%d bytes)", subSize); + warning("SmushPlayerRebel2::handleLoad: chunk too small (%d bytes)", subSize); return; } @@ -428,7 +428,7 @@ void SmushPlayerRebel2::handleLoad(int32 subSize, Common::SeekableReadStream &b) int32 dataSize = subSize - 10; - debugC(DEBUG_SMUSH, "SmushPlayer::handleLoad: chunk %d/%d, dataSize=%d, bufferOffset=%d", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleLoad: chunk %d/%d, dataSize=%d, bufferOffset=%d", chunkIndex, totalChunks, dataSize, _loadBufferOffset); // First chunk in sequence - reset buffer state @@ -444,26 +444,26 @@ void SmushPlayerRebel2::handleLoad(int32 subSize, Common::SeekableReadStream &b) _loadBufferSize = estimatedSize; _loadBuffer = (byte *)malloc(_loadBufferSize); if (_loadBuffer == nullptr) { - warning("SmushPlayer::handleLoad: Failed to allocate %d bytes for LOAD buffer", + warning("SmushPlayerRebel2::handleLoad: Failed to allocate %d bytes for LOAD buffer", _loadBufferSize); _loadBufferSize = 0; return; } - debugC(DEBUG_SMUSH, "SmushPlayer::handleLoad: Allocated %d bytes for LOAD buffer", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleLoad: Allocated %d bytes for LOAD buffer", _loadBufferSize); } } // Check sequential order if (_lastLoadChunkIdx + 1 != chunkIndex) { - debugC(DEBUG_SMUSH, "SmushPlayer::handleLoad: Non-sequential chunk %d (expected %d), skipping", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleLoad: Non-sequential chunk %d (expected %d), skipping", chunkIndex, _lastLoadChunkIdx + 1); return; } // Check buffer capacity if (_loadBuffer == nullptr || _loadBufferOffset + dataSize >= _loadBufferSize) { - warning("SmushPlayer::handleLoad: Buffer overflow - offset=%d size=%d limit=%d", + warning("SmushPlayerRebel2::handleLoad: Buffer overflow - offset=%d size=%d limit=%d", _loadBufferOffset, dataSize, _loadBufferSize); return; } @@ -473,10 +473,10 @@ void SmushPlayerRebel2::handleLoad(int32 subSize, Common::SeekableReadStream &b) _loadBufferOffset += dataSize; _lastLoadChunkIdx = chunkIndex; - debugC(DEBUG_SMUSH, "SmushPlayer::handleLoad: Accumulated %d bytes total", _loadBufferOffset); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleLoad: Accumulated %d bytes total", _loadBufferOffset); if (chunkIndex == totalChunks - 1) { - debugC(DEBUG_SMUSH, "SmushPlayer::handleLoad: Sequence complete - %d chunks, %d bytes total", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleLoad: Sequence complete - %d chunks, %d bytes total", totalChunks, _loadBufferOffset); } } @@ -490,7 +490,7 @@ void SmushPlayerRebel2::ra2HandleTextResource(const char *str, int fontId, int c ensureMultiFont(); _multiFont->setDefaultFont(fontId); - debugC(DEBUG_SMUSH, "SmushPlayer::handleTextResource: RA2 TRES frame=%d fontId=%d color=%d flags=0x%x flg=%d pos=(%d,%d) clip=(%d,%d,%d,%d) str=\"%.40s\"", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2HandleTextResource: RA2 TRES frame=%d fontId=%d color=%d flags=0x%x flg=%d pos=(%d,%d) clip=(%d,%d,%d,%d) str=\"%.40s\"", _frame, fontId, color, (int)flg, (int)flg, pos_x, pos_y, left, top, width, height, str); if (flg & kStyleWordWrap) { @@ -521,24 +521,24 @@ void SmushPlayerRebel2::ra2SelectFrameBuffer(int width, int height) { _height = height; // Zero-fill the new buffer to avoid garbage in areas not written by FOBJ codec memset(_specialBuffer, 0, bufSize); - debugC(DEBUG_SMUSH, "SmushPlayer: Allocated new _specialBuffer %dx%d (%d bytes)", width, height, bufSize); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Allocated new _specialBuffer %dx%d (%d bytes)", width, height, bufSize); } } if (bufSize > _vm->_screenWidth * _vm->_screenHeight && _specialBuffer != nullptr && _specialBufferSize >= bufSize) { _dst = _specialBuffer; - debugC(DEBUG_SMUSH, "SmushPlayer: Using _specialBuffer for oversized FOBJ %dx%d", width, height); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Using _specialBuffer for oversized FOBJ %dx%d", width, height); } else { if (_specialBuffer == nullptr) { VirtScreen *vs = &_vm->_virtscr[kMainVirtScreen]; _dst = vs->getPixels(0, 0); - debugC(DEBUG_SMUSH, "SmushPlayer: Reset _dst to virtual screen for FOBJ %dx%d at (%d,%d) _dst=%p", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Reset _dst to virtual screen for FOBJ %dx%d at (%d,%d) _dst=%p", width, height, 0, 0, (void*)_dst); } else { // Large frame was in this video, use _specialBuffer for compositing _dst = _specialBuffer; - debugC(DEBUG_SMUSH, "SmushPlayer: Using _specialBuffer for small FOBJ %dx%d (compositing with large frame)", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Using _specialBuffer for small FOBJ %dx%d (compositing with large frame)", width, height); } } @@ -605,7 +605,7 @@ void SmushPlayerRebel2::ra2HandleGost(int32 subSize, Common::SeekableReadStream int16 ghostY = b.readSint16LE(); if (!_hasFrameFobjForGost || _lastFobjData == nullptr || _lastFobjDataSize <= 0) { - debugC(DEBUG_SMUSH, "SmushPlayer GOST: frame=%d ignored (no current-frame FOBJ cached)", _frame); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2HandleGost GOST: frame=%d ignored (no current-frame FOBJ cached)", _frame); return; } @@ -623,7 +623,7 @@ void SmushPlayerRebel2::ra2HandleGost(int32 subSize, Common::SeekableReadStream int left = _lastFobjLeft + ghostX; int top = _lastFobjTop + ghostY; - debugC(DEBUG_SMUSH, "SmushPlayer GOST: frame=%d type=%d flags=0x%04x gostPos=(%d,%d) basePos=(%d,%d) finalPos=(%d,%d) size=%dx%d codec=%d", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2HandleGost GOST: frame=%d type=%d flags=0x%04x gostPos=(%d,%d) basePos=(%d,%d) finalPos=(%d,%d) size=%dx%d codec=%d", _frame, ghostType, priorityFlags, ghostX, ghostY, _lastFobjLeft, _lastFobjTop, left, top, _lastFobjWidth, _lastFobjHeight, _lastFobjCodec); @@ -691,7 +691,7 @@ bool SmushPlayerRebel2::handleGameStoreFrame() { } void SmushPlayerRebel2::handleGameFrameObjectPre(int codec, int left, int top, int width, int height, int dataSize) { - debugC(DEBUG_SMUSH, "SmushPlayer FOBJ: frame=%d codec=%d pos=(%d,%d) size=%dx%d dataSize=%d storeFrame=%d _width=%d _height=%d", + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameFrameObjectPre FOBJ: frame=%d codec=%d pos=(%d,%d) size=%dx%d dataSize=%d storeFrame=%d _width=%d _height=%d", _frame, codec, left, top, width, height, dataSize, _storeFrame, _width, _height); } @@ -710,7 +710,7 @@ void SmushPlayerRebel2::handleGameFrameStart() { bool SmushPlayerRebel2::handleGameSkipChunk(uint32 subType, int32 subSize, Common::SeekableReadStream &b) { if (_skipNext) { _skipNext = false; - debugC(DEBUG_SMUSH, "SmushPlayer::handleFrame: SKIP consumed chunk %s frame=%d", tag2str(subType), _frame); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameSkipChunk: SKIP consumed chunk %s frame=%d", tag2str(subType), _frame); return true; } return false; Commit: e44a371ebd858f7fb84d427b2c478bafefd1fa4e https://github.com/scummvm/scummvm/commit/e44a371ebd858f7fb84d427b2c478bafefd1fa4e Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T09:43:41+02:00 Commit Message: SCUMM: RA: removed some redundant/useless debug statement Changed paths: engines/scumm/insane/rebel1/menu.cpp engines/scumm/insane/rebel1/render.cpp engines/scumm/insane/rebel1/runlevels.cpp engines/scumm/smush/rebel/smush_player_ra2.cpp diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp index 3ded18a95d8..cf8a11e568a 100644 --- a/engines/scumm/insane/rebel1/menu.cpp +++ b/engines/scumm/insane/rebel1/menu.cpp @@ -676,7 +676,6 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { return true; } - debugC(DEBUG_INSANE, "InsaneRebel1::notifyEvent: ESC pressed during gameplay - opening ScummVM menu"); const bool wasPaused = _player->_paused; if (!wasPaused) _player->pause(); @@ -689,13 +688,11 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { if (_interactiveVideoActive && !_menuActive && event.kbd.keycode == Common::KEYCODE_s && event.kbd.hasFlags(Common::KBD_SHIFT)) { - debugC(DEBUG_INSANE, "InsaneRebel1::notifyEvent: Shift+S pressed - skipping gameplay section"); _vm->_smushVideoShouldFinish = true; return true; } if (!_interactiveVideoActive && event.kbd.keycode == Common::KEYCODE_ESCAPE) { - debugC(DEBUG_INSANE, "InsaneRebel1::notifyEvent: ESC pressed - skipping cinematic"); _vm->_smushVideoShouldFinish = true; return true; } @@ -929,8 +926,6 @@ bool InsaneRebel1::runTextEntryMenuLoop() { } int InsaneRebel1::runMainMenu() { - debugC(DEBUG_INSANE, "InsaneRebel1::runMainMenu: Main menu"); - _menuSelection = 0; while (!shouldAbortGameFlow()) { playMenuBackground(); diff --git a/engines/scumm/insane/rebel1/render.cpp b/engines/scumm/insane/rebel1/render.cpp index 110c3911e43..ac5c801a121 100644 --- a/engines/scumm/insane/rebel1/render.cpp +++ b/engines/scumm/insane/rebel1/render.cpp @@ -1731,9 +1731,6 @@ void InsaneRebel1::renderHUD(byte *dst, int pitch, int width, int height) { memcpy(d, s, drawW); } } - - debug(5, "RA1 HUD: drawn at (%d,%d) size=%dx%d", - hudPlateX, hudPlateY, bar.width, bar.height); } // Draw health bar from FUN_1BBCB (0x1BBCB) + FUN_21D66 (0x21D66): diff --git a/engines/scumm/insane/rebel1/runlevels.cpp b/engines/scumm/insane/rebel1/runlevels.cpp index 0e9f86c23c0..cb9c68b8058 100644 --- a/engines/scumm/insane/rebel1/runlevels.cpp +++ b/engines/scumm/insane/rebel1/runlevels.cpp @@ -315,8 +315,6 @@ void InsaneRebel1::clearVideoBuffer() { // 1. O1LOGO.ANM ??? LucasArts logo // 2. O1OPEN.ANM ??? Star Wars opening crawl void InsaneRebel1::playIntroSequence() { - debugC(DEBUG_INSANE, "InsaneRebel1::playIntroSequence: Playing intro sequence"); - // LucasArts logo (original: PUSH 0x57cc, CALL FUN_1BA32 with flags 0x0420) playCinematic("OPEN/O1LOGO.ANM"); if (shouldAbortGameFlow()) @@ -347,8 +345,6 @@ void InsaneRebel1::playIntroSequence() { // lives==0: L1DEATH ??? return to menu bool InsaneRebel1::runLevel1() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel1: Running level 1"); - _currentLevel = 0; loadTuningForLevel(0); loadLevelSprites(1); @@ -448,8 +444,6 @@ bool InsaneRebel1::runLevel1() { } bool InsaneRebel1::runLevel2() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel2: Running level 2"); - _currentLevel = 1; loadLevelSprites(2); // DOS RunLevel2Flow launches L2PLAY.ANM with gameplay selector 2. @@ -489,8 +483,6 @@ bool InsaneRebel1::runLevel2() { } bool InsaneRebel1::runLevel3() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel3: Running level 3"); - _currentLevel = 2; loadLevelSprites(3); // DOS RunLevel3Flow launches L3PLAY.ANM with gameplay selector 3. @@ -530,8 +522,6 @@ bool InsaneRebel1::runLevel3() { } bool InsaneRebel1::runLevel4() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel4: Running level 4"); - _currentLevel = 3; loadLevelSprites(4); // DOS RunLevel4Flow launches L4PLAY1.ANM with selector 4 and L4PLAY2.ANM with selector 5. @@ -600,8 +590,6 @@ bool InsaneRebel1::runLevel4() { } bool InsaneRebel1::runLevel5() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel5: Running level 5"); - _currentLevel = 4; loadLevelSprites(5); // DOS RunLevel5Flow passes segment 6 for L5PLAY and segment 7 for L5PLAY2. @@ -682,8 +670,6 @@ bool InsaneRebel1::runLevel5() { } bool InsaneRebel1::runLevel6() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel6: Running level 6"); - _currentLevel = 5; loadLevelSprites(6); // DOS RunLevel6Flow starts L6PLAY with PlayAnmFile(..., 8), so chapter 6 @@ -727,8 +713,6 @@ bool InsaneRebel1::runLevel6() { } bool InsaneRebel1::runLevel7() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel7: Running level 7"); - const char *const kLevel7Segments[] = { "LVL7/L7PLAY1.ANM", "LVL7/L7PLAY2.ANM", @@ -811,8 +795,6 @@ bool InsaneRebel1::runLevel7() { } bool InsaneRebel1::runLevel8() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel8: Running level 8"); - const char *const kLevel8Routes[] = { "LVL8/L8PLAY.ANM", "LVL8/L8PLAY2.ANM", @@ -887,8 +869,6 @@ bool InsaneRebel1::runLevel8() { } bool InsaneRebel1::runLevel9() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel9: Running level 9"); - // DOS RunLevel9Flow calls RandScaleByte(2) three times before the intro. // That helper advances a byte seed with seed = seed * 9 + 0x35 and returns // (2 * seed) >> 8. Do not use ScummVM's session RNG here: it can turn the @@ -1077,8 +1057,6 @@ bool InsaneRebel1::runLevel9() { } bool InsaneRebel1::runLevel10() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel10: Running level 10"); - _currentLevel = 9; loadLevelSprites(10); // DOS RunLevel10Flow starts L10PLAY.ANM with initLevelFlag=0x0D. @@ -1118,8 +1096,6 @@ bool InsaneRebel1::runLevel10() { // Turret-style level. Single interactive phase with kill-count retry. // Original: L11INTRO ??? L11PLAY (turret, killCount>4 to pass) ??? L11RETRY ??? retry/L11END bool InsaneRebel1::runLevel11() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel11: Running level 11"); - _currentLevel = 10; loadLevelSprites(11); // DOS RunLevel11Flow starts L11PLAY.ANM with initLevelFlag=0x0E. @@ -1175,8 +1151,6 @@ bool InsaneRebel1::runLevel11() { // Single interactive phase with mid-level retry mechanism. // Original: L12INTRO ??? L12PLAY ??? (retry at specific frame) ??? L12END bool InsaneRebel1::runLevel12() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel12: Running level 12"); - _currentLevel = 11; loadLevelSprites(12); // DOS RunLevel12Flow starts L12PLAY.ANM with initLevelFlag=0x0F. @@ -1238,8 +1212,6 @@ bool InsaneRebel1::runLevel12() { // Flight level with enemy projectile system (original has 5-slot projectile tracking). // Original: L13INTRO ??? L13PLAY ??? L13END/L13NEW/L13DEATH bool InsaneRebel1::runLevel13() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel13: Running level 13"); - _currentLevel = 12; loadLevelSprites(13); loadRA1Nut("LVL13/L13LASR2.NUT", _enemyLaserBank); @@ -1281,8 +1253,6 @@ bool InsaneRebel1::runLevel13() { // Original: L14INTRO ??? L14PLAY ??? L14PLAY2 ??? optional L14PLY2B splice // ??? L14END/L14NEW/L14DEATH bool InsaneRebel1::runLevel14() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel14: Running level 14"); - _currentLevel = 13; loadLevelSprites(14); // DOS RunLevel14Flow uses selector 0x11 for L14PLAY and 0x12 for L14PLAY2. @@ -1355,8 +1325,6 @@ bool InsaneRebel1::runLevel14() { // Original: L15INTRO ??? L15PLAY1 (trench run) ??? L15INTR2 (torpedo lock cutscene) // ??? L15PLAY2 (final approach + torpedo) ??? L15END1/L15NEW/L15DEATH bool InsaneRebel1::runLevel15() { - debugC(DEBUG_INSANE, "InsaneRebel1::runLevel15: Running level 15"); - _currentLevel = 14; loadLevelSprites(15); // DOS RunLevel1GameLoop uses selector 0x13 for L15PLAY1 and 0x14 for L15PLAY2. diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp index 6b3da4f7524..dc0ffb3b21b 100644 --- a/engines/scumm/smush/rebel/smush_player_ra2.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp @@ -490,8 +490,8 @@ void SmushPlayerRebel2::ra2HandleTextResource(const char *str, int fontId, int c ensureMultiFont(); _multiFont->setDefaultFont(fontId); - debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2HandleTextResource: RA2 TRES frame=%d fontId=%d color=%d flags=0x%x flg=%d pos=(%d,%d) clip=(%d,%d,%d,%d) str=\"%.40s\"", - _frame, fontId, color, (int)flg, (int)flg, pos_x, pos_y, left, top, width, height, str); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2HandleTextResource: RA2 TRES frame=%d fontId=%d color=%d flags=0x%x pos=(%d,%d) clip=(%d,%d,%d,%d) str=\"%.40s\"", + _frame, fontId, color, (int)flg, pos_x, pos_y, left, top, width, height, str); if (flg & kStyleWordWrap) { Common::Rect clipRect(MAX(0, left), MAX(0, top), MIN(left + width, _width), MIN(top + height, _height)); @@ -533,8 +533,8 @@ void SmushPlayerRebel2::ra2SelectFrameBuffer(int width, int height) { if (_specialBuffer == nullptr) { VirtScreen *vs = &_vm->_virtscr[kMainVirtScreen]; _dst = vs->getPixels(0, 0); - debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Reset _dst to virtual screen for FOBJ %dx%d at (%d,%d) _dst=%p", - width, height, 0, 0, (void*)_dst); + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Reset _dst to virtual screen for FOBJ %dx%d at (%d,%d)", + width, height, 0, 0); } else { // Large frame was in this video, use _specialBuffer for compositing _dst = _specialBuffer; From noreply at scummvm.org Mon Jun 1 09:35:36 2026 From: noreply at scummvm.org (ScummVM-Translations) Date: Mon, 1 Jun 2026 09:35:36 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> e0b2dabb2b974e3e3a59e896e16ae6eb3b95eef7 Message-ID: <20260601093536.AF298700591@ron.scummvm.net> This automated email contains information about 2 new commits which have been pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm . Summary: 5a1c3ff325 I18N: Update translation (Spanish) e0b2dabb2b I18N: Update translation (French) Commit: 5a1c3ff325702fe72f749281a6190fcba6a643df https://github.com/scummvm/scummvm/commit/5a1c3ff325702fe72f749281a6190fcba6a643df Author: IlDucci (pajaroloco_2 at hotmail.com) Date: 2026-06-01T09:35:27Z Commit Message: I18N: Update translation (Spanish) Currently translated at 100.0% (3202 of 3202 strings) Changed paths: po/es_ES.po diff --git a/po/es_ES.po b/po/es_ES.po index db6115d14bf..66eb78584aa 100644 --- a/po/es_ES.po +++ b/po/es_ES.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: ScummVM 1.4.0svn\n" "Report-Msgid-Bugs-To: scummvm-devel at lists.scummvm.org\n" "POT-Creation-Date: 2026-05-31 14:10+0000\n" -"PO-Revision-Date: 2026-05-23 21:54+0000\n" +"PO-Revision-Date: 2026-06-01 09:35+0000\n" "Last-Translator: IlDucci \n" "Language-Team: Spanish \n" @@ -13676,21 +13676,18 @@ msgid "Enable ambience sounds." msgstr "Activa los sonidos ambientales." #: engines/scumm/metaengine.cpp:882 -#, fuzzy -#| msgctxt "Options menu" -#| msgid "High resolution on" msgid "High resolution mode" -msgstr "Alta resoluci??n activada" +msgstr "Modo en alta resoluci??n" #: engines/scumm/metaengine.cpp:883 msgid "Run the game in 640x400 high resolution mode instead of 320x200" msgstr "" +"Muestra el juego en el modo de alta resoluci??n a 640??400 p??xeles, en vez de " +"a 320??200" #: engines/scumm/metaengine.cpp:892 -#, fuzzy -#| msgid "All levels will be available to play." msgid "All levels will be available without requiring passwords" -msgstr "Permite el acceso a todos los niveles." +msgstr "Desbloquea todos los niveles sin necesitar contrase??as" #: engines/scumm/metaengine.cpp:1025 msgid "Down left" @@ -13719,75 +13716,59 @@ msgstr "Truco para ganar pelea de motos" #: engines/scumm/metaengine.cpp:1106 msgid "Rebel Assault controls" -msgstr "" +msgstr "Controles de Rebel Assault" #: engines/scumm/metaengine.cpp:1108 engines/scumm/metaengine.cpp:1170 msgid "Aim up / menu up" -msgstr "" +msgstr "Apuntar arriba/Subir men??" #: engines/scumm/metaengine.cpp:1113 engines/scumm/metaengine.cpp:1176 msgid "Aim down / menu down" -msgstr "" +msgstr "Apuntar abajo/Bajar men??" #: engines/scumm/metaengine.cpp:1118 engines/scumm/metaengine.cpp:1182 msgid "Aim left / menu left" -msgstr "" +msgstr "Apuntar a izda./Men?? a izda." #: engines/scumm/metaengine.cpp:1123 engines/scumm/metaengine.cpp:1188 msgid "Aim right / menu right" -msgstr "" +msgstr "Apuntar a dcha./Men?? a dcha." #: engines/scumm/metaengine.cpp:1128 -#, fuzzy -#| msgid "Pick up" msgid "Stick up" -msgstr "Recoger" +msgstr "Stick hacia arriba" #: engines/scumm/metaengine.cpp:1134 -#, fuzzy -#| msgid "Scroll down" msgid "Stick down" -msgstr "Bajar" +msgstr "Stick hacia abajo" #: engines/scumm/metaengine.cpp:1140 -#, fuzzy -#| msgid "Slide left" msgid "Stick left" -msgstr "Deslizarse a la izquierda" +msgstr "Stick hacia la izquierda" #: engines/scumm/metaengine.cpp:1146 -#, fuzzy -#| msgid "Slide right" msgid "Stick right" -msgstr "Deslizarse a la derecha" +msgstr "Stick hacia la derecha" #: engines/scumm/metaengine.cpp:1152 engines/scumm/metaengine.cpp:1194 -#, fuzzy -#| msgid "Move / Select" msgid "Fire / select" -msgstr "Mover/Seleccionar" +msgstr "Disparar/Seleccionar" #: engines/scumm/metaengine.cpp:1157 -#, fuzzy -#| msgid "Backspace" msgid "Back / skip" -msgstr "Retroceso" +msgstr "Volver/Omitir" #: engines/scumm/metaengine.cpp:1168 msgid "Rebel Assault II controls" -msgstr "" +msgstr "Controles de Rebel Assault II" #: engines/scumm/metaengine.cpp:1199 -#, fuzzy -#| msgid "Move back" msgid "Cover / back" -msgstr "Retroceder" +msgstr "Cubrirse/Volver" #: engines/scumm/metaengine.cpp:1204 -#, fuzzy -#| msgid "Skip main menu" msgid "Skip / menu" -msgstr "Omitir men?? principal" +msgstr "Omitir/Men??" #: engines/scumm/saveload.cpp:1990 #, c-format Commit: e0b2dabb2b974e3e3a59e896e16ae6eb3b95eef7 https://github.com/scummvm/scummvm/commit/e0b2dabb2b974e3e3a59e896e16ae6eb3b95eef7 Author: Purple T (ZEONK at hotmail.com) Date: 2026-06-01T09:35:28Z Commit Message: I18N: Update translation (French) Currently translated at 100.0% (3202 of 3202 strings) Changed paths: po/fr_FR.po diff --git a/po/fr_FR.po b/po/fr_FR.po index d4b954e7f30..7f847ed26dc 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: ScummVM 1.8.0git\n" "Report-Msgid-Bugs-To: scummvm-devel at lists.scummvm.org\n" "POT-Creation-Date: 2026-05-31 14:10+0000\n" -"PO-Revision-Date: 2026-05-24 13:22+0000\n" +"PO-Revision-Date: 2026-06-01 09:35+0000\n" "Last-Translator: Purple T \n" "Language-Team: French \n" @@ -13703,21 +13703,16 @@ msgid "Enable ambience sounds." msgstr "Active les sons d'ambiance." #: engines/scumm/metaengine.cpp:882 -#, fuzzy -#| msgctxt "Options menu" -#| msgid "High resolution on" msgid "High resolution mode" -msgstr "Haute r??solution activ??e" +msgstr "Mode Haute r??solution" #: engines/scumm/metaengine.cpp:883 msgid "Run the game in 640x400 high resolution mode instead of 320x200" -msgstr "" +msgstr "Lance le jeu en 640x400 haute r??solution au lieu de 320x200" #: engines/scumm/metaengine.cpp:892 -#, fuzzy -#| msgid "All levels will be available to play." msgid "All levels will be available without requiring passwords" -msgstr "Tous les niveaux seront disponibles." +msgstr "Tous les niveaux seront disponibles sans demander de mots de passe" #: engines/scumm/metaengine.cpp:1025 msgid "Down left" @@ -13746,75 +13741,59 @@ msgstr "Gagner les bagarres en b??cane (cheat)" #: engines/scumm/metaengine.cpp:1106 msgid "Rebel Assault controls" -msgstr "" +msgstr "Contr??les Rebel Assault" #: engines/scumm/metaengine.cpp:1108 engines/scumm/metaengine.cpp:1170 msgid "Aim up / menu up" -msgstr "" +msgstr "Vis??e haut / Menu haut" #: engines/scumm/metaengine.cpp:1113 engines/scumm/metaengine.cpp:1176 msgid "Aim down / menu down" -msgstr "" +msgstr "Vis??e bas / Menu bas" #: engines/scumm/metaengine.cpp:1118 engines/scumm/metaengine.cpp:1182 msgid "Aim left / menu left" -msgstr "" +msgstr "Vis??e gauche / menu gauche" #: engines/scumm/metaengine.cpp:1123 engines/scumm/metaengine.cpp:1188 msgid "Aim right / menu right" -msgstr "" +msgstr "Vis??e droite / Menu droite" #: engines/scumm/metaengine.cpp:1128 -#, fuzzy -#| msgid "Pick up" msgid "Stick up" -msgstr "Prendre" +msgstr "Manche haut" #: engines/scumm/metaengine.cpp:1134 -#, fuzzy -#| msgid "Scroll down" msgid "Stick down" -msgstr "D??filer vers le bas" +msgstr "Manche bas" #: engines/scumm/metaengine.cpp:1140 -#, fuzzy -#| msgid "Slide left" msgid "Stick left" -msgstr "Faire un pas vers la gauche" +msgstr "Manche gauche" #: engines/scumm/metaengine.cpp:1146 -#, fuzzy -#| msgid "Slide right" msgid "Stick right" -msgstr "Faire un pas vers la droite" +msgstr "Manche droite" #: engines/scumm/metaengine.cpp:1152 engines/scumm/metaengine.cpp:1194 -#, fuzzy -#| msgid "Move / Select" msgid "Fire / select" -msgstr "Se d??placer / S??lectionner" +msgstr "Tirer / S??lectionner" #: engines/scumm/metaengine.cpp:1157 -#, fuzzy -#| msgid "Backspace" msgid "Back / skip" -msgstr "Retour arri??re" +msgstr "Retour / passer" #: engines/scumm/metaengine.cpp:1168 msgid "Rebel Assault II controls" -msgstr "" +msgstr "Contr??les Rebel Assault II" #: engines/scumm/metaengine.cpp:1199 -#, fuzzy -#| msgid "Move back" msgid "Cover / back" -msgstr "Reculer" +msgstr "Couverture / retour" #: engines/scumm/metaengine.cpp:1204 -#, fuzzy -#| msgid "Skip main menu" msgid "Skip / menu" -msgstr "Passer le menu principal" +msgstr "Passer / menu" #: engines/scumm/saveload.cpp:1990 #, c-format From noreply at scummvm.org Mon Jun 1 09:40:30 2026 From: noreply at scummvm.org (mduggan) Date: Mon, 1 Jun 2026 09:40:30 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> ae8c870dea59928e37df83e5259239e2261c6528 Message-ID: <20260601094030.AEC01700591@ron.scummvm.net> 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: ae8c870dea ACCESS: Fix sfx number for comic viewer Commit: ae8c870dea59928e37df83e5259239e2261c6528 https://github.com/scummvm/scummvm/commit/ae8c870dea59928e37df83e5259239e2261c6528 Author: Matthew Duggan (mgithub at guarana.org) Date: 2026-06-01T19:39:55+10:00 Commit Message: ACCESS: Fix sfx number for comic viewer Don't overwrite active room sfx, only add them to the end. This fixes a crash if you clicked on something that plays sfx in the initial comic. Changed paths: engines/access/noctropolis/noctropolis_comicviewer.cpp engines/access/sound.cpp engines/access/sound.h diff --git a/engines/access/noctropolis/noctropolis_comicviewer.cpp b/engines/access/noctropolis/noctropolis_comicviewer.cpp index b47601a5a32..c099bea5a6a 100644 --- a/engines/access/noctropolis/noctropolis_comicviewer.cpp +++ b/engines/access/noctropolis/noctropolis_comicviewer.cpp @@ -78,7 +78,7 @@ PageResult ComicViewer::runPage(const ComicPage *page) { _bubbleSprites = new SpriteResource(_vm, bubbleData); delete bubbleData; - bool playedSound = false; + int loadedSoundIdx = -1; while (result == kPageResultNone) { _vm->_events->pollEvents(); @@ -128,11 +128,12 @@ PageResult ComicViewer::runPage(const ComicPage *page) { const ComicBlock &hotspot = page->blocks[hotspotIndex]; if (hotspot.soundFileIndex >= 0) { - _vm->_sound->loadSoundTable(1, hotspot.soundFileIndex, hotspot.soundResIndex); - _vm->_sound->playSound(1); - playedSound = true; + if (loadedSoundIdx >= 0) + _vm->_sound->freeSound(loadedSoundIdx); + loadedSoundIdx = _vm->_sound->loadAndAddSound(hotspot.soundFileIndex, hotspot.soundResIndex); + _vm->_sound->playSound(loadedSoundIdx); } - // TODO: Play hotspot sound + for (int bubbleIndex = 0; bubbleIndex < hotspot.numBoxes; bubbleIndex++) { const ComicBox &bubble = hotspot.boxes[bubbleIndex]; // Slightly lazy, just save/restore whole screen when @@ -157,9 +158,8 @@ PageResult ComicViewer::runPage(const ComicPage *page) { } } - if (playedSound) { - _vm->_sound->freeSound(1); - } + if (loadedSoundIdx >= 0) + _vm->_sound->freeSound(loadedSoundIdx); delete _bubbleSprites; diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp index 0f7f4dc861a..b54bb14c776 100644 --- a/engines/access/sound.cpp +++ b/engines/access/sound.cpp @@ -84,13 +84,14 @@ void SoundManager::loadSoundTable(int idx, int fileNum, int subfile, int priorit _soundTable[idx] = SoundEntry(soundResource, priority, fileNum, subfile); } -void SoundManager::loadAndAddSound(const FileIdent &ident, int priority) { - loadAndAddSound(ident._fileNum, ident._subFile); +int SoundManager::loadAndAddSound(const FileIdent &ident, int priority) { + return loadAndAddSound(ident._fileNum, ident._subFile); } -void SoundManager::loadAndAddSound(int fileNum, int subfile, int priority) { +int SoundManager::loadAndAddSound(int fileNum, int subfile, int priority) { Resource *res = _vm->_files->loadFile(fileNum, subfile); _soundTable.push_back(SoundEntry(res, priority, fileNum, subfile)); + return _soundTable.size() - 1; } bool SoundManager::hasLoadedSound(const FileIdent &ident) const { @@ -107,7 +108,10 @@ void SoundManager::freeSound(int idx) { stopSound(); assert(!isSoundQueued(idx)); delete _soundTable[idx]._res; - _soundTable[idx] = SoundEntry(); + if (idx == (int)_soundTable.size() - 1) + _soundTable.pop_back(); + else + _soundTable[idx] = SoundEntry(); } void SoundManager::playSound(int soundIndex, bool loop /* = false */) { diff --git a/engines/access/sound.h b/engines/access/sound.h index 61ab0d74c85..739d5c8a59e 100644 --- a/engines/access/sound.h +++ b/engines/access/sound.h @@ -79,8 +79,8 @@ public: void loadSoundTable(int idx, int fileNum, int subfile, int priority = 1); // load and add a single sound resource to the table - void loadAndAddSound(int fileNum, int subfile, int priority = 1); - void loadAndAddSound(const FileIdent &ident, int priority = 1); + int loadAndAddSound(int fileNum, int subfile, int priority = 1); + int loadAndAddSound(const FileIdent &ident, int priority = 1); bool hasLoadedSound(const FileIdent &ident) const; From noreply at scummvm.org Mon Jun 1 11:15:59 2026 From: noreply at scummvm.org (neuromancer) Date: Mon, 1 Jun 2026 11:15:59 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> c4980b5fc133e82742b50b85e8f2810131f0a12d Message-ID: <20260601111559.A093D700591@ron.scummvm.net> 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: fd84ee8ad9 SCUMM: RA1: allow mouse navigation in menus 3143a91c42 SCUMM: RA1: honor subtitles config c4980b5fc1 SCUMM: RA2: honor subtitles config Commit: fd84ee8ad906ab655792c72a9da6b58ba1ab039c https://github.com/scummvm/scummvm/commit/fd84ee8ad906ab655792c72a9da6b58ba1ab039c Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T13:15:46+02:00 Commit Message: SCUMM: RA1: allow mouse navigation in menus Changed paths: engines/scumm/insane/rebel1/menu.cpp engines/scumm/insane/rebel1/rebel.h diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp index cf8a11e568a..35ecd26bc26 100644 --- a/engines/scumm/insane/rebel1/menu.cpp +++ b/engines/scumm/insane/rebel1/menu.cpp @@ -26,6 +26,8 @@ #include "audio/mixer.h" +#include "graphics/cursorman.h" + #include "scumm/scumm_v7.h" #include "scumm/smush/smush_player.h" #include "scumm/insane/rebel1/rebel.h" @@ -43,6 +45,14 @@ const int kRA1MenuFrameW = 0xdc; const int kRA1MenuFrameH = 0x0f; const int kRA1MenuRowH = 0x0f; const byte kRA1MenuFrameColor = 0xdf; +// Highlight-frame geometry shared by the render*Overlay drawing and the mouse hit-testing +// (clicking menu items is a ScummVM-exclusive feature, so the rects must stay in sync). +const int kRA1MainMenuFrameYBase = 0x2c; // frame Y = (item + 1) * kRA1MenuRowH + this +const int kRA1OptionsFrameYBase = 0x1d; // frame Y = (item + 1) * kRA1MenuRowH + this +const int kRA1LevelSelectFrameYBase = 0x2c; // frame Y = row * kRA1MenuRowH + this +const int kRA1LevelSelectLeftX = 20; +const int kRA1LevelSelectRightX = 170; +const int kRA1LevelSelectColW = 130; const uint32 kRA1JoystickAxisEscGuardMs = 250; // Original picker traversal uses fixed max indices, not strlen(): passcodes // stop at 0x1d and high-score names stop at 0x37. @@ -496,6 +506,70 @@ bool InsaneRebel1::handleControllerMenuAxis(int16 oldAxisX, int16 oldAxisY) { return false; } +// ScummVM-exclusive feature (not in the original game): let the player navigate and +// activate the front-end menus with the mouse. Hovering highlights an item and a left +// click activates it (same as pressing accept). The item hit-rectangles mirror the +// highlight frames drawn by the render*Overlay() functions, so they share the +// kRA1*FrameYBase / kRA1LevelSelect* geometry constants. Returns true if consumed. +bool InsaneRebel1::handleMenuMouse(const Common::Event &event) { + if (!_menuActive || _textEntryActive || _highScoresActive) + return false; + if (event.type != Common::EVENT_MOUSEMOVE && event.type != Common::EVENT_LBUTTONDOWN) + return false; + + const int mx = event.mouse.x; + const int my = event.mouse.y; + int *selection = nullptr; + int hit = -1; + + if (_levelSelectActive) { + selection = &_levelSelectSel; + for (int i = 0; i < kRA1LevelSelectItemCount; i++) { + const int col = i / kRA1LevelSelectRowsPerCol; + const int row = i % kRA1LevelSelectRowsPerCol; + const int frameX = (col == 0) ? kRA1LevelSelectLeftX : kRA1LevelSelectRightX; + const int frameY = row * kRA1MenuRowH + kRA1LevelSelectFrameYBase; + if (mx >= frameX && mx < frameX + kRA1LevelSelectColW && + my >= frameY && my < frameY + kRA1MenuFrameH) { + hit = i; + break; + } + } + } else if (_optionsActive) { + selection = &_optionsSel; + for (int i = 0; i < kOptionsItemCount; i++) { + const int frameY = (i + 1) * kRA1MenuRowH + kRA1OptionsFrameYBase; + if (mx >= kRA1MenuFrameX && mx < kRA1MenuFrameX + kRA1MenuFrameW && + my >= frameY && my < frameY + kRA1MenuFrameH) { + hit = i; + break; + } + } + } else { + selection = &_menuSelection; + for (int i = 0; i < kRA1MainMenuItemCount; i++) { + const int frameY = (i + 1) * kRA1MenuRowH + kRA1MainMenuFrameYBase; + if (mx >= kRA1MenuFrameX && mx < kRA1MenuFrameX + kRA1MenuFrameW && + my >= frameY && my < frameY + kRA1MenuFrameH) { + hit = i; + break; + } + } + } + + if (hit < 0) + return false; + + _activeInputSource = kInputSourceMouse; + *selection = hit; + + // A left click activates the hovered item, just like pressing accept. + if (event.type == Common::EVENT_LBUTTONDOWN) + handleMenuCommand(kRA1MenuCommandAccept); + + return true; +} + bool InsaneRebel1::notifyEvent(const Common::Event &event) { // Global ScummVM dialogs pause the engine while their modal event loop runs. // Do not consume those mouse/key events as RA1 gameplay/menu input, or the @@ -507,6 +581,10 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { _activeInputSource = kInputSourceMouse; } + // ScummVM-exclusive feature: mouse navigation/clicking of the RA1 front-end menus. + if (handleMenuMouse(event)) + return true; + if (event.type == Common::EVENT_JOYAXIS_MOTION) { _lastJoystickAxisEventTime = _vm->_system->getMillis(); debugC(DEBUG_INSANE, "RA1 input raw-joy-axis: axis=%d pos=%d menu=%d gameplay=%d storedAxis=(%d,%d)", @@ -772,7 +850,7 @@ void InsaneRebel1::renderOptionsOverlay(byte *dst, int pitch, int width, int hei if (i == _optionsSel) drawRebel1MenuFrame(dst, pitch, width, height, - kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + 0x1d, kRA1MenuFrameW); + kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + kRA1OptionsFrameYBase, kRA1MenuFrameW); } } @@ -801,9 +879,9 @@ void InsaneRebel1::renderLevelSelectOverlay(byte *dst, int pitch, int width, int }; const int menuY = 0x2d; - const int leftFrameX = 20; - const int rightFrameX = 170; - const int columnW = 130; + const int leftFrameX = kRA1LevelSelectLeftX; + const int rightFrameX = kRA1LevelSelectRightX; + const int columnW = kRA1LevelSelectColW; for (int i = 0; i < kRA1LevelSelectItemCount; i++) { const int col = i / kRA1LevelSelectRowsPerCol; @@ -817,7 +895,7 @@ void InsaneRebel1::renderLevelSelectOverlay(byte *dst, int pitch, int width, int if (i == _levelSelectSel) drawRebel1MenuFrame(dst, pitch, width, height, - frameX, row * kRA1MenuRowH + 0x2c, columnW); + frameX, row * kRA1MenuRowH + kRA1LevelSelectFrameYBase, columnW); } } @@ -847,13 +925,20 @@ void InsaneRebel1::renderMainMenuItems(byte *dst, int pitch, int width, int heig if (i == _menuSelection) drawRebel1MenuFrame(dst, pitch, width, height, - kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + 0x2c, kRA1MenuFrameW); + kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + kRA1MainMenuFrameYBase, kRA1MenuFrameW); } } void InsaneRebel1::renderMainMenuOverlay(byte *dst, int pitch, int width, int height) { _menuFrameCounter++; + // ScummVM-exclusive feature: the menus are mouse-clickable, so keep the default + // arrow cursor visible. SmushPlayer::play() hides the system cursor for the whole + // video (and re-hides it every video), so re-assert visibility each rendered frame + // while a menu overlay is on screen. The arrow bitmap/palette is set in + // playMenuBackground(); gameplay hides it again via captureInteractiveVideoInput(). + CursorMan.showMouse(true); + if (_textEntryActive) { renderTextEntryOverlay(dst, pitch, width, height); return; @@ -913,6 +998,12 @@ void InsaneRebel1::playMenuBackground() { _menuActive = true; _menuConfirmed = false; _menuFrameCounter = 0; + // Show ScummVM's built-in arrow pointer for the (mouse-clickable) menus. Set it once + // here; renderMainMenuOverlay() re-asserts showMouse() each frame because the SMUSH + // player forces the cursor off while a video plays. disableCursorPalette(false) ensures + // the arrow's own CLUT palette is used rather than the game palette. + CursorMan.disableCursorPalette(false); + CursorMan.setDefaultArrowCursor(); clearVideoBuffer(); playCinematic("OPEN/O1OPTION.ANM"); _menuActive = false; diff --git a/engines/scumm/insane/rebel1/rebel.h b/engines/scumm/insane/rebel1/rebel.h index 22f93bd3e49..8bedfdff0e0 100644 --- a/engines/scumm/insane/rebel1/rebel.h +++ b/engines/scumm/insane/rebel1/rebel.h @@ -529,6 +529,8 @@ private: bool handleMenuCommand(RA1MenuCommand command); bool handleControllerMenuAction(ScummAction action); bool handleControllerMenuAxis(int16 oldAxisX, int16 oldAxisY); + // ScummVM-exclusive feature: navigate/click the menus with the mouse. + bool handleMenuMouse(const Common::Event &event); bool handleTextEntryAction(ScummAction action); bool handleTextEntryKey(const Common::Event &event); void playMenuBackground(); Commit: 3143a91c420e08db3fb020ff1d7de0c159b80b3c https://github.com/scummvm/scummvm/commit/3143a91c420e08db3fb020ff1d7de0c159b80b3c Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T13:15:46+02:00 Commit Message: SCUMM: RA1: honor subtitles config Changed paths: engines/scumm/insane/rebel1/rebel.cpp engines/scumm/smush/rebel/smush_player_ra1.cpp diff --git a/engines/scumm/insane/rebel1/rebel.cpp b/engines/scumm/insane/rebel1/rebel.cpp index af3ecab61c7..9b4a89b174f 100644 --- a/engines/scumm/insane/rebel1/rebel.cpp +++ b/engines/scumm/insane/rebel1/rebel.cpp @@ -19,6 +19,7 @@ * */ +#include "common/config-manager.h" #include "common/system.h" #include "common/events.h" #include "common/endian.h" @@ -343,7 +344,10 @@ InsaneRebel1::InsaneRebel1(ScummEngine_v7 *scumm) : Insane(), _vm(scumm) { _optRookieOneFemale = false; _optMusicEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kMusicSoundType); _optSfxEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kSFXSoundType); - _optTextEnabled = true; + // Initialize the dialogue-text (subtitles) toggle from ScummVM's global setting so the + // game and the in-game DIALOGUE TEXT menu label reflect it. The menu toggle writes the + // same "subtitles" key, and ra1HandleText() gates rendering on it. + _optTextEnabled = ConfMan.getBool("subtitles"); _optEnhancedControls = true; _optControlsYFlip = false; _optVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType) * 127 / Audio::Mixer::kMaxChannelVolume; diff --git a/engines/scumm/smush/rebel/smush_player_ra1.cpp b/engines/scumm/smush/rebel/smush_player_ra1.cpp index 6c6712b787c..aa213b17a65 100644 --- a/engines/scumm/smush/rebel/smush_player_ra1.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra1.cpp @@ -24,6 +24,7 @@ // Keep these in a dedicated file so the shared smush_player.cpp stays close // to upstream while RA1 behavior is isolated in one place. +#include "common/config-manager.h" #include "common/endian.h" #include "common/memstream.h" @@ -320,7 +321,13 @@ bool SmushPlayerRebel1::handleGameTextResource(uint32 subType, int32 subSize, Co if (subType != MKTAG('T','E','X','T')) return false; - ra1HandleText(subSize, b); + // RA1 dialogue subtitles. Only render them when subtitles are enabled ??? this honors + // both ScummVM's global "subtitles" setting and the in-game DIALOGUE TEXT toggle + // (which writes the same ConfMan key). Still return true so the base handler doesn't + // try to parse RA1's custom TEXT format. Querying ConfMan per chunk also lets the + // setting take effect mid-video. + if (ConfMan.getBool("subtitles")) + ra1HandleText(subSize, b); return true; } Commit: c4980b5fc133e82742b50b85e8f2810131f0a12d https://github.com/scummvm/scummvm/commit/c4980b5fc133e82742b50b85e8f2810131f0a12d Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T13:15:46+02:00 Commit Message: SCUMM: RA2: honor subtitles config Changed paths: engines/scumm/insane/rebel2/iact.cpp engines/scumm/insane/rebel2/menu.cpp engines/scumm/insane/rebel2/rebel.cpp engines/scumm/smush/rebel/smush_player_ra2.cpp diff --git a/engines/scumm/insane/rebel2/iact.cpp b/engines/scumm/insane/rebel2/iact.cpp index fd69da34581..114ecc49136 100644 --- a/engines/scumm/insane/rebel2/iact.cpp +++ b/engines/scumm/insane/rebel2/iact.cpp @@ -19,6 +19,7 @@ * */ +#include "common/config-manager.h" #include "common/system.h" #include "common/memstream.h" #include "common/util.h" @@ -2510,13 +2511,18 @@ void InsaneRebel2::iactRebel2Opcode9(byte *renderBitmap, Common::SeekableReadStr } convertedText[dstIdx] = '\0'; - // Draw the text string (with converted character indices) - if (textFlags & 0x04) { - // Word-wrapped text - _rebelMsgFont->drawStringWrap(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags); - } else { - // Single-line text - _rebelMsgFont->drawString(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags); + // Draw the text string (with converted character indices), but only when subtitles are + // enabled ??? opcode 9 is a subtitle/message path, so it honors ScummVM's global + // "subtitles" setting and the in-game TEXT toggle (same ConfMan key). The chunk is + // still fully parsed above so stream consumption is unaffected. + if (ConfMan.getBool("subtitles")) { + if (textFlags & 0x04) { + // Word-wrapped text + _rebelMsgFont->drawStringWrap(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags); + } else { + // Single-line text + _rebelMsgFont->drawString(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags); + } } debug("Rebel2 Opcode 9: Rendered subtitle at (%d,%d) flags=0x%x clip=(%d,%d,%d,%d)", diff --git a/engines/scumm/insane/rebel2/menu.cpp b/engines/scumm/insane/rebel2/menu.cpp index ffe9ccdb0cf..8dfdd0cac36 100644 --- a/engines/scumm/insane/rebel2/menu.cpp +++ b/engines/scumm/insane/rebel2/menu.cpp @@ -19,6 +19,7 @@ * */ +#include "common/config-manager.h" #include "common/system.h" #include "common/events.h" #include "common/util.h" @@ -1797,6 +1798,7 @@ int InsaneRebel2::processOptionsInput() { break; case 3: // Text toggle _optTextEnabled = !_optTextEnabled; + ConfMan.setBool("subtitles", _optTextEnabled); break; case 4: // Controls toggle _optControlsFlipped = !_optControlsFlipped; diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp index ba9e1b5ed92..c843a74296b 100644 --- a/engines/scumm/insane/rebel2/rebel.cpp +++ b/engines/scumm/insane/rebel2/rebel.cpp @@ -454,7 +454,10 @@ InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) { _optMusicEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kMusicSoundType); _optSfxEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kSFXSoundType); _optVoicesEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kSpeechSoundType); - _optTextEnabled = true; + // Initialize the dialogue-text (subtitles) toggle from ScummVM's global setting so the + // game and the in-game TEXT menu label reflect it. The menu toggle writes the same + // "subtitles" key, which the text-render paths gate on. + _optTextEnabled = ConfMan.getBool("subtitles"); _optControlsFlipped = false; _optRapidFire = false; _optVolumeLevel = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2; diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp index dc0ffb3b21b..1299f5034b0 100644 --- a/engines/scumm/smush/rebel/smush_player_ra2.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp @@ -24,6 +24,7 @@ // Overrides the virtual hooks defined in SmushPlayer to provide // Rebel Assault 2 specific video, font, text and codec handling. +#include "common/config-manager.h" #include "common/endian.h" #include "common/rect.h" #include "common/system.h" @@ -189,7 +190,12 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea bool SmushPlayerRebel2::handleGameTextRendering(const char *str, int fontId, int color, int pos_x, int pos_y, int left, int top, int width, int height, TextStyleFlags flg) { - ra2HandleTextResource(str, fontId, color, pos_x, pos_y, left, top, width, height, flg); + // RA2 dialogue subtitles. Only render them when subtitles are enabled ??? this honors + // both ScummVM's global "subtitles" setting and the in-game TEXT toggle (which writes + // the same ConfMan key). Still return true so the base handler treats the chunk as + // handled. Querying ConfMan per chunk also lets the setting take effect mid-video. + if (ConfMan.getBool("subtitles")) + ra2HandleTextResource(str, fontId, color, pos_x, pos_y, left, top, width, height, flg); return true; } From noreply at scummvm.org Mon Jun 1 14:35:04 2026 From: noreply at scummvm.org (neuromancer) Date: Mon, 1 Jun 2026 14:35:04 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> 793b12545ac64040201408a037438c2525579849 Message-ID: <20260601143504.4FD3F700591@ron.scummvm.net> This automated email contains information about 5 new commits which have been pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm . Summary: 06333e5f71 SCUMM: RA1: make it touchpad friendly 790e05d816 SCUMM: RA2: fixed invalid palette handling in L2 ec305dee37 SCUMM: RA2: improved gamepad support 0025c4e108 SCUMM: RA2: match the joytick/gamepad input speed 793b12545a SCUMM: RA2: make sure input starts centered Commit: 06333e5f71e11b2a9e9b332c2c42a89e87ed69a1 https://github.com/scummvm/scummvm/commit/06333e5f71e11b2a9e9b332c2c42a89e87ed69a1 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T13:46:31+02:00 Commit Message: SCUMM: RA1: make it touchpad friendly Changed paths: engines/scumm/insane/rebel1/iact.cpp engines/scumm/insane/rebel1/menu.cpp engines/scumm/insane/rebel1/rebel.cpp engines/scumm/insane/rebel1/rebel.h engines/scumm/insane/rebel1/runlevels.cpp diff --git a/engines/scumm/insane/rebel1/iact.cpp b/engines/scumm/insane/rebel1/iact.cpp index 68b0e2afac4..f3d2a507789 100644 --- a/engines/scumm/insane/rebel1/iact.cpp +++ b/engines/scumm/insane/rebel1/iact.cpp @@ -857,6 +857,16 @@ void InsaneRebel1::preprocessMouseAxes(int16 &inputX, int16 &inputY, bool *usedJ return; } + // On touchscreen devices aiming comes from the on-screen gamepad (joystick), never the + // absolute touch/cursor position; and we must not recenter the system cursor + // (smush_warpMouse below), which would inject spurious motion and drift the reticle. + if (isTouchscreenActive()) { + inputX = 0; + inputY = 0; + _mouseVirtualValid = false; + return; + } + int16 logicalX = (int16)CLIP(_vm->_mouse.x, 0, 319); int16 logicalY = (int16)CLIP(_vm->_mouse.y, 0, 199); diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp index 35ecd26bc26..0dbc31baf07 100644 --- a/engines/scumm/insane/rebel1/menu.cpp +++ b/engines/scumm/insane/rebel1/menu.cpp @@ -577,7 +577,9 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) { if (_vm->isPaused()) return false; - if (event.type == Common::EVENT_MOUSEMOVE && !_mouseRecentering) { + // On touchscreen devices, finger drags arrive as mouse-move events; do not let them + // hijack RA1 into absolute-cursor aiming (aiming there comes from the on-screen gamepad). + if (event.type == Common::EVENT_MOUSEMOVE && !_mouseRecentering && !isTouchscreenActive()) { _activeInputSource = kInputSourceMouse; } diff --git a/engines/scumm/insane/rebel1/rebel.cpp b/engines/scumm/insane/rebel1/rebel.cpp index 9b4a89b174f..8341fa0c1cd 100644 --- a/engines/scumm/insane/rebel1/rebel.cpp +++ b/engines/scumm/insane/rebel1/rebel.cpp @@ -200,6 +200,10 @@ void InsaneRebel1::loadTuningForLevel(int level) { _tuning.time, _tuning.levelPts, _tuning.bonus, _tuning.flags); } +bool InsaneRebel1::isTouchscreenActive() const { + return g_system->hasFeature(OSystem::kFeatureTouchscreen); +} + void InsaneRebel1::resetGameplayFlagsFromTuning() { const uint16 tuningFlags = (uint16)_tuning.flags; _gameplayFlags75fe = tuningFlags & 0x00FF; diff --git a/engines/scumm/insane/rebel1/rebel.h b/engines/scumm/insane/rebel1/rebel.h index 8bedfdff0e0..0b7d2da299b 100644 --- a/engines/scumm/insane/rebel1/rebel.h +++ b/engines/scumm/insane/rebel1/rebel.h @@ -105,6 +105,10 @@ public: void handleGameChunk(int32 subSize, Common::SeekableReadStream &b); bool isInteractiveVideoActive() const { return _interactiveVideoActive; } + // True on touchscreen devices (e.g. Android). RA1 then aims from the on-screen gamepad + // joystick instead of the DOS absolute-mouse model, and skips cursor warping/locking, + // which otherwise inject spurious motion that drifts the reticle and on-screen buttons. + bool isTouchscreenActive() const; void setFrameHasGameChunk(bool hasGameChunk) { _frameHasGameChunk = hasGameChunk; } int getCurrentLevel() const { return _currentLevel; } uint16 getActiveGameOpcode() const { return _activeGameOpcode; } diff --git a/engines/scumm/insane/rebel1/runlevels.cpp b/engines/scumm/insane/rebel1/runlevels.cpp index cb9c68b8058..f1d67c8e49b 100644 --- a/engines/scumm/insane/rebel1/runlevels.cpp +++ b/engines/scumm/insane/rebel1/runlevels.cpp @@ -1636,7 +1636,11 @@ void InsaneRebel1::captureInteractiveVideoInput() { // Level 7 route splices happen inside one original gameplay loop, so keep // the current input state instead of recentering between route clips. if (!level7RouteSplice) { - smush_warpMouse(160, 100, -1); + // On touchscreen devices the DOS recenter-the-cursor aiming model does not apply + // (aiming uses the on-screen gamepad); warping/locking the system mouse there only + // injects spurious motion that drifts the reticle and on-screen buttons. + if (!isTouchscreenActive()) + smush_warpMouse(160, 100, -1); _mouseVirtualRawX = 0x140; _mouseVirtualRawY = 100; _mouseVirtualPrevLogicalX = kRA1CenterX; @@ -1644,7 +1648,8 @@ void InsaneRebel1::captureInteractiveVideoInput() { _mouseVirtualValid = false; } CursorMan.showMouse(false); - g_system->lockMouse(true); + if (!isTouchscreenActive()) + g_system->lockMouse(true); } void InsaneRebel1::releaseInteractiveVideoInput() { Commit: 790e05d8162689cbf73cb223a32bf9a912a87bc8 https://github.com/scummvm/scummvm/commit/790e05d8162689cbf73cb223a32bf9a912a87bc8 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T14:36:44+02:00 Commit Message: SCUMM: RA2: fixed invalid palette handling in L2 Changed paths: engines/scumm/insane/rebel2/iact.cpp engines/scumm/insane/rebel2/render.cpp engines/scumm/insane/rebel2/runlevels.cpp engines/scumm/smush/rebel/smush_player_ra2.cpp engines/scumm/smush/rebel/smush_player_ra2.h engines/scumm/smush/smush_player.cpp engines/scumm/smush/smush_player.h diff --git a/engines/scumm/insane/rebel2/iact.cpp b/engines/scumm/insane/rebel2/iact.cpp index 114ecc49136..2ed784f0480 100644 --- a/engines/scumm/insane/rebel2/iact.cpp +++ b/engines/scumm/insane/rebel2/iact.cpp @@ -74,7 +74,7 @@ void InsaneRebel2::procPreRendering(byte *renderBitmap) { _rebelOp6Initialized = false; } - // For Level 2 gameplay (Handler 8 only), restore the background BEFORE FOBJ decoding. + // For Level 2 handler 8 gameplay, restore the background BEFORE FOBJ decoding. // The tiny FOBJ sprites (7x10, 9x38 pixels) only draw new sprite positions but don't // clear old ones. By restoring the full background each frame, we ensure old sprite // positions are erased before new ones are drawn. @@ -2267,10 +2267,9 @@ bool InsaneRebel2::loadLevel2Background(byte *animData, int32 size, byte *render _level2BackgroundLoaded = true; foundBackground = true; - // Copy to render bitmap immediately if provided. - // Only copy when render buffer pitch is 320 (standard screen size). - // For oversized buffers, the FOBJ/FETCH system handles background rendering. - if (renderBitmap) { + // Handler 25 uses this buffer as a lookup mask; the retail code does not + // copy it to the live screen. Handler 8 still uses it as a restore source. + if (renderBitmap && _rebelHandler != 25) { int bufferPitch = (_player && _player->_width > 0) ? _player->_width : 320; if (bufferPitch == 320) { for (int by = 0; by < 200; by++) { diff --git a/engines/scumm/insane/rebel2/render.cpp b/engines/scumm/insane/rebel2/render.cpp index e9b35a408b6..c93f1c24aa0 100644 --- a/engines/scumm/insane/rebel2/render.cpp +++ b/engines/scumm/insane/rebel2/render.cpp @@ -2339,11 +2339,9 @@ void InsaneRebel2::renderGameplayPostFrame(byte *renderBitmap, int pitch, int wi // Original: FUN_00403240 only runs handlers when DAT_0047a814 == 0. processMouse(); - // NOTE: Level 2 background is drawn ONCE during IACT opcode 8 par4=5 processing - // (in procIACT when the background ANIM is first loaded). The 0x08 video flag - // (preserve background) prevents the frame buffer from being cleared, so the - // background persists. FOBJ sprites (enemies) are then decoded on top by SMUSH. - // We do NOT redraw the background here as that would overwrite FOBJ content. + // NOTE: Level 2 handler 8's background is restored in procPreRendering before + // SMUSH decodes the frame's FOBJ sprites. Handler 25 draws its corridor overlay + // from IACT opcode 6 instead. Redrawing either here would overwrite enemies. // --- HUD Drawing Order (from FUN_004089ab / FUN_40D836 assembly analysis) --- // Original assembly render order for handler 0x26: diff --git a/engines/scumm/insane/rebel2/runlevels.cpp b/engines/scumm/insane/rebel2/runlevels.cpp index 93a763db401..673a67def8a 100644 --- a/engines/scumm/insane/rebel2/runlevels.cpp +++ b/engines/scumm/insane/rebel2/runlevels.cpp @@ -235,6 +235,9 @@ void InsaneRebel2::resetLevelAttemptState(int initialPhase) { _playerShield = 255; _playerDamage = 0; _currentPhase = initialPhase; + resetDamageFlash(); + _damageHighFlashCounter = 0; + _damageShakeCounter = 0; _rebelAutopilot = 0; _rebelDamageLevel = 0; @@ -253,6 +256,28 @@ void InsaneRebel2::resetLevelPhaseState(bool clearEnemies) { _rebelHitCounter = 0; resetLevelWaveState(); + delete _grd001Sprite; + _grd001Sprite = nullptr; + delete _grd002Sprite; + _grd002Sprite = nullptr; + _grdShotOriginTableLoaded = false; + + static const int handler25FrameSlots[] = { 4, 6, 7, 10, 12, 13 }; + for (uint i = 0; i < ARRAYSIZE(handler25FrameSlots); ++i) { + EmbeddedSanFrame &frame = _rebelEmbeddedHud[handler25FrameSlots[i]]; + free(frame.pixels); + frame.pixels = nullptr; + frame.width = 0; + frame.height = 0; + frame.renderX = 0; + frame.renderY = 0; + frame.valid = false; + } + + free(_level2Background); + _level2Background = nullptr; + _level2BackgroundLoaded = false; + if (clearEnemies) _enemies.clear(); } diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp index 1299f5034b0..87fb6db2eef 100644 --- a/engines/scumm/smush/rebel/smush_player_ra2.cpp +++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp @@ -387,6 +387,56 @@ void SmushPlayerRebel2::adjustGamePalette() { memset(_deltaPal, 0, sizeof(_deltaPal)); } +bool SmushPlayerRebel2::shouldLoadAnimHeaderPalette() const { + // Original RA2 AHDR handler skips the embedded palette when video flag 0x400 is set. + return (_curVideoFlags & 0x400) == 0; +} + +void SmushPlayerRebel2::ra2HandleDeltaPalette(int32 subSize, Common::SeekableReadStream &b) { + if (subSize < 4) { + b.skip(subSize); + return; + } + + b.readUint16LE(); + const uint16 xpalCommand = b.readUint16LE(); + + if (xpalCommand != 0 && xpalCommand != 512) { + if (subSize > 4) + b.skip(subSize - 4); + + for (int i = 0; i < 768; ++i) { + _shiftedDeltaPal[i] += _deltaPal[i]; + _pal[i] = CLIP(_shiftedDeltaPal[i] >> 7, 0, 255); + } + setDirtyColors(0, 255); + return; + } + + const int32 deltaBytes = 0x300 * 2; + if (subSize < 4 + deltaBytes) { + b.skip(subSize - 4); + return; + } + + int16 deltaPal[0x300]; + for (int i = 0; i < 768; ++i) + deltaPal[i] = b.readSint16LE(); + + if (xpalCommand == 512 && subSize >= 4 + deltaBytes + 0x300) { + b.read(_pal, 0x300); + } else if (subSize > 4 + deltaBytes) { + b.skip(subSize - 4 - deltaBytes); + } + + for (int i = 0; i < 768; ++i) { + _shiftedDeltaPal[i] = _pal[i] << 7; + _deltaPal[i] = deltaPal[i]; + } + + setDirtyColors(0, 255); +} + /** * RA2-specific handleAnimHeader fixup: when AHDR reports 0x0 dimensions, * use screen dimensions instead. @@ -510,18 +560,31 @@ void SmushPlayerRebel2::ra2HandleTextResource(const char *str, int fontId, int c /** * RA2-specific buffer selection for non-standard FOBJ dimensions. - * Returns the destination buffer to use and updates _dst, _width, _height. + * Returns true when the dimensions are valid and updates _dst, _width, _height as needed. */ -void SmushPlayerRebel2::ra2SelectFrameBuffer(int width, int height) { +bool SmushPlayerRebel2::ra2SelectFrameBuffer(int width, int height) { // Rebel2 uses a special buffer for all non-matching frames. // Level 1: First frame is 424x260 (background), small sprites reuse same buffer // Level 2: Uses virtual screen directly (handled below when _specialBuffer stays null) - int bufSize = width * height; - if (bufSize > _vm->_screenWidth * _vm->_screenHeight) { + const int64 bufSize64 = (int64)width * height; + if (width <= 0 || height <= 0 || bufSize64 > INT_MAX) { + debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Skipping invalid FOBJ dimensions %dx%d", width, height); + return false; + } + + const int bufSize = (int)bufSize64; + const int screenSize = _vm->_screenWidth * _vm->_screenHeight; + if (bufSize > screenSize) { // Frame is larger than screen - need special buffer if (_specialBuffer == nullptr || bufSize > _specialBufferSize) { + byte *newSpecialBuffer = (byte *)malloc(bufSize); + if (newSpecialBuffer == nullptr) { + warning("SmushPlayerRebel2::ra2SelectFrameBuffer: Failed to allocate %d bytes for FOBJ %dx%d", + bufSize, width, height); + return false; + } free(_specialBuffer); - _specialBuffer = (byte *)malloc(bufSize); + _specialBuffer = newSpecialBuffer; _specialBufferSize = bufSize; _width = width; _height = height; @@ -531,7 +594,7 @@ void SmushPlayerRebel2::ra2SelectFrameBuffer(int width, int height) { } } - if (bufSize > _vm->_screenWidth * _vm->_screenHeight && + if (bufSize > screenSize && _specialBuffer != nullptr && _specialBufferSize >= bufSize) { _dst = _specialBuffer; debugC(DEBUG_SMUSH, "SmushPlayerRebel2::ra2SelectFrameBuffer: Using _specialBuffer for oversized FOBJ %dx%d", width, height); @@ -548,6 +611,8 @@ void SmushPlayerRebel2::ra2SelectFrameBuffer(int width, int height) { width, height); } } + + return true; } /** @@ -656,8 +721,7 @@ void SmushPlayerRebel2::handleGameParseNextFrame() { bool SmushPlayerRebel2::handleGameFrameBufferSelect(int codec, int width, int height) { if ((height != _vm->_screenHeight) || (width != _vm->_screenWidth)) { - ra2SelectFrameBuffer(width, height); - return true; + return ra2SelectFrameBuffer(width, height); } return false; } @@ -719,6 +783,12 @@ bool SmushPlayerRebel2::handleGameSkipChunk(uint32 subType, int32 subSize, Commo debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameSkipChunk: SKIP consumed chunk %s frame=%d", tag2str(subType), _frame); return true; } + + if (subType == MKTAG('X','P','A','L')) { + ra2HandleDeltaPalette(subSize, b); + return true; + } + return false; } diff --git a/engines/scumm/smush/rebel/smush_player_ra2.h b/engines/scumm/smush/rebel/smush_player_ra2.h index 7af86cf66f0..084a727fb3d 100644 --- a/engines/scumm/smush/rebel/smush_player_ra2.h +++ b/engines/scumm/smush/rebel/smush_player_ra2.h @@ -42,6 +42,7 @@ protected: bool shouldAlwaysShowSubtitles() const override { return true; } SmushFont *getGameFont(int font) override; void adjustGamePalette() override; + bool shouldLoadAnimHeaderPalette() const override; bool handleGameAnimHeader(byte *headerContent) override; bool handleGameSetupStrings() override; void handleGameParseNextFrame() override; @@ -65,9 +66,10 @@ private: void ra2HandleTextResource(const char *str, int fontId, int color, int pos_x, int pos_y, int left, int top, int width, int height, TextStyleFlags flg); - void ra2SelectFrameBuffer(int width, int height); + bool ra2SelectFrameBuffer(int width, int height); bool ra2DecodeCodec(int codec, const uint8 *src, int left, int top, int width, int height, int pitch, int dataSize); + void ra2HandleDeltaPalette(int32 subSize, Common::SeekableReadStream &b); void ra2StoreFobjData(int codec, const byte *data, int32 dataSize, int left, int top, int width, int height); void ra2HandleGost(int32 subSize, Common::SeekableReadStream &b); diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp index 795a90be08f..a6db75dfc8e 100644 --- a/engines/scumm/smush/smush_player.cpp +++ b/engines/scumm/smush/smush_player.cpp @@ -1155,7 +1155,7 @@ void SmushPlayer::handleAnimHeader(int32 subSize, Common::SeekableReadStream &b) } } - if (!_skipPalette) { + if (!_skipPalette && shouldLoadAnimHeaderPalette()) { byte *palettePtr = &headerContent[6]; memcpy(_pal, palettePtr, sizeof(_pal)); adjustGamePalette(); diff --git a/engines/scumm/smush/smush_player.h b/engines/scumm/smush/smush_player.h index 4f967932c5a..a5dc1ff6f79 100644 --- a/engines/scumm/smush/smush_player.h +++ b/engines/scumm/smush/smush_player.h @@ -311,6 +311,7 @@ protected: virtual bool shouldAlwaysShowSubtitles() const { return false; } virtual SmushFont *getGameFont(int font) { return nullptr; } virtual void adjustGamePalette() {} + virtual bool shouldLoadAnimHeaderPalette() const { return true; } virtual bool handleGameAnimHeader(byte *headerContent) { return false; } virtual bool handleGameSetupStrings() { return false; } virtual void handleGameParseNextFrame() {} Commit: ec305dee3713343ba93643eb27ab1d0534f16100 https://github.com/scummvm/scummvm/commit/ec305dee3713343ba93643eb27ab1d0534f16100 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T16:13:54+02:00 Commit Message: SCUMM: RA2: improved gamepad support Changed paths: engines/scumm/insane/rebel2/iact.cpp engines/scumm/insane/rebel2/levels.cpp engines/scumm/insane/rebel2/rebel.cpp engines/scumm/insane/rebel2/rebel.h engines/scumm/metaengine.cpp engines/scumm/scumm.h diff --git a/engines/scumm/insane/rebel2/iact.cpp b/engines/scumm/insane/rebel2/iact.cpp index 2ed784f0480..fe30e70a2dc 100644 --- a/engines/scumm/insane/rebel2/iact.cpp +++ b/engines/scumm/insane/rebel2/iact.cpp @@ -67,6 +67,10 @@ static bool readLevel2BackgroundChunkHeader(Common::SeekableReadStream &stream, void InsaneRebel2::procPreRendering(byte *renderBitmap) { Insane::procPreRendering(renderBitmap); + // Pan the reticle from held directional controls (on-screen/physical gamepad dpad, + // keyboard arrows) once per frame. No-op outside gameplay; mouse aiming is unaffected. + updateGameplayAimFromGamepad(); + // Reset opcode 6 init flag at the start of each new video. // This ensures the per-wave init (clearBit, link table reset, wave state) // fires exactly once per wave video, not every frame. diff --git a/engines/scumm/insane/rebel2/levels.cpp b/engines/scumm/insane/rebel2/levels.cpp index d0d2368c7d7..cef25c6b9e2 100644 --- a/engines/scumm/insane/rebel2/levels.cpp +++ b/engines/scumm/insane/rebel2/levels.cpp @@ -403,6 +403,9 @@ int InsaneRebel2::runLevel(int levelId) { smush_warpMouse(160, 100, -1); CursorMan.showMouse(false); g_system->lockMouse(true); + // Start each level with the centered cursor as the authoritative aim source; + // the first gamepad input reclaims it (see updateGameplayAimFromGamepad). + _gamepadAimActive = false; // Initialize common player state _playerLives = 3; diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp index c843a74296b..a91e46c276c 100644 --- a/engines/scumm/insane/rebel2/rebel.cpp +++ b/engines/scumm/insane/rebel2/rebel.cpp @@ -465,6 +465,13 @@ InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) { // Initialize menu input capture system _menuInputActive = false; + // Analog stick state for gamepad aiming (mirrors RA1's analog model). + // Ingested from EVENT_CUSTOM_BACKEND_ACTION_AXIS, read with a deadzone and + // integrated as velocity into the reticle in updateGameplayAimFromGamepad(). + _joystickAxisX = 0; + _joystickAxisY = 0; + _gamepadAimActive = false; + // Initialize level state tracking for multi-phase levels _currentPhase = 1; _deathFrame = 0; @@ -524,6 +531,67 @@ InsaneRebel2::~InsaneRebel2() { bool InsaneRebel2::notifyEvent(const Common::Event &event) { SmushPlayer *splayer = ((ScummEngine_v7 *)_vm)->_splayer; + // Keep the gamepad reticle authoritative against stray pointer events. During + // gameplay the cursor is locked ~screen-center (levels.cpp lockMouse), so any + // spurious pointer event ??? e.g. a gamepad "fire" surfacing as a button-down ??? + // carries that centered position, and SCUMM's input layer copies it straight + // into _mouse on button-down (scumm/input.cpp), yanking the reticle to center on + // every shot. We observe before ScummEngine (priority 1 > kEventManPriority), so + // dropping the event here prevents the clobber. Firing is driven by the + // kScummActionInsaneAttack action, not the pointer, so this does not affect shots. + // A genuine mouse/touch motion (nonzero relative delta) hands control back. + if (_gamepadAimActive && _gameState == kStateGameplay && !_menuInputActive) { + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + if (event.relMouse.x != 0 || event.relMouse.y != 0) { + _gamepadAimActive = false; // real pointer motion takes over + break; + } + return true; // drop zero-delta artifact (e.g. locked-cursor recentre) + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + return true; // drop stray button-down that would recenter the reticle + // Let LBUTTONUP/RBUTTONUP fall through so the backend _buttonState latch + // always clears and can never stick when a real mouse later takes over. + default: + break; + } + } + + // Analog stick ??? reticle velocity (mirrors RA1's analog model). The mapped + // axis actions carry a signed position; a centered stick reports position 0. + // We ignore a recentre that would fight the opposite direction so a quick + // flick doesn't get cancelled by the trailing zero of the other axis half. + if (event.type == Common::EVENT_CUSTOM_BACKEND_ACTION_AXIS) { + const int16 axisPosition = (event.joystick.position == Common::JOYAXIS_MIN) + ? Common::JOYAXIS_MAX : event.joystick.position; + + switch (event.customType) { + case kScummBackendActionRebel2AxisUp: + if (event.joystick.position == 0 && _joystickAxisY > 0) + return true; + _joystickAxisY = -axisPosition; + return true; + case kScummBackendActionRebel2AxisDown: + if (event.joystick.position == 0 && _joystickAxisY < 0) + return true; + _joystickAxisY = axisPosition; + return true; + case kScummBackendActionRebel2AxisLeft: + if (event.joystick.position == 0 && _joystickAxisX > 0) + return true; + _joystickAxisX = -axisPosition; + return true; + case kScummBackendActionRebel2AxisRight: + if (event.joystick.position == 0 && _joystickAxisX < 0) + return true; + _joystickAxisX = axisPosition; + return true; + default: + break; + } + } + if (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START || event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) { const bool pressed = (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START); @@ -593,10 +661,12 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { } } - if (event.customType == kScummActionInsaneAttack || - event.customType == kScummActionInsaneSwitch) { - return true; - } + // Do NOT consume Attack/Switch during gameplay: like the dpad actions, these + // custom-action events must fall through to ScummEngine::parseEvent() so it keeps + // _actionMap in sync (input.cpp). processMouse() reads getActionState() for the + // gamepad trigger; consuming here breaks the dispatch loop (events.cpp) before the + // map is updated, leaving fire dead. The menu/paused branches above already + // consumed (and returned true for) the cases they handle. } if (event.type == Common::EVENT_KEYDOWN) { @@ -1285,29 +1355,58 @@ int32 InsaneRebel2::processMouse() { } Common::Point InsaneRebel2::getGameplayAimPoint() { - Common::Point aimPos(_vm->_mouse.x, _vm->_mouse.y); + // Pure getter (queried many times per frame): the aim/reticle follows the virtual + // mouse position. Directional controls pan that position incrementally once per frame + // via updateGameplayAimFromGamepad(), rather than snapping the reticle to a screen edge. + return Common::Point(_vm->_mouse.x, _vm->_mouse.y); +} +// Apply the user's configured analog deadzone so a resting stick reports no +// motion. Mirrors RA1's applyRebel1AnalogDeadzone (iact.cpp). +static inline int16 applyRebel2AnalogDeadzone(int16 axisValue) { + const int deadZone = MAX(0, ConfMan.getInt("joystick_deadzone")) * 1000; + return (ABS((int)axisValue) <= deadZone) ? 0 : axisValue; +} + +void InsaneRebel2::updateGameplayAimFromGamepad() { if (_menuInputActive || _gameState != kStateGameplay) - return aimPos; - - int dx = 0; - int dy = 0; - - if (_vm->getActionState(kScummActionInsaneLeft)) - dx--; - if (_vm->getActionState(kScummActionInsaneRight)) - dx++; - if (_vm->getActionState(kScummActionInsaneUp)) - dy--; - if (_vm->getActionState(kScummActionInsaneDown)) - dy++; - - if (dx || dy) { - aimPos.x = (dx < 0) ? 0 : (dx > 0) ? 319 : 160; - aimPos.y = (dy < 0) ? 0 : (dy > 0) ? 199 : 100; + return; + + // Velocity model ported from RA1 (insane/rebel1/iact.cpp preprocessMouseAxes): + // the digital dpad pans at full rate, while the analog stick pans proportionally + // to its deflection past the deadzone. This replaces the old edge-snap that pinned + // the reticle to the screen borders. Mouse input is untouched: with nothing held the + // reticle simply follows _vm->_mouse as before. + int velX = 0; + int velY = 0; + + const int dpadX = (_vm->getActionState(kScummActionInsaneRight) ? 1 : 0) - + (_vm->getActionState(kScummActionInsaneLeft) ? 1 : 0); + const int dpadY = (_vm->getActionState(kScummActionInsaneDown) ? 1 : 0) - + (_vm->getActionState(kScummActionInsaneUp) ? 1 : 0); + + if (dpadX || dpadY) { + velX = dpadX * 127; + velY = dpadY * 127; + } else { + const int16 ax = applyRebel2AnalogDeadzone(_joystickAxisX); + const int16 ay = applyRebel2AnalogDeadzone(_joystickAxisY); + velX = CLIP((int)ax * 127 / Common::JOYAXIS_MAX, -127, 127); + velY = CLIP((int)ay * 127 / Common::JOYAXIS_MAX, -127, 127); } - return aimPos; + if (!velX && !velY) + return; + + // The gamepad is now driving the reticle: mark it the active aim source so + // notifyEvent() suppresses stray pointer events that would recenter it on fire. + _gamepadAimActive = true; + + // Integrate velocity into the reticle, clamped to the 320x200 play area. + // kStep sets the max pixels-per-frame at full deflection; tune for feel. + const int kStep = 8; + _vm->_mouse.x = (int16)CLIP(_vm->_mouse.x + velX * kStep / 127, 0, 319); + _vm->_mouse.y = (int16)CLIP(_vm->_mouse.y + velY * kStep / 127, 0, 199); } bool InsaneRebel2::isBitSet(int n) { diff --git a/engines/scumm/insane/rebel2/rebel.h b/engines/scumm/insane/rebel2/rebel.h index bf19ea2af37..28161f25106 100644 --- a/engines/scumm/insane/rebel2/rebel.h +++ b/engines/scumm/insane/rebel2/rebel.h @@ -492,6 +492,21 @@ public: int32 processMouse() override; Common::Point getGameplayAimPoint(); + // Per-frame: pan the gameplay reticle incrementally from the held directional controls + // (on-screen/physical gamepad dpad, keyboard arrows) instead of snapping it to a screen + // edge. Call once per frame; getGameplayAimPoint() stays a pure getter. + void updateGameplayAimFromGamepad(); + + // Analog stick state, ingested from EVENT_CUSTOM_BACKEND_ACTION_AXIS in notifyEvent() + // and read (with a deadzone) by updateGameplayAimFromGamepad(). Signed; 0 = centered. + int16 _joystickAxisX; + int16 _joystickAxisY; + + // True once the gamepad has driven the gameplay reticle, until a genuine mouse/touch + // motion takes over. While set, notifyEvent() drops stray pointer events so they can't + // recenter the reticle (the cursor is locked ~center during gameplay, so a gamepad + // "click" lands at center). See notifyEvent()/updateGameplayAimFromGamepad(). + bool _gamepadAimActive; bool isBitSet(int n) override; void setBit(int n) override; diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp index 5c8c0025a02..93e61776248 100644 --- a/engines/scumm/metaengine.cpp +++ b/engines/scumm/metaengine.cpp @@ -1170,25 +1170,45 @@ Common::KeymapArray ScummMetaEngine::initKeymaps(const char *target) const { act = new Action("RA2UP", _("Aim up / menu up")); act->setCustomEngineActionEvent(kScummActionInsaneUp); act->addDefaultInputMapping("JOY_UP"); - act->addDefaultInputMapping("JOY_LEFT_STICK_Y-"); rebel2Keymap->addAction(act); act = new Action("RA2DOWN", _("Aim down / menu down")); act->setCustomEngineActionEvent(kScummActionInsaneDown); act->addDefaultInputMapping("JOY_DOWN"); - act->addDefaultInputMapping("JOY_LEFT_STICK_Y+"); rebel2Keymap->addAction(act); act = new Action("RA2LEFT", _("Aim left / menu left")); act->setCustomEngineActionEvent(kScummActionInsaneLeft); act->addDefaultInputMapping("JOY_LEFT"); - act->addDefaultInputMapping("JOY_LEFT_STICK_X-"); rebel2Keymap->addAction(act); act = new Action("RA2RIGHT", _("Aim right / menu right")); act->setCustomEngineActionEvent(kScummActionInsaneRight); act->addDefaultInputMapping("JOY_RIGHT"); + rebel2Keymap->addAction(act); + + act = new Action("RA2STICKUP", _("Stick up")); + act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisUp); + act->addDefaultInputMapping("JOY_LEFT_STICK_Y-"); + act->addDefaultInputMapping("JOY_RIGHT_STICK_Y-"); + rebel2Keymap->addAction(act); + + act = new Action("RA2STICKDOWN", _("Stick down")); + act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisDown); + act->addDefaultInputMapping("JOY_LEFT_STICK_Y+"); + act->addDefaultInputMapping("JOY_RIGHT_STICK_Y+"); + rebel2Keymap->addAction(act); + + act = new Action("RA2STICKLEFT", _("Stick left")); + act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisLeft); + act->addDefaultInputMapping("JOY_LEFT_STICK_X-"); + act->addDefaultInputMapping("JOY_RIGHT_STICK_X-"); + rebel2Keymap->addAction(act); + + act = new Action("RA2STICKRIGHT", _("Stick right")); + act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisRight); act->addDefaultInputMapping("JOY_LEFT_STICK_X+"); + act->addDefaultInputMapping("JOY_RIGHT_STICK_X+"); rebel2Keymap->addAction(act); act = new Action("RA2FIRE", _("Fire / select")); diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 4a7b88a8421..94ebcfc4a7a 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -507,7 +507,11 @@ enum ScummBackendAction { kScummBackendActionRebel1AxisUp = 11000, kScummBackendActionRebel1AxisDown, kScummBackendActionRebel1AxisLeft, - kScummBackendActionRebel1AxisRight + kScummBackendActionRebel1AxisRight, + kScummBackendActionRebel2AxisUp, + kScummBackendActionRebel2AxisDown, + kScummBackendActionRebel2AxisLeft, + kScummBackendActionRebel2AxisRight }; extern const char *const insaneKeymapId; Commit: 0025c4e108654c7f9224366be4fab93f6c0a7a8c https://github.com/scummvm/scummvm/commit/0025c4e108654c7f9224366be4fab93f6c0a7a8c Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T16:26:14+02:00 Commit Message: SCUMM: RA2: match the joytick/gamepad input speed Changed paths: engines/scumm/insane/rebel2/rebel.cpp diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp index a91e46c276c..3b34d0bd1cc 100644 --- a/engines/scumm/insane/rebel2/rebel.cpp +++ b/engines/scumm/insane/rebel2/rebel.cpp @@ -1372,13 +1372,12 @@ void InsaneRebel2::updateGameplayAimFromGamepad() { if (_menuInputActive || _gameState != kStateGameplay) return; - // Velocity model ported from RA1 (insane/rebel1/iact.cpp preprocessMouseAxes): - // the digital dpad pans at full rate, while the analog stick pans proportionally - // to its deflection past the deadzone. This replaces the old edge-snap that pinned - // the reticle to the screen borders. Mouse input is untouched: with nothing held the - // reticle simply follows _vm->_mouse as before. - int velX = 0; - int velY = 0; + // The analog stick still reports the original joystick-style centered axis range + // [-127,127], while the dpad follows the original keyboard handler's normal + // movement step (FUN_405822: 3 units, or 5 with the DOS fast modifier). + int deltaX = 0; + int deltaY = 0; + bool activeGamepadAim = false; const int dpadX = (_vm->getActionState(kScummActionInsaneRight) ? 1 : 0) - (_vm->getActionState(kScummActionInsaneLeft) ? 1 : 0); @@ -1386,16 +1385,25 @@ void InsaneRebel2::updateGameplayAimFromGamepad() { (_vm->getActionState(kScummActionInsaneUp) ? 1 : 0); if (dpadX || dpadY) { - velX = dpadX * 127; - velY = dpadY * 127; + const int kOriginalDigitalStep = 3; + deltaX = dpadX * kOriginalDigitalStep; + deltaY = dpadY * kOriginalDigitalStep; + activeGamepadAim = true; } else { const int16 ax = applyRebel2AnalogDeadzone(_joystickAxisX); const int16 ay = applyRebel2AnalogDeadzone(_joystickAxisY); - velX = CLIP((int)ax * 127 / Common::JOYAXIS_MAX, -127, 127); - velY = CLIP((int)ay * 127 / Common::JOYAXIS_MAX, -127, 127); + const int velX = CLIP((int)ax * 127 / Common::JOYAXIS_MAX, -127, 127); + const int velY = CLIP((int)ay * 127 / Common::JOYAXIS_MAX, -127, 127); + + if (velX || velY) { + const int kAnalogMaxStep = 8; + deltaX = velX * kAnalogMaxStep / 127; + deltaY = velY * kAnalogMaxStep / 127; + activeGamepadAim = true; + } } - if (!velX && !velY) + if (!activeGamepadAim) return; // The gamepad is now driving the reticle: mark it the active aim source so @@ -1403,10 +1411,8 @@ void InsaneRebel2::updateGameplayAimFromGamepad() { _gamepadAimActive = true; // Integrate velocity into the reticle, clamped to the 320x200 play area. - // kStep sets the max pixels-per-frame at full deflection; tune for feel. - const int kStep = 8; - _vm->_mouse.x = (int16)CLIP(_vm->_mouse.x + velX * kStep / 127, 0, 319); - _vm->_mouse.y = (int16)CLIP(_vm->_mouse.y + velY * kStep / 127, 0, 199); + _vm->_mouse.x = (int16)CLIP(_vm->_mouse.x + deltaX, 0, 319); + _vm->_mouse.y = (int16)CLIP(_vm->_mouse.y + deltaY, 0, 199); } bool InsaneRebel2::isBitSet(int n) { Commit: 793b12545ac64040201408a037438c2525579849 https://github.com/scummvm/scummvm/commit/793b12545ac64040201408a037438c2525579849 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T16:34:43+02:00 Commit Message: SCUMM: RA2: make sure input starts centered Changed paths: engines/scumm/insane/rebel2/levels.cpp engines/scumm/insane/rebel2/rebel.h engines/scumm/insane/rebel2/runlevels.cpp diff --git a/engines/scumm/insane/rebel2/levels.cpp b/engines/scumm/insane/rebel2/levels.cpp index cef25c6b9e2..ad3f32077be 100644 --- a/engines/scumm/insane/rebel2/levels.cpp +++ b/engines/scumm/insane/rebel2/levels.cpp @@ -31,6 +31,9 @@ namespace Scumm { +static const int kRebel2GameplayAimCenterX = 160; +static const int kRebel2GameplayAimCenterY = 100; + // --------------------------------------------------------------------------- // Level Loading System // --------------------------------------------------------------------------- @@ -363,6 +366,17 @@ void InsaneRebel2::playCreditsSequence() { splayer->play("OPEN/O_CREDIT.SAN", 12); } +void InsaneRebel2::centerGameplayAim() { + _vm->_mouse.x = kRebel2GameplayAimCenterX; + _vm->_mouse.y = kRebel2GameplayAimCenterY; + + _joystickAxisX = 0; + _joystickAxisY = 0; + _gamepadAimActive = false; + + smush_warpMouse(kRebel2GameplayAimCenterX, kRebel2GameplayAimCenterY, -1); +} + // runLevel -- Main level dispatcher, calls per-level handlers. int InsaneRebel2::runLevel(int levelId) { @@ -400,12 +414,9 @@ int InsaneRebel2::runLevel(int levelId) { // The original hides the cursor (ShowCursor(0)) and relies on Windows confining // the mouse to the game window. Without locking, the cursor can escape the // ScummVM window making the ship uncontrollable. - smush_warpMouse(160, 100, -1); + centerGameplayAim(); CursorMan.showMouse(false); g_system->lockMouse(true); - // Start each level with the centered cursor as the authoritative aim source; - // the first gamepad input reclaims it (see updateGameplayAimFromGamepad). - _gamepadAimActive = false; // Initialize common player state _playerLives = 3; diff --git a/engines/scumm/insane/rebel2/rebel.h b/engines/scumm/insane/rebel2/rebel.h index 28161f25106..fefd80a6f96 100644 --- a/engines/scumm/insane/rebel2/rebel.h +++ b/engines/scumm/insane/rebel2/rebel.h @@ -459,6 +459,9 @@ public: // Play retry video (phase-specific for multi-phase levels) void playLevelRetryVariant(int levelId, int phase); + // Reset gameplay aim to the original centered mouse/joystick baseline. + void centerGameplayAim(); + // Level state tracking for multi-phase levels int _currentPhase; // Current gameplay phase (1, 2, 3 for Level 2; 1, 2 for Level 3/6) int _deathFrame; // Frame number where player died (for death video selection) diff --git a/engines/scumm/insane/rebel2/runlevels.cpp b/engines/scumm/insane/rebel2/runlevels.cpp index 673a67def8a..2d054d0c888 100644 --- a/engines/scumm/insane/rebel2/runlevels.cpp +++ b/engines/scumm/insane/rebel2/runlevels.cpp @@ -190,6 +190,13 @@ InsaneRebel2::WaveEndResult InsaneRebel2::processWaveEnd(int16 mask, int16 *budg bool InsaneRebel2::playLevelSegment(const char *filename, uint16 flags, bool recordFrame) { SmushPlayer *splayer = ((ScummEngine_v7 *)_vm)->_splayer; + + // Retail reset helpers clear the centered input axes before gameplay starts. + // Do the same for playable segments, but keep seamless continuation videos + // (0x40, e.g. 13PLAY_B) from snapping the aim point mid-sequence. + if (recordFrame && (flags & 0x08) != 0 && (flags & 0x40) == 0) + centerGameplayAim(); + splayer->setCurVideoFlags(flags); splayer->play(filename, 12); if (recordFrame) From noreply at scummvm.org Mon Jun 1 14:35:07 2026 From: noreply at scummvm.org (ScummVM-Translations) Date: Mon, 1 Jun 2026 14:35:07 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> 660e5010a45a535821210d19a0cb2e34cb97cb3b Message-ID: <20260601143507.0BFF27005C2@ron.scummvm.net> 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: 660e5010a4 I18N: Update translations templates Commit: 660e5010a45a535821210d19a0cb2e34cb97cb3b https://github.com/scummvm/scummvm/commit/660e5010a45a535821210d19a0cb2e34cb97cb3b Author: Weblate (noreply at weblate.org) Date: 2026-06-01T14:35:01Z Commit Message: I18N: Update translations templates Changed paths: po/scummvm.pot diff --git a/po/scummvm.pot b/po/scummvm.pot index 8d434f2fd95..a0615fac668 100644 --- a/po/scummvm.pot +++ b/po/scummvm.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 2026.2.1git\n" "Report-Msgid-Bugs-To: scummvm-devel at lists.scummvm.org\n" -"POT-Creation-Date: 2026-05-31 14:10+0000\n" +"POT-Creation-Date: 2026-06-01 14:35+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -12425,35 +12425,35 @@ msgstr "" msgid "Aim up / menu up" msgstr "" -#: engines/scumm/metaengine.cpp:1113 engines/scumm/metaengine.cpp:1176 +#: engines/scumm/metaengine.cpp:1113 engines/scumm/metaengine.cpp:1175 msgid "Aim down / menu down" msgstr "" -#: engines/scumm/metaengine.cpp:1118 engines/scumm/metaengine.cpp:1182 +#: engines/scumm/metaengine.cpp:1118 engines/scumm/metaengine.cpp:1180 msgid "Aim left / menu left" msgstr "" -#: engines/scumm/metaengine.cpp:1123 engines/scumm/metaengine.cpp:1188 +#: engines/scumm/metaengine.cpp:1123 engines/scumm/metaengine.cpp:1185 msgid "Aim right / menu right" msgstr "" -#: engines/scumm/metaengine.cpp:1128 +#: engines/scumm/metaengine.cpp:1128 engines/scumm/metaengine.cpp:1190 msgid "Stick up" msgstr "" -#: engines/scumm/metaengine.cpp:1134 +#: engines/scumm/metaengine.cpp:1134 engines/scumm/metaengine.cpp:1196 msgid "Stick down" msgstr "" -#: engines/scumm/metaengine.cpp:1140 +#: engines/scumm/metaengine.cpp:1140 engines/scumm/metaengine.cpp:1202 msgid "Stick left" msgstr "" -#: engines/scumm/metaengine.cpp:1146 +#: engines/scumm/metaengine.cpp:1146 engines/scumm/metaengine.cpp:1208 msgid "Stick right" msgstr "" -#: engines/scumm/metaengine.cpp:1152 engines/scumm/metaengine.cpp:1194 +#: engines/scumm/metaengine.cpp:1152 engines/scumm/metaengine.cpp:1214 msgid "Fire / select" msgstr "" @@ -12465,11 +12465,11 @@ msgstr "" msgid "Rebel Assault II controls" msgstr "" -#: engines/scumm/metaengine.cpp:1199 +#: engines/scumm/metaengine.cpp:1219 msgid "Cover / back" msgstr "" -#: engines/scumm/metaengine.cpp:1204 +#: engines/scumm/metaengine.cpp:1224 msgid "Skip / menu" msgstr "" From noreply at scummvm.org Mon Jun 1 14:35:39 2026 From: noreply at scummvm.org (ScummVM-Translations) Date: Mon, 1 Jun 2026 14:35:39 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> 7c3ffa518dea6b8886c80476bc7c8836742d93e4 Message-ID: <20260601143539.48216700591@ron.scummvm.net> 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: 7c3ffa518d I18N: Update translation files Commit: 7c3ffa518dea6b8886c80476bc7c8836742d93e4 https://github.com/scummvm/scummvm/commit/7c3ffa518dea6b8886c80476bc7c8836742d93e4 Author: Weblate (noreply at weblate.org) Date: 2026-06-01T14:35:18Z Commit Message: I18N: Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: ScummVM/scummvm Translate-URL: https://translations.scummvm.org/projects/scummvm/scummvm/ Changed paths: po/ar.po po/be-tarask.po po/be_BY.po po/ca_ES.po po/cs_CZ.po po/da.po po/de_DE.po po/el.po po/es_ES.po po/eu.po po/fi_FI.po po/fr_FR.po po/gl_ES.po po/he.po po/hi.po po/hu_HU.po po/it_IT.po po/ja.po po/ka.po po/ko.po po/nb_NO.po po/nl_NL.po po/nn_NO.po po/pl_PL.po po/pt_BR.po po/pt_PT.po po/ro.po po/ru_RU.po po/sv_SE.po po/tr.po po/uk_UA.po po/zh.po po/zh_Hans.po po/zh_Hant.po diff --git a/po/ar.po b/po/ar.po index bfa3167691c..fc404c6b896 100644 --- a/po/ar.po +++ b/po/ar.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 2.8.0git\n" "Report-Msgid-Bugs-To: scummvm-devel at lists.scummvm.org\n" -"POT-Creation-Date: 2026-05-31 14:10+0000\n" +"POT-Creation-Date: 2026-06-01 14:35+0000\n" "PO-Revision-Date: 2026-02-24 22:26+0000\n" "Last-Translator: Mohamed Shaaban \n" "Language-Team: Arabic \n" "Language-Team: Belarusian (Tara??kievica) \n" "Language-Team: Belarusian \n" "Language-Team: Catalan \n" "Language-Team: Czech \n" "Language-Team: Danish \n" "Language-Team: German \n" "Language-Team: Greek \n" "Language-Team: Spanish \n" "Language-Team: Basque \n" "Language-Team: Finnish \n" "Language-Team: French \n" "Language-Team: Galician \n" "Language-Team: Hebrew \n" "Language-Team: Hindi \n" "Language-Team: Hungarian \n" "Language-Team: Italian \n" "Language-Team: Japanese \n" "Language-Team: Georgian \n" "Language-Team: Korean \n" "Language-Team: Norwegian Bokm??l \n" "Language-Team: Dutch \n" "Language-Team: Norwegian Nynorsk \n" "Language-Team: Polish \n" "Language-Team: Portuguese (Brazil) \n" "Language-Team: Portuguese (Portugal) \n" "Language-Team: Russian \n" "Language-Team: Swedish \n" "Language-Team: Turkish \n" "Language-Team: Ukrainian \n" "Language-Team: Chinese \n" "Language-Team: Chinese (Simplified Han script) 2f5bbc4c20dc1a2e6f7bbd0291dee480dd2ec760 Message-ID: <20260601155811.97B35700591@ron.scummvm.net> This automated email contains information about 14 new commits which have been pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm . Summary: 8f552fa4ef DM: Fix floor sensors failing to open closed door in Hall of Champions 72b3ad705a DM: Fix crash on save dialog selection highlight d18af2b285 DM: Implement EventManager::highlightScreenBox() 7bce6e9e88 DM: Fix in-game save loading failing on first attempt 92a8dc48ed DM: Fix stairs transition crash in Hall of Champions 1f57def68f DM: Fix null pointer dereference when rendering creature groups 182c24df56 DM: Correct bitfield masks and sensor data setter 6aeb6b5b32 DM: Fix debugger crash on wrong spelling in 'gimme' command 7238392ca2 DM: Fix crash by correcting the order of values in CLIP dc8e5ad33b DM: Correct evaluation order for footprint scent checks. PVS-Studio V501 3f611279e0 DM: Fix out-of-bounds read. PVS-Studio V781 22841aa24c DM: Correct sign mismatch using explicit cast. PVS-Studio V1112 e59edaa25d DM: Fix out-of-bounds pointer arithmetic. PVS-Studio V557 2f5bbc4c20 DM: Fix out-of-bounds map data access. PVS-Studio V781 Commit: 8f552fa4efbfa76203ccc229c66a2f7d4b36addc https://github.com/scummvm/scummvm/commit/8f552fa4efbfa76203ccc229c66a2f7d4b36addc Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix floor sensors failing to open closed door in Hall of Champions Previously, checking both open and closed door states under the kDMSensorEffectSet caused incorrect early return. Changed paths: engines/dm/timeline.cpp diff --git a/engines/dm/timeline.cpp b/engines/dm/timeline.cpp index 42cc84dea34..324de237264 100644 --- a/engines/dm/timeline.cpp +++ b/engines/dm/timeline.cpp @@ -482,11 +482,16 @@ void Timeline::processEventSquareDoor(TimelineEvent *event) { if (doorState == kDMDoorStateDestroyed) return; - if (event->_Cu.A._effect == kDMSensorEffectToggle) + if (event->_Cu.A._effect == kDMSensorEffectToggle) { event->_Cu.A._effect = (doorState == kDMDoorStateOpen) ? kDMSensorEffectClear : kDMSensorEffectSet; - else if (event->_Cu.A._effect == kDMSensorEffectSet) { - if ((doorState == kDMDoorStateOpen) || (doorState == kDMDoorStateClosed)) - return; + } else { + if (event->_Cu.A._effect == kDMSensorEffectSet) { + if (doorState == kDMDoorStateOpen) + return; + } else if (event->_Cu.A._effect == kDMSensorEffectClear) { + if (doorState == kDMDoorStateClosed) + return; + } } event->_type = kDMEventTypeDoorAnimation; addEventGetEventIndex(event); Commit: 72b3ad705a5e274255357b8ca00607ad84f83ce6 https://github.com/scummvm/scummvm/commit/72b3ad705a5e274255357b8ca00607ad84f83ce6 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix crash on save dialog selection highlight Correct the order of parameter in the Box constructor Changed paths: engines/dm/dialog.cpp diff --git a/engines/dm/dialog.cpp b/engines/dm/dialog.cpp index d6478fe681f..839eaed1c02 100644 --- a/engines/dm/dialog.cpp +++ b/engines/dm/dialog.cpp @@ -206,7 +206,7 @@ int16 DialogMan::getChoice(uint16 choiceCount, uint16 dialogSetIndex, int16 driv boxA._rect.bottom += 4; evtMan.showMouse(); displMan._drawFloorAndCeilingRequested = true; - Box boxB(0, 0, boxA._rect.right - boxA._rect.left + 3, boxA._rect.bottom - boxA._rect.top + 3); + Box boxB(0, boxA._rect.right - boxA._rect.left + 3, 0, boxA._rect.bottom - boxA._rect.top + 3); displMan.blitToBitmap(displMan._bitmapScreen, displMan._bitmapViewport, boxB, boxA._rect.left, boxA._rect.top, k160_byteWidthScreen, k160_byteWidthScreen, kDMColorNoTransparency, 200, 25); _vm->delay(1); Commit: d18af2b285ea1e2cdb12452ac957d154f223ed63 https://github.com/scummvm/scummvm/commit/d18af2b285ea1e2cdb12452ac957d154f223ed63 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Implement EventManager::highlightScreenBox() This enablers move indicator highlight in game UI. Changed paths: engines/dm/eventman.cpp engines/dm/eventman.h diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp index 03e418f6776..9a0377cc39b 100644 --- a/engines/dm/eventman.cpp +++ b/engines/dm/eventman.cpp @@ -1678,4 +1678,20 @@ void EventManager::highlightBoxDisable() { } } +void EventManager::highlightScreenBox(int16 x1, int16 x2, int16 y1, int16 y2) { + x1 = CLIP(x1, 0, _vm->_displayMan->_screenWidth - 1); + x2 = CLIP(x2, 0, _vm->_displayMan->_screenWidth - 1); + y1 = CLIP(y1, 0, _vm->_displayMan->_screenHeight - 1); + y2 = CLIP(y2, 0, _vm->_displayMan->_screenHeight - 1); + + byte *screen = _vm->_displayMan->_bitmapScreen; + uint16 pitch = _vm->_displayMan->_screenWidth; + + for (int16 y = y1; y <= y2; ++y) { + for (int16 x = x1; x <= x2; ++x) { + screen[y * pitch + x] ^= 0x0F; + } + } +} + } // end of namespace DM diff --git a/engines/dm/eventman.h b/engines/dm/eventman.h index 2f81ce82fee..4fde15d62a6 100644 --- a/engines/dm/eventman.h +++ b/engines/dm/eventman.h @@ -286,7 +286,7 @@ public: void waitForMouseOrKeyActivity(); // @ F0541_INPUT_WaitForMouseOrKeyboardActivity void commandHighlightBoxEnable(int16 x1, int16 x2, int16 y1, int16 y2); // @ F0362_COMMAND_HighlightBoxEnable void highlightBoxDisable(); // @ F0363_COMMAND_HighlightBoxDisable - void highlightScreenBox(int16 x1, int16 x2, int16 y1, int16 y2) { warning("STUB METHOD: highlightScreenBox"); } // @ F0006_MAIN_HighlightScreenBox + void highlightScreenBox(int16 x1, int16 x2, int16 y1, int16 y2); // @ F0006_MAIN_HighlightScreenBox KeyboardInput _primaryKeyboardInputInterface[7]; // @ G0458_as_Graphic561_PrimaryKeyboardInput_Interface KeyboardInput _secondaryKeyboardInputMovement[19]; // @ G0459_as_Graphic561_SecondaryKeyboardInput_Movement Commit: 7bce6e9e883e12f40e6c7d0bbf8beaab1249f49a https://github.com/scummvm/scummvm/commit/7bce6e9e883e12f40e6c7d0bbf8beaab1249f49a Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix in-game save loading failing on first attempt Set _gameMode to kDMModeLoadSavedGame when a valid slot is loaded. Changed paths: engines/dm/loadsave.cpp diff --git a/engines/dm/loadsave.cpp b/engines/dm/loadsave.cpp index bd177faf5af..3b567325058 100644 --- a/engines/dm/loadsave.cpp +++ b/engines/dm/loadsave.cpp @@ -42,6 +42,9 @@ namespace DM { LoadgameResult DMEngine::loadgame(int16 slot) { + if (slot >= 0) + _gameMode = kDMModeLoadSavedGame; + if (slot == -1 && _gameMode == kDMModeLoadSavedGame) return kDMLoadgameFailure; Commit: 92a8dc48ed958a77ef46563af53989e82c86db6d https://github.com/scummvm/scummvm/commit/92a8dc48ed958a77ef46563af53989e82c86db6d Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix stairs transition crash in Hall of Champions Make CreatureType strictly a 16-bit enum to prevent C++ struct padding and over-read. Changed paths: engines/dm/group.h diff --git a/engines/dm/group.h b/engines/dm/group.h index 7fd95bdb43a..cc96c8d8c70 100644 --- a/engines/dm/group.h +++ b/engines/dm/group.h @@ -37,7 +37,7 @@ namespace DM { class CreatureInfo; /* Creature types */ -enum CreatureType { +enum CreatureType : uint16 { kDMCreatureTypeGiantScorpion = 0, // @ C00_CREATURE_GIANT_SCORPION_SCORPION kDMCreatureTypeSwampSlime = 1, // @ C01_CREATURE_SWAMP_SLIME_SLIME_DEVIL kDMCreatureTypeGiggler = 2, // @ C02_CREATURE_GIGGLER Commit: 1f57def68f9d85ce0cd5a50cadae5c6602065b07 https://github.com/scummvm/scummvm/commit/1f57def68f9d85ce0cd5a50cadae5c6602065b07 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix null pointer dereference when rendering creature groups Changed paths: engines/dm/gfx.cpp diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp index 8f4894cd016..cd0a4428ad7 100644 --- a/engines/dm/gfx.cpp +++ b/engines/dm/gfx.cpp @@ -3368,12 +3368,12 @@ T0115015_DrawProjectileAsObject: if (group == nullptr) { /* If all creature data and info has not already been gathered */ group = (Group *)dungeon.getThingData(groupThing); - activeGroup = &_vm->_groupMan->_activeGroups[group->getActiveGroupIndex()]; CreatureInfo *creatureInfo = &dungeon._creatureInfos[group->_type]; creatureAspectStruct = &_creatureAspects219[creatureInfo->_creatureAspectIndex]; creatureSize = getFlag(creatureInfo->_attributes, kDMCreatureMaskSize); creatureGraphicInfoGreen = creatureInfo->_graphicInfo; } + activeGroup = &_vm->_groupMan->_activeGroups[group->getActiveGroupIndex()]; objectAspect = (ObjectAspect *)creatureAspectStruct; AL_0_creatureIndexRed = _vm->_groupMan->getCreatureOrdinalInCell(group, cellYellowBear); Commit: 182c24df56619e8ee151e0e181db770d6c115991 https://github.com/scummvm/scummvm/commit/182c24df56619e8ee151e0e181db770d6c115991 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Correct bitfield masks and sensor data setter Fix Sensor::setData & some getters to use correct bit masks matching the original. Changed paths: engines/dm/dungeonman.h diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h index 66ca67c61a3..59df5773c2a 100644 --- a/engines/dm/dungeonman.h +++ b/engines/dm/dungeonman.h @@ -354,11 +354,11 @@ public: explicit Teleporter(uint16 *rawDat) : _nextThing(rawDat[0]), _attributes(rawDat[1]), _destMapIndex(rawDat[2]) {} Thing getNextThing() { return _nextThing; } bool isAudible() { return (_attributes >> 15) & 1; } - TeleporterScope getScope() { return (TeleporterScope)((_attributes >> 13) & 1); } + TeleporterScope getScope() { return (TeleporterScope)((_attributes >> 13) & 3); } bool getAbsoluteRotation() { return (_attributes >> 12) & 1; } - Direction getRotation() { return (Direction)((_attributes >> 10) & 1); } - byte getTargetMapY() { return (_attributes >> 5) & 0xF; } - byte getTargetMapX() { return _attributes & 0xF; } + Direction getRotation() { return (Direction)((_attributes >> 10) & 3); } + byte getTargetMapY() { return (_attributes >> 5) & 0x1F; } + byte getTargetMapX() { return _attributes & 0x1F; } uint16 getTargetMapIndex() { return _destMapIndex >> 8; } }; // @ TELEPORTER @@ -388,7 +388,7 @@ public: uint16 getData() { return (_datAndType >> 7) & 0x1FF; } // @ M40_DATA static uint16 getDataMask1(uint16 data) { return (data >> 7) & 0xF; } // @ M42_MASK1 static uint16 getDataMask2(uint16 data) { return (data >> 11) & 0xF; } // @ M43_MASK2 - void setData(uint16 dat) { _datAndType = dat; } // @ M41_SET_DATA + void setData(uint16 dat) { _datAndType = (_datAndType & 0x7F) | (dat << 7); } // @ M41_SET_DATA void setTypeDisabled() { _datAndType &= 0xFF80; } // @ M44_SET_TYPE_DISABLED bool getAttrOnlyOnce() { return (_attributes >> 2) & 1; } Commit: 6aeb6b5b3272c3f8e8e03269f616140098391832 https://github.com/scummvm/scummvm/commit/6aeb6b5b3272c3f8e8e03269f616140098391832 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix debugger crash on wrong spelling in 'gimme' command Changed paths: engines/dm/console.cpp diff --git a/engines/dm/console.cpp b/engines/dm/console.cpp index 8d7dcfa8dfc..7372da0bb18 100644 --- a/engines/dm/console.cpp +++ b/engines/dm/console.cpp @@ -264,7 +264,7 @@ bool Console::Cmd_gimme(int argc, const char** argv) { for (int16 thingIndex = 0; thingIndex < thingCount; ++thingIndex) { dummyThing.setIndex(thingIndex); int16 iconIndex = _vm->_objectMan->getIconIndex(dummyThing); - if (iconIndex != -1) { + if (iconIndex >= 0 && iconIndex < kDMObjectNameCount) { const char *displayName = _vm->_objectMan->_objectNames[iconIndex]; if (cstrEquals(displayName, requestedItemName.c_str())) { uint16 *newThingData = new uint16[(thingCount + 1) * thingTypeSize]; Commit: 7238392ca2926771a81aa428e3fb51fc42d2631e https://github.com/scummvm/scummvm/commit/7238392ca2926771a81aa428e3fb51fc42d2631e Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix crash by correcting the order of values in CLIP Changed paths: engines/dm/champion.cpp engines/dm/gfx.cpp engines/dm/menus.cpp diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp index 1d2c8b518e7..21fb97016f2 100644 --- a/engines/dm/champion.cpp +++ b/engines/dm/champion.cpp @@ -661,7 +661,7 @@ uint16 ChampionMan::getStrength(int16 champIndex, int16 slotIndex) { if (getFlag(curChampion->_wounds, (slotIndex == kDMSlotReadyHand) ? kDMWoundReadHand : kDMWoundActionHand)) strength >>= 1; - return CLIP(0, strength >> 1, 100); + return CLIP(strength >> 1, 0, 100); } Thing ChampionMan::getObjectRemovedFromSlot(uint16 champIndex, uint16 slotIndex) { @@ -883,7 +883,7 @@ int16 ChampionMan::getWoundDefense(int16 champIndex, uint16 woundIndex) { if (_partyIsSleeping) woundDefense >>= 1; - return CLIP(0, woundDefense >> 1, 100); + return CLIP(woundDefense >> 1, 0, 100); } uint16 ChampionMan::getStatisticAdjustedAttack(Champion *champ, uint16 statIndex, uint16 attack) { @@ -920,7 +920,7 @@ void ChampionMan::wakeUp() { int16 ChampionMan::getThrowingStaminaCost(Thing thing) { int16 weight = _vm->_dungeonMan->getObjectWeight(thing) >> 1; - int16 staminaCost = CLIP(1, weight, 10); + int16 staminaCost = CLIP(weight, 1, 10); while ((weight -= 10) > 0) staminaCost += weight >> 1; @@ -979,7 +979,7 @@ void ChampionMan::addSkillExperience(uint16 champIndex, uint16 skillIndex, uint1 Skill *curSkill = &curChampion->_skills[skillIndex]; curSkill->_experience += exp; if (curSkill->_temporaryExperience < 32000) - curSkill->_temporaryExperience += CLIP(1, exp >> 3, 100); + curSkill->_temporaryExperience += CLIP(exp >> 3, 1, 100); curSkill = &curChampion->_skills[baseSkillIndex]; if (skillIndex >= kDMSkillSwing) @@ -1121,7 +1121,7 @@ bool ChampionMan::isLucky(Champion *champ, uint16 percentage) { unsigned char *curStat = champ->_statistics[kDMStatLuck]; bool retVal = (_vm->getRandomNumber(curStat[kDMStatCurrent]) > percentage); - curStat[kDMStatCurrent] = CLIP(curStat[kDMStatMinimum], curStat[kDMStatCurrent] + (retVal ? -2 : 2), curStat[kDMStatMaximum]); + curStat[kDMStatCurrent] = CLIP(curStat[kDMStatCurrent] + (retVal ? -2 : 2), curStat[kDMStatMinimum], curStat[kDMStatMaximum]); return retVal; } @@ -1660,7 +1660,7 @@ void ChampionMan::applyTimeEffects() { staminaGainCycleCount += 2; int16 staminaLoss = 0; - int16 staminaAmount = CLIP(1, (championPtr->_maxStamina >> 8) - 1, 6); + int16 staminaAmount = CLIP((championPtr->_maxStamina >> 8) - 1, 1, 6); if (_partyIsSleeping) staminaAmount <<= 1; diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp index cd0a4428ad7..41b6f422c55 100644 --- a/engines/dm/gfx.cpp +++ b/engines/dm/gfx.cpp @@ -3580,12 +3580,12 @@ T0115077_DrawSecondHalfSquareCreature: else if (viewLane != kDMViewLaneCenter) /* Lane right */ AL_4_xPos += 100; - boxByteGreen._rect.right = CLIP(0, AL_4_xPos + byteWidth, 223); + boxByteGreen._rect.right = CLIP(AL_4_xPos + byteWidth, 0, 223); if (!boxByteGreen._rect.right) goto T0115126_CreatureNotVisible; int16 AL_0_creaturePosX; - boxByteGreen._rect.left = CLIP(0, AL_4_xPos - byteWidth + 1, 223); + boxByteGreen._rect.left = CLIP(AL_4_xPos - byteWidth + 1, 0, 223); if (boxByteGreen._rect.left) { if (boxByteGreen._rect.left == 223) goto T0115126_CreatureNotVisible; @@ -3845,7 +3845,7 @@ T0115200_DrawExplosion: continue; boxByteGreen._rect.right = AL_4_xPos; AL_4_xPos = explosionCoordinates[0]; - boxByteGreen._rect.left = CLIP(0, AL_4_xPos - byteWidth + 1, 223); + boxByteGreen._rect.left = CLIP(AL_4_xPos - byteWidth + 1, 0, 223); if (boxByteGreen._rect.left) AL_4_xPos = paddingPixelCount; diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp index 8747273341b..7fca0f08134 100644 --- a/engines/dm/menus.cpp +++ b/engines/dm/menus.cpp @@ -589,7 +589,7 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { if (curSpell->getType() == kDMSpellTypeProjectileOpenDoor) skillLevel <<= 1; - championMan.isProjectileSpellCast(champIndex, Thing(curSpell->getType() + _vm->_thingFirstExplosion.toUint16()), CLIP(21, (powerSymbolOrdinal + 2) * (4 + (skillLevel << 1)), 255), 0); + championMan.isProjectileSpellCast(champIndex, Thing(curSpell->getType() + _vm->_thingFirstExplosion.toUint16()), CLIP((powerSymbolOrdinal + 2) * (4 + (skillLevel << 1)), 21, 255), 0); break; case kDMSpellKindOther: { TimelineEvent newEvent; Commit: dc8e5ad33b3b1154fb73807c62f302281d826180 https://github.com/scummvm/scummvm/commit/dc8e5ad33b3b1154fb73807c62f302281d826180 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Correct evaluation order for footprint scent checks. PVS-Studio V501 Check footprints-allowed before assigning scent ordinal to avoid overwriting their shared memory too early, matching the original. Changed paths: engines/dm/dungeonman.cpp diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp index b585ca68733..a989070b636 100644 --- a/engines/dm/dungeonman.cpp +++ b/engines/dm/dungeonman.cpp @@ -962,8 +962,7 @@ T0172010_ClosedFakeWall: curThing = getNextThing(curThing); } - AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY); - if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex)) + if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY)) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex)) setFlag(aspectArray[kDMSquareAspectFloorOrn], kDMMaskFootprints); break; @@ -987,8 +986,7 @@ T0172010_ClosedFakeWall: while ((curThing != _vm->_thingEndOfList) && (curThing.getType() <= kDMThingTypeSensor)) curThing = getNextThing(curThing); - AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY); - if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex)) + if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY)) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex)) setFlag(aspectArray[kDMSquareAspectFloorOrn], kDMMaskFootprints); break; default: Commit: 3f611279e0bc389acb00f81a51a1267ccb785674 https://github.com/scummvm/scummvm/commit/3f611279e0bc389acb00f81a51a1267ccb785674 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix out-of-bounds read. PVS-Studio V781 Move coordinates bounds checks before accessing map data to prevent crashes Changed paths: engines/dm/dungeonman.cpp diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp index a989070b636..f6e6ea312a8 100644 --- a/engines/dm/dungeonman.cpp +++ b/engines/dm/dungeonman.cpp @@ -831,8 +831,11 @@ Square DungeonMan::getRelSquare(Direction dir, int16 stepsForward, int16 stepsRi } int16 DungeonMan::getSquareFirstThingIndex(int16 mapX, int16 mapY) { + if ((mapX < 0) || (mapX >= _currMapWidth) || (mapY < 0) || (mapY >= _currMapHeight)) + return -1; + unsigned char *curSquare = _currMapData[mapX]; - if ((mapX < 0) || (mapX >= _currMapWidth) || (mapY < 0) || (mapY >= _currMapHeight) || !getFlag(curSquare[mapY], kDMSquareMaskThingListPresent)) + if (!getFlag(curSquare[mapY], kDMSquareMaskThingListPresent)) return -1; int16 curMapY = 0; Commit: 22841aa24c85be7c35dc12efb783899949d3b874 https://github.com/scummvm/scummvm/commit/22841aa24c85be7c35dc12efb783899949d3b874 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Correct sign mismatch using explicit cast. PVS-Studio V1112 Changed paths: engines/dm/champion.cpp engines/dm/eventman.cpp diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp index 21fb97016f2..436a529dae2 100644 --- a/engines/dm/champion.cpp +++ b/engines/dm/champion.cpp @@ -1604,7 +1604,7 @@ void ChampionMan::unpoison(int16 champIndex) { TimelineEvent *eventPtr = _vm->_timeline->_events; for (uint16 eventIndex = 0; eventIndex < _vm->_timeline->_eventMaxCount; eventPtr++, eventIndex++) { - if ((eventPtr->_type == kDMEventTypePoisonChampion) && (eventPtr->_priority == champIndex)) + if ((eventPtr->_type == kDMEventTypePoisonChampion) && ((int16)eventPtr->_priority == champIndex)) _vm->_timeline->deleteEvent(eventIndex); } _champions[champIndex]._poisonEventCount = 0; diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp index 9a0377cc39b..7515380d0df 100644 --- a/engines/dm/eventman.cpp +++ b/engines/dm/eventman.cpp @@ -530,7 +530,7 @@ void EventManager::buildpointerScreenArea(int16 mousePosX, int16 mousePosY) { _mousePointerType = k4_pointerTypeAutoselect; else { championIdx++; - if (championIdx == _vm->_inventoryMan->_inventoryChampionOrdinal) + if (championIdx == (uint16)_vm->_inventoryMan->_inventoryChampionOrdinal) _mousePointerType = k0_pointerTypeArrow; else if (mousePosY <= 6) _mousePointerType = k0_pointerTypeArrow; Commit: e59edaa25dc38e778775b95dc3980484510bc833 https://github.com/scummvm/scummvm/commit/e59edaa25dc38e778775b95dc3980484510bc833 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix out-of-bounds pointer arithmetic. PVS-Studio V557 Use row-pointer incrementing to traverse _doorButtonCoordSets safely, avoiding out-of-bounds warnings when traversing to the next sub-array in contiguous memory. Changed paths: engines/dm/gfx.cpp diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp index 41b6f422c55..13c9c31a5c5 100644 --- a/engines/dm/gfx.cpp +++ b/engines/dm/gfx.cpp @@ -2642,10 +2642,10 @@ void DisplayMan::loadCurrentMapGraphics() { } for (uint16 index = kDMDerivedBitmapFirstDoorButton, counter = 0; counter < k1_DoorButtonCount; counter++) { - uint16 *coords = _doorButtonCoordSets[_doorButtonCoordSet[counter]][1]; - _derivedBitmapByteCount[index++] = coords[4] * coords[5]; - coords += 6; - _derivedBitmapByteCount[index++] = coords[4] * coords[5]; + uint16 (*rowPtr)[6] = _doorButtonCoordSets[_doorButtonCoordSet[counter]] + 1; + _derivedBitmapByteCount[index++] = (*rowPtr)[4] * (*rowPtr)[5]; + rowPtr++; + _derivedBitmapByteCount[index++] = (*rowPtr)[4] * (*rowPtr)[5]; } applyCreatureReplColors(9, 8); Commit: 2f5bbc4c20dc1a2e6f7bbd0291dee480dd2ec760 https://github.com/scummvm/scummvm/commit/2f5bbc4c20dc1a2e6f7bbd0291dee480dd2ec760 Author: Mohit Bankar (mohitbankar1212 at gmail.com) Date: 2026-06-01T17:57:59+02:00 Commit Message: DM: Fix out-of-bounds map data access. PVS-Studio V781 Move the map coordinate boundary check to run before indexing dungeon._currMapData array. Changed paths: engines/dm/group.cpp diff --git a/engines/dm/group.cpp b/engines/dm/group.cpp index e268cb1028f..84bda38c9db 100644 --- a/engines/dm/group.cpp +++ b/engines/dm/group.cpp @@ -1105,12 +1105,14 @@ bool GroupMan::isMovementPossible(CreatureInfo *creatureInfo, int16 mapX, int16 dungeon.mapCoordsAfterRelMovement((Direction)dir, 1, 0, mapX, mapY); + if ((mapX < 0) || (mapX >= dungeon._currMapWidth) || (mapY < 0) || (mapY >= dungeon._currMapHeight)) { + _groupMovBlockedByWallStairsPitFakeWalFluxCageTeleporter = true; + return false; + } uint16 curSquare = dungeon._currMapData[mapX][mapY]; int16 curSquareType = Square(curSquare).getType(); _groupMovBlockedByWallStairsPitFakeWalFluxCageTeleporter = - !(((mapX >= 0) && (mapX < dungeon._currMapWidth)) && - ((mapY >= 0) && (mapY < dungeon._currMapHeight)) && - (curSquareType != kDMElementTypeWall) && + !((curSquareType != kDMElementTypeWall) && (curSquareType != kDMElementTypeStairs) && ((curSquareType != kDMElementTypePit) || (getFlag(curSquare, kDMSquareMaskPitImaginary) && allowMovementOverImaginaryPitsAndFakeWalls) || !getFlag(curSquare, kDMSquareMaskPitOpen) || getFlag(creatureInfo->_attributes, kDMCreatureMaskLevitation)) && ((curSquareType != kDMElementTypeFakeWall) || getFlag(curSquare, kDMSquareMaskFakeWallOpen) || (getFlag(curSquare, kDMSquareMaskFakeWallImaginary) && allowMovementOverImaginaryPitsAndFakeWalls))); From noreply at scummvm.org Mon Jun 1 16:27:19 2026 From: noreply at scummvm.org (neuromancer) Date: Mon, 1 Jun 2026 16:27:19 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> 56763c322d0a69c065105df8bb385b4dc330fb22 Message-ID: <20260601162719.2DCFC700591@ron.scummvm.net> 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: 56763c322d SCUMM: RA2: allow gamepad navigation Commit: 56763c322d0a69c065105df8bb385b4dc330fb22 https://github.com/scummvm/scummvm/commit/56763c322d0a69c065105df8bb385b4dc330fb22 Author: neuromancer (gustavo.grieco at gmail.com) Date: 2026-06-01T18:26:45+02:00 Commit Message: SCUMM: RA2: allow gamepad navigation Changed paths: engines/scumm/insane/rebel2/rebel.cpp engines/scumm/insane/rebel2/rebel.h engines/scumm/metaengine.cpp engines/scumm/scumm.h diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp index 3b34d0bd1cc..4c363df1be4 100644 --- a/engines/scumm/insane/rebel2/rebel.cpp +++ b/engines/scumm/insane/rebel2/rebel.cpp @@ -51,6 +51,47 @@ namespace Scumm { +const int kRA2MenuAxisThreshold = Common::JOYAXIS_MAX / 5; +const uint32 kRA2MenuGamepadNavigationDebounceMs = 250; +const uint32 kRA2MenuGamepadMouseSuppressMs = 250; + +bool isRebel2RawMenuAxis(int axis) { + return axis == Common::JOYSTICK_AXIS_LEFT_STICK_X || + axis == Common::JOYSTICK_AXIS_LEFT_STICK_Y || + axis == Common::JOYSTICK_AXIS_RIGHT_STICK_X || + axis == Common::JOYSTICK_AXIS_RIGHT_STICK_Y || + axis == Common::JOYSTICK_AXIS_HAT_X || + axis == Common::JOYSTICK_AXIS_HAT_Y || + axis >= 8; +} + +Common::KeyCode getRebel2RawMenuAxisKey(int axis, int16 position) { + const bool horizontalAxis = axis == Common::JOYSTICK_AXIS_LEFT_STICK_X || + axis == Common::JOYSTICK_AXIS_RIGHT_STICK_X || + axis == Common::JOYSTICK_AXIS_HAT_X || + (axis >= 8 && (axis % 2) == 0); + const bool verticalAxis = axis == Common::JOYSTICK_AXIS_LEFT_STICK_Y || + axis == Common::JOYSTICK_AXIS_RIGHT_STICK_Y || + axis == Common::JOYSTICK_AXIS_HAT_Y || + (axis >= 8 && (axis % 2) != 0); + + if (!horizontalAxis && !verticalAxis) + return Common::KEYCODE_INVALID; + + if (position >= kRA2MenuAxisThreshold) + return horizontalAxis ? Common::KEYCODE_RIGHT : Common::KEYCODE_DOWN; + if (position <= -kRA2MenuAxisThreshold) + return horizontalAxis ? Common::KEYCODE_LEFT : Common::KEYCODE_UP; + + return Common::KEYCODE_INVALID; +} + +bool isRebel2MenuDirectionKey(Common::KeyCode keycode) { + return keycode == Common::KEYCODE_UP || + keycode == Common::KEYCODE_DOWN || + keycode == Common::KEYCODE_LEFT || + keycode == Common::KEYCODE_RIGHT; +} InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) { _vm = scumm; @@ -471,6 +512,8 @@ InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) { _joystickAxisX = 0; _joystickAxisY = 0; _gamepadAimActive = false; + _lastGameplayMenuCloseTime = 0; + _lastMenuGamepadNavigationTime = 0; // Initialize level state tracking for multi-phase levels _currentPhase = 1; @@ -525,6 +568,23 @@ InsaneRebel2::~InsaneRebel2() { } } +void InsaneRebel2::openGameplayMainMenu(SmushPlayer *splayer) { + if (!splayer) + return; + + if (_pauseOverlayActive) { + _vm->_system->getPaletteManager()->setPalette(_savedPausePalette, 0, 256); + _pauseOverlayActive = false; + } + + if (!splayer->_paused) + splayer->pause(); + + _vm->openMainMenuDialog(); + splayer->unpause(); + _lastGameplayMenuCloseTime = _vm->_system->getMillis(); +} + // notifyEvent -- EventObserver callback for global input dispatch. // Handles ESC (skip) and SPACE (pause) regardless of menu state. // Pause behavior matches original FUN_405A21: SPACE pauses, ANY key unpauses. @@ -558,11 +618,82 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { } } + if (_menuInputActive && event.type == Common::EVENT_JOYAXIS_MOTION) { + const int axis = event.joystick.axis; + + if (!isRebel2RawMenuAxis(axis)) + return false; + + const Common::KeyCode keycode = getRebel2RawMenuAxisKey(axis, event.joystick.position); + if (keycode == Common::KEYCODE_INVALID) + return true; + + const uint32 now = _vm->_system->getMillis(); + if (_lastMenuGamepadNavigationTime != 0 && + now - _lastMenuGamepadNavigationTime < kRA2MenuGamepadNavigationDebounceMs) + return true; + + _lastMenuGamepadNavigationTime = now; + Common::Event syntheticEvent = Common::Event(); + syntheticEvent.type = Common::EVENT_KEYDOWN; + syntheticEvent.kbd.keycode = keycode; + _menuEventQueue.push(syntheticEvent); + return true; + } + // Analog stick ??? reticle velocity (mirrors RA1's analog model). The mapped // axis actions carry a signed position; a centered stick reports position 0. // We ignore a recentre that would fight the opposite direction so a quick // flick doesn't get cancelled by the trailing zero of the other axis half. if (event.type == Common::EVENT_CUSTOM_BACKEND_ACTION_AXIS) { + if (_menuInputActive) { + if (event.joystick.position == 0) { + switch (event.customType) { + case kScummBackendActionRebel2AxisUp: + case kScummBackendActionRebel2AxisDown: + return true; + case kScummBackendActionRebel2AxisLeft: + case kScummBackendActionRebel2AxisRight: + return true; + default: + break; + } + return true; + } + + Common::KeyCode keycode = Common::KEYCODE_INVALID; + switch (event.customType) { + case kScummBackendActionRebel2AxisUp: + keycode = Common::KEYCODE_UP; + break; + case kScummBackendActionRebel2AxisDown: + keycode = Common::KEYCODE_DOWN; + break; + case kScummBackendActionRebel2AxisLeft: + keycode = Common::KEYCODE_LEFT; + break; + case kScummBackendActionRebel2AxisRight: + keycode = Common::KEYCODE_RIGHT; + break; + default: + break; + } + + if (keycode != Common::KEYCODE_INVALID) { + const uint32 now = _vm->_system->getMillis(); + if (_lastMenuGamepadNavigationTime != 0 && + now - _lastMenuGamepadNavigationTime < kRA2MenuGamepadNavigationDebounceMs) + return true; + + _lastMenuGamepadNavigationTime = now; + Common::Event syntheticEvent = Common::Event(); + syntheticEvent.type = Common::EVENT_KEYDOWN; + syntheticEvent.kbd.keycode = keycode; + _menuEventQueue.push(syntheticEvent); + return true; + } + } + const int16 axisPosition = (event.joystick.position == Common::JOYAXIS_MIN) ? Common::JOYAXIS_MAX : event.joystick.position; @@ -595,6 +726,67 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { if (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START || event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) { const bool pressed = (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START); + const bool menuState = _gameState == kStateMainMenu || + _gameState == kStatePilotSelect || + _gameState == kStateDifficultySelect || + _gameState == kStateChapterSelect || + _gameState == kStateOptions || + _gameState == kStateTopPilots; + + if (event.customType == kScummActionInsaneSkip) { + if (!pressed) + return true; + + if (_menuInputActive && menuState) { + Common::Event syntheticEvent = Common::Event(); + syntheticEvent.type = Common::EVENT_KEYDOWN; + syntheticEvent.kbd.keycode = Common::KEYCODE_ESCAPE; + syntheticEvent.kbd.ascii = Common::ASCII_ESCAPE; + _menuEventQueue.push(syntheticEvent); + return true; + } + + if (_gameState == kStateGameplay && _rebelHandler != 0) { + debug("Rebel2: Skip/back action ignored during gameplay"); + return true; + } + + debug("Rebel2: Skip/back action - skipping video"); + _vm->_smushVideoShouldFinish = true; + return true; + } + + if (event.customType == kScummActionInsaneBack) { + if (!pressed) + return true; + + if (_menuInputActive && menuState) { + Common::Event syntheticEvent = Common::Event(); + syntheticEvent.type = Common::EVENT_KEYDOWN; + syntheticEvent.kbd.keycode = Common::KEYCODE_ESCAPE; + syntheticEvent.kbd.ascii = Common::ASCII_ESCAPE; + _menuEventQueue.push(syntheticEvent); + return true; + } + + if (_gameState == kStateGameplay && _rebelHandler != 0) { + if (_lastGameplayMenuCloseTime != 0) { + const uint32 elapsedSinceMenuClose = _vm->_system->getMillis() - _lastGameplayMenuCloseTime; + if (elapsedSinceMenuClose < 500) { + debug("Rebel2: Ignoring repeated gameplay menu action (%u ms)", elapsedSinceMenuClose); + return true; + } + } + + debug("Rebel2: Back/menu action during gameplay - opening ScummVM menu"); + openGameplayMainMenu(splayer); + return true; + } + + debug("Rebel2: Back/menu action - skipping video"); + _vm->_smushVideoShouldFinish = true; + return true; + } if (pressed && splayer && splayer->_paused && _gameState == kStateGameplay) { debug("Rebel2: Joystick action while paused - unpausing"); @@ -634,6 +826,12 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { case kScummActionInsaneSwitch: keycode = Common::KEYCODE_ESCAPE; break; + case kScummActionInsaneBack: + keycode = Common::KEYCODE_ESCAPE; + break; + case kScummActionInsaneSkip: + keycode = Common::KEYCODE_ESCAPE; + break; default: break; } @@ -642,7 +840,9 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { case kStateTopPilots: if (event.customType == kScummActionInsaneAttack) keycode = Common::KEYCODE_RETURN; - else if (event.customType == kScummActionInsaneSwitch) + else if (event.customType == kScummActionInsaneSwitch || + event.customType == kScummActionInsaneBack || + event.customType == kScummActionInsaneSkip) keycode = Common::KEYCODE_ESCAPE; break; @@ -651,6 +851,14 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { } if (keycode != Common::KEYCODE_INVALID) { + if (isRebel2MenuDirectionKey(keycode)) { + const uint32 now = _vm->_system->getMillis(); + if (_lastMenuGamepadNavigationTime != 0 && + now - _lastMenuGamepadNavigationTime < kRA2MenuGamepadNavigationDebounceMs) + return true; + _lastMenuGamepadNavigationTime = now; + } + Common::Event syntheticEvent = Common::Event(); syntheticEvent.type = Common::EVENT_KEYDOWN; syntheticEvent.kbd.keycode = keycode; @@ -669,7 +877,40 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { // consumed (and returned true for) the cases they handle. } + const bool gameplayMenuTrigger = (event.type == Common::EVENT_MAINMENU) || + (event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE); + if (gameplayMenuTrigger && _gameState == kStateGameplay && _lastGameplayMenuCloseTime != 0) { + const uint32 elapsedSinceMenuClose = _vm->_system->getMillis() - _lastGameplayMenuCloseTime; + if (elapsedSinceMenuClose < 500) { + debug("Rebel2: Ignoring repeated gameplay menu trigger (%u ms)", elapsedSinceMenuClose); + return true; + } + } + + if (event.type == Common::EVENT_MAINMENU && splayer && + _gameState == kStateGameplay && _rebelHandler != 0) { + debug("Rebel2: Main menu action during gameplay - opening ScummVM menu"); + openGameplayMainMenu(splayer); + return true; + } + if (event.type == Common::EVENT_KEYDOWN) { + // Gamepad buttons mapped to ESC can lose their key-up while the GMM is open, + // leaving the key repeat source to synthesize another ESC immediately after + // returning to gameplay. Treat repeats as part of the original press. + if (event.kbd.keycode == Common::KEYCODE_ESCAPE && event.kbdRepeat) { + debug("Rebel2: Ignoring repeated ESC keydown"); + return true; + } + if (_menuInputActive && event.kbdRepeat && + (event.kbd.keycode == Common::KEYCODE_UP || + event.kbd.keycode == Common::KEYCODE_DOWN || + event.kbd.keycode == Common::KEYCODE_LEFT || + event.kbd.keycode == Common::KEYCODE_RIGHT)) { + debug("Rebel2: Ignoring repeated menu direction keydown"); + return true; + } + // When paused during gameplay, ANY key unpauses (FUN_405A21 line 360-365). // ESC additionally opens the ScummVM menu (original: quit key exits level). if (splayer && splayer->_paused && _gameState == kStateGameplay) { @@ -682,9 +923,7 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { splayer->unpause(); if (event.kbd.keycode == Common::KEYCODE_ESCAPE && _rebelHandler != 0) { debug("Rebel2: ESC during pause - opening ScummVM menu"); - splayer->pause(); - _vm->openMainMenuDialog(); - splayer->unpause(); + openGameplayMainMenu(splayer); } return true; } @@ -709,12 +948,7 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { } else if (_gameState == kStateGameplay && _rebelHandler != 0) { // During active gameplay (handler != 0): pause and open ScummVM menu. debug("Rebel2: ESC pressed during gameplay - opening ScummVM menu"); - bool wasPaused = splayer->_paused; - if (!wasPaused) - splayer->pause(); - _vm->openMainMenuDialog(); - if (!wasPaused) - splayer->unpause(); + openGameplayMainMenu(splayer); } else { // During cutscenes/intros/mission briefings: skip video debug("Rebel2: ESC pressed - skipping video"); @@ -762,12 +996,16 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) { switch (event.type) { case Common::EVENT_KEYDOWN: case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_MOUSEMOVE: case Common::EVENT_QUIT: case Common::EVENT_RETURN_TO_LAUNCHER: // Queue these events for processing in processMenuInput() _menuEventQueue.push(event); break; + case Common::EVENT_MOUSEMOVE: + if (_lastMenuGamepadNavigationTime == 0 || + _vm->_system->getMillis() - _lastMenuGamepadNavigationTime >= kRA2MenuGamepadMouseSuppressMs) + _menuEventQueue.push(event); + break; default: break; } diff --git a/engines/scumm/insane/rebel2/rebel.h b/engines/scumm/insane/rebel2/rebel.h index fefd80a6f96..926c23d69ab 100644 --- a/engines/scumm/insane/rebel2/rebel.h +++ b/engines/scumm/insane/rebel2/rebel.h @@ -510,6 +510,9 @@ public: // recenter the reticle (the cursor is locked ~center during gameplay, so a gamepad // "click" lands at center). See notifyEvent()/updateGameplayAimFromGamepad(). bool _gamepadAimActive; + uint32 _lastGameplayMenuCloseTime; + uint32 _lastMenuGamepadNavigationTime; + void openGameplayMainMenu(SmushPlayer *splayer); bool isBitSet(int n) override; void setBit(int n) override; diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp index 93e61776248..c43f81ea35d 100644 --- a/engines/scumm/metaengine.cpp +++ b/engines/scumm/metaengine.cpp @@ -1019,6 +1019,18 @@ Common::KeymapArray ScummMetaEngine::initKeymaps(const char *target) const { Common::String gameId = ConfMan.get("gameid", target); Action *act; + if (gameId == "rebel2") { + for (uint i = 0; i < keymaps.size(); ++i) { + if (keymaps[i]->getId() == "engine-default") { + delete keymaps.remove_at(i); + Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "engine-default", _("Default game keymappings")); + engineKeyMap->setPartialMatchAllowed(false); + keymaps.insert_at(i, engineKeyMap); + break; + } + } + } + if (gameId == "ft") { Keymap *insaneKeymap = new Keymap(Keymap::kKeymapTypeGame, insaneKeymapId, "SCUMM - Bike Fights"); @@ -1191,24 +1203,28 @@ Common::KeymapArray ScummMetaEngine::initKeymaps(const char *target) const { act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisUp); act->addDefaultInputMapping("JOY_LEFT_STICK_Y-"); act->addDefaultInputMapping("JOY_RIGHT_STICK_Y-"); + act->addDefaultInputMapping("JOY_HAT_Y-"); rebel2Keymap->addAction(act); act = new Action("RA2STICKDOWN", _("Stick down")); act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisDown); act->addDefaultInputMapping("JOY_LEFT_STICK_Y+"); act->addDefaultInputMapping("JOY_RIGHT_STICK_Y+"); + act->addDefaultInputMapping("JOY_HAT_Y+"); rebel2Keymap->addAction(act); act = new Action("RA2STICKLEFT", _("Stick left")); act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisLeft); act->addDefaultInputMapping("JOY_LEFT_STICK_X-"); act->addDefaultInputMapping("JOY_RIGHT_STICK_X-"); + act->addDefaultInputMapping("JOY_HAT_X-"); rebel2Keymap->addAction(act); act = new Action("RA2STICKRIGHT", _("Stick right")); act->setCustomBackendActionAxisEvent(kScummBackendActionRebel2AxisRight); act->addDefaultInputMapping("JOY_LEFT_STICK_X+"); act->addDefaultInputMapping("JOY_RIGHT_STICK_X+"); + act->addDefaultInputMapping("JOY_HAT_X+"); rebel2Keymap->addAction(act); act = new Action("RA2FIRE", _("Fire / select")); @@ -1218,12 +1234,20 @@ Common::KeymapArray ScummMetaEngine::initKeymaps(const char *target) const { act = new Action("RA2COVER", _("Cover / back")); act->setCustomEngineActionEvent(kScummActionInsaneSwitch); + act->addDefaultInputMapping("JOY_X"); + act->addDefaultInputMapping("JOY_Y"); + rebel2Keymap->addAction(act); + + act = new Action("RA2SKIP", _("Skip / back")); + act->setCustomEngineActionEvent(kScummActionInsaneSkip); act->addDefaultInputMapping("JOY_B"); + act->addDefaultInputMapping("JOY_RIGHT_TRIGGER"); + act->addDefaultInputMapping("AC_BACK"); rebel2Keymap->addAction(act); act = new Action("RA2BACK", _("Skip / menu")); - act->setKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE)); - act->addDefaultInputMapping("JOY_Y"); + act->setCustomEngineActionEvent(kScummActionInsaneBack); + act->addDefaultInputMapping("ESCAPE"); act->addDefaultInputMapping("JOY_START"); rebel2Keymap->addAction(act); diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 94ebcfc4a7a..ae7b4bb7cd1 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -499,6 +499,8 @@ enum ScummAction { kScummActionInsaneAttack, kScummActionInsaneSwitch, kScummActionInsaneCheat, + kScummActionInsaneBack, + kScummActionInsaneSkip, kScummActionCount }; From noreply at scummvm.org Mon Jun 1 16:27:26 2026 From: noreply at scummvm.org (ScummVM-Translations) Date: Mon, 1 Jun 2026 16:27:26 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> c03bb4f729c9ae5223e084ee90ceb3906df6ec2e Message-ID: <20260601162726.84AA27005BB@ron.scummvm.net> 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: c03bb4f729 I18N: Update translations templates Commit: c03bb4f729c9ae5223e084ee90ceb3906df6ec2e https://github.com/scummvm/scummvm/commit/c03bb4f729c9ae5223e084ee90ceb3906df6ec2e Author: Weblate (noreply at weblate.org) Date: 2026-06-01T16:27:20Z Commit Message: I18N: Update translations templates Changed paths: po/scummvm.pot diff --git a/po/scummvm.pot b/po/scummvm.pot index a0615fac668..27bbdefa188 100644 --- a/po/scummvm.pot +++ b/po/scummvm.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 2026.2.1git\n" "Report-Msgid-Bugs-To: scummvm-devel at lists.scummvm.org\n" -"POT-Creation-Date: 2026-06-01 14:35+0000\n" +"POT-Creation-Date: 2026-06-01 16:27+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1014,7 +1014,7 @@ msgstr "" #: engines/dragons/metaengine.cpp:158 engines/freescape/movement.cpp:35 #: engines/got/metaengine.cpp:70 engines/griffon/metaengine.cpp:121 #: engines/grim/grim.cpp:481 engines/grim/grim.cpp:563 engines/icb/icb.cpp:68 -#: engines/icb/icb.cpp:152 engines/scumm/metaengine.cpp:1064 +#: engines/icb/icb.cpp:152 engines/scumm/metaengine.cpp:1076 #: engines/supernova/metaengine.cpp:273 engines/twine/metaengine.cpp:430 #: engines/twine/metaengine.cpp:497 engines/twp/metaengine.cpp:154 #: engines/ultima/ultima0/metaengine.cpp:45 @@ -1035,7 +1035,7 @@ msgstr "" #: engines/dragons/metaengine.cpp:164 engines/freescape/movement.cpp:44 #: engines/got/metaengine.cpp:71 engines/griffon/metaengine.cpp:127 #: engines/grim/grim.cpp:486 engines/grim/grim.cpp:568 engines/icb/icb.cpp:73 -#: engines/icb/icb.cpp:157 engines/scumm/metaengine.cpp:1031 +#: engines/icb/icb.cpp:157 engines/scumm/metaengine.cpp:1043 #: engines/supernova/metaengine.cpp:279 engines/twine/metaengine.cpp:437 #: engines/twine/metaengine.cpp:505 engines/twp/metaengine.cpp:155 #: engines/ultima/ultima0/metaengine.cpp:46 @@ -1056,7 +1056,7 @@ msgstr "" #: engines/dragons/metaengine.cpp:170 engines/glk/dialogs.cpp:371 #: engines/got/metaengine.cpp:72 engines/griffon/metaengine.cpp:133 #: engines/grim/grim.cpp:491 engines/grim/grim.cpp:573 engines/icb/icb.cpp:78 -#: engines/icb/icb.cpp:162 engines/scumm/metaengine.cpp:1044 +#: engines/icb/icb.cpp:162 engines/scumm/metaengine.cpp:1056 #: engines/twine/metaengine.cpp:452 engines/twine/metaengine.cpp:520 #: engines/twp/metaengine.cpp:152 engines/ultima/ultima4/metaengine.cpp:46 #: engines/ultima/ultima4/metaengine.cpp:141 @@ -1076,7 +1076,7 @@ msgstr "" #: engines/dragons/metaengine.cpp:176 engines/glk/dialogs.cpp:373 #: engines/got/metaengine.cpp:73 engines/griffon/metaengine.cpp:139 #: engines/grim/grim.cpp:496 engines/grim/grim.cpp:578 engines/icb/icb.cpp:83 -#: engines/icb/icb.cpp:167 engines/scumm/metaengine.cpp:1051 +#: engines/icb/icb.cpp:167 engines/scumm/metaengine.cpp:1063 #: engines/twine/metaengine.cpp:444 engines/twine/metaengine.cpp:513 #: engines/twp/metaengine.cpp:153 engines/ultima/ultima4/metaengine.cpp:47 #: engines/ultima/ultima4/metaengine.cpp:142 @@ -3589,6 +3589,7 @@ msgid "Game not implemented" msgstr "" #: engines/metaengine.cpp:75 engines/saga/metaengine.cpp:267 +#: engines/scumm/metaengine.cpp:1026 msgid "Default game keymappings" msgstr "" @@ -6795,7 +6796,7 @@ msgstr "" #: engines/bladerunner/metaengine.cpp:229 engines/buried/metaengine.cpp:160 #: engines/darkseed/metaengine.cpp:65 engines/hypno/metaengine.cpp:152 #: engines/phoenixvr/metaengine.cpp:85 engines/scumm/help.cpp:79 -#: engines/scumm/metaengine.cpp:1090 engines/supernova/metaengine.cpp:309 +#: engines/scumm/metaengine.cpp:1102 engines/supernova/metaengine.cpp:309 #: engines/toltecs/metaengine.cpp:246 engines/twp/metaengine.cpp:162 #: engines/zvision/metaengine.cpp:304 msgid "Skip cutscene" @@ -7442,7 +7443,7 @@ msgstr "" #. I18N: Combat command in Might & Magic 1 #: engines/crab/input/input.cpp:125 engines/efh/metaengine.cpp:487 #: engines/efh/metaengine.cpp:512 engines/griffon/metaengine.cpp:145 -#: engines/mm/mm1/metaengine.cpp:70 engines/scumm/metaengine.cpp:1077 +#: engines/mm/mm1/metaengine.cpp:70 engines/scumm/metaengine.cpp:1089 #: engines/ultima/ultima0/metaengine.cpp:82 #: engines/ultima/ultima4/metaengine.cpp:48 #: engines/ultima/nuvie/metaengine.cpp:74 @@ -12392,84 +12393,88 @@ msgstr "" msgid "All levels will be available without requiring passwords" msgstr "" -#: engines/scumm/metaengine.cpp:1025 +#: engines/scumm/metaengine.cpp:1037 msgid "Down left" msgstr "" -#: engines/scumm/metaengine.cpp:1038 +#: engines/scumm/metaengine.cpp:1050 msgid "Down right" msgstr "" -#: engines/scumm/metaengine.cpp:1058 +#: engines/scumm/metaengine.cpp:1070 msgid "Up left" msgstr "" -#: engines/scumm/metaengine.cpp:1071 +#: engines/scumm/metaengine.cpp:1083 msgid "Up right" msgstr "" -#: engines/scumm/metaengine.cpp:1083 +#: engines/scumm/metaengine.cpp:1095 msgid "Switch weapon" msgstr "" #. I18N: Lets one skip the bike/car fight sequences in Full Throttle -#: engines/scumm/metaengine.cpp:1097 +#: engines/scumm/metaengine.cpp:1109 msgid "Win the bike fight cheat" msgstr "" -#: engines/scumm/metaengine.cpp:1106 +#: engines/scumm/metaengine.cpp:1118 msgid "Rebel Assault controls" msgstr "" -#: engines/scumm/metaengine.cpp:1108 engines/scumm/metaengine.cpp:1170 +#: engines/scumm/metaengine.cpp:1120 engines/scumm/metaengine.cpp:1182 msgid "Aim up / menu up" msgstr "" -#: engines/scumm/metaengine.cpp:1113 engines/scumm/metaengine.cpp:1175 +#: engines/scumm/metaengine.cpp:1125 engines/scumm/metaengine.cpp:1187 msgid "Aim down / menu down" msgstr "" -#: engines/scumm/metaengine.cpp:1118 engines/scumm/metaengine.cpp:1180 +#: engines/scumm/metaengine.cpp:1130 engines/scumm/metaengine.cpp:1192 msgid "Aim left / menu left" msgstr "" -#: engines/scumm/metaengine.cpp:1123 engines/scumm/metaengine.cpp:1185 +#: engines/scumm/metaengine.cpp:1135 engines/scumm/metaengine.cpp:1197 msgid "Aim right / menu right" msgstr "" -#: engines/scumm/metaengine.cpp:1128 engines/scumm/metaengine.cpp:1190 +#: engines/scumm/metaengine.cpp:1140 engines/scumm/metaengine.cpp:1202 msgid "Stick up" msgstr "" -#: engines/scumm/metaengine.cpp:1134 engines/scumm/metaengine.cpp:1196 +#: engines/scumm/metaengine.cpp:1146 engines/scumm/metaengine.cpp:1209 msgid "Stick down" msgstr "" -#: engines/scumm/metaengine.cpp:1140 engines/scumm/metaengine.cpp:1202 +#: engines/scumm/metaengine.cpp:1152 engines/scumm/metaengine.cpp:1216 msgid "Stick left" msgstr "" -#: engines/scumm/metaengine.cpp:1146 engines/scumm/metaengine.cpp:1208 +#: engines/scumm/metaengine.cpp:1158 engines/scumm/metaengine.cpp:1223 msgid "Stick right" msgstr "" -#: engines/scumm/metaengine.cpp:1152 engines/scumm/metaengine.cpp:1214 +#: engines/scumm/metaengine.cpp:1164 engines/scumm/metaengine.cpp:1230 msgid "Fire / select" msgstr "" -#: engines/scumm/metaengine.cpp:1157 +#: engines/scumm/metaengine.cpp:1169 msgid "Back / skip" msgstr "" -#: engines/scumm/metaengine.cpp:1168 +#: engines/scumm/metaengine.cpp:1180 msgid "Rebel Assault II controls" msgstr "" -#: engines/scumm/metaengine.cpp:1219 +#: engines/scumm/metaengine.cpp:1235 msgid "Cover / back" msgstr "" -#: engines/scumm/metaengine.cpp:1224 +#: engines/scumm/metaengine.cpp:1241 +msgid "Skip / back" +msgstr "" + +#: engines/scumm/metaengine.cpp:1248 msgid "Skip / menu" msgstr "" From noreply at scummvm.org Mon Jun 1 16:28:00 2026 From: noreply at scummvm.org (ScummVM-Translations) Date: Mon, 1 Jun 2026 16:28:00 +0000 (UTC) Subject: [Scummvm-git-logs] scummvm master -> 0a62c03c18eb7cc033b8906d7bf5bf7c41de2ed1 Message-ID: <20260601162800.D8DC5700591@ron.scummvm.net> 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: 0a62c03c18 I18N: Update translation files Commit: 0a62c03c18eb7cc033b8906d7bf5bf7c41de2ed1 https://github.com/scummvm/scummvm/commit/0a62c03c18eb7cc033b8906d7bf5bf7c41de2ed1 Author: Weblate (noreply at weblate.org) Date: 2026-06-01T16:27:40Z Commit Message: I18N: Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: ScummVM/scummvm Translate-URL: https://translations.scummvm.org/projects/scummvm/scummvm/ Changed paths: po/ar.po po/be-tarask.po po/be_BY.po po/ca_ES.po po/cs_CZ.po po/da.po po/de_DE.po po/el.po po/es_ES.po po/eu.po po/fi_FI.po po/fr_FR.po po/gl_ES.po po/he.po po/hi.po po/hu_HU.po po/it_IT.po po/ja.po po/ka.po po/ko.po po/nb_NO.po po/nl_NL.po po/nn_NO.po po/pl_PL.po po/pt_BR.po po/pt_PT.po po/ro.po po/ru_RU.po po/sv_SE.po po/tr.po po/uk_UA.po po/zh.po po/zh_Hans.po po/zh_Hant.po diff --git a/po/ar.po b/po/ar.po index fc404c6b896..ff95d404548 100644 --- a/po/ar.po +++ b/po/ar.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 2.8.0git\n" "Report-Msgid-Bugs-To: scummvm-devel at lists.scummvm.org\n" -"POT-Creation-Date: 2026-06-01 14:35+0000\n" +"POT-Creation-Date: 2026-06-01 16:27+0000\n" "PO-Revision-Date: 2026-02-24 22:26+0000\n" "Last-Translator: Mohamed Shaaban \n" "Language-Team: Arabic \n" "Language-Team: Belarusian (Tara??kievica) \n" "Language-Team: Belarusian \n" "Language-Team: Catalan \n" "Language-Team: Czech \n" "Language-Team: Danish \n" "Language-Team: German \n" "Language-Team: Greek \n" "Language-Team: Spanish \n" "Language-Team: Basque \n" "Language-Team: Finnish \n" "Language-Team: French \n" "Language-Team: Galician \n" "Language-Team: Hebrew \n" "Language-Team: Hindi