The recovered system: fire channels = LBE4ControlsManager buttonGroups (0x40/0x45/0x46/0x47); default groups = the per-mech type-6 controls-map resource in BTL4.RES, installed by the T0 CreateStreamedMappings the port already called -- it needed only the TriggerState attribute (id 0x13 PINNED to the binary value; fireImpulse@0x31C is the binary's TriggerState) and an input feed. Keyboard/harness now push press/release edges into the button groups; the gBT*Trigger bypasses, per-type keyboard split and 1,0 pulse hack are retired -- weapons sharing a button fire TOGETHER (madcat Trigger = 4 weapons). Myomers @4b9550/@4b95b8 misattribution corrected (they are MechWeapon ConfigureMappables/ChooseButton). Verified 2-node: kill through the authentic chain (12 hits vs ~36 pre-groups). Config-mode session (regrouping UI) = the remaining stage, KB-scoped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
import sys, re
|
|
from capstone import Cs, CS_ARCH_X86, CS_MODE_32
|
|
|
|
DUMP = r"C:/git/bt411/reference/decomp/section_dump.txt"
|
|
|
|
def load_bytes():
|
|
mem = {}
|
|
pat = re.compile(r'^ ([0-9a-f]{6,8}) ((?:[0-9a-f ]{8} ?){1,4})')
|
|
with open(DUMP) as f:
|
|
for line in f:
|
|
m = pat.match(line)
|
|
if not m:
|
|
continue
|
|
addr = int(m.group(1), 16)
|
|
hexpart = m.group(2).replace(' ', '')
|
|
data = bytes.fromhex(hexpart)
|
|
mem[addr] = data
|
|
return mem
|
|
|
|
def extract(mem, start, end):
|
|
out = bytearray()
|
|
addr = start
|
|
# dump lines are 16 bytes each, aligned to line starts; build a flat map
|
|
flat = {}
|
|
for a, d in mem.items():
|
|
for i, b in enumerate(d):
|
|
flat[a+i] = b
|
|
for a in range(start, end):
|
|
out.append(flat.get(a, 0x90))
|
|
return bytes(out)
|
|
|
|
def main():
|
|
start = int(sys.argv[1], 16)
|
|
end = int(sys.argv[2], 16)
|
|
mem = load_bytes()
|
|
code = extract(mem, start, end)
|
|
md = Cs(CS_ARCH_X86, CS_MODE_32)
|
|
md.detail = False
|
|
for ins in md.disasm(code, start):
|
|
print("%08x: %-8s %s" % (ins.address, ins.mnemonic, ins.op_str))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|