diff --git a/config/decl-agreement-baseline.json b/config/decl-agreement-baseline.json index 60d56b44e2..30fe972ceb 100644 --- a/config/decl-agreement-baseline.json +++ b/config/decl-agreement-baseline.json @@ -14379,19 +14379,11 @@ "src/unnamed/ov063/func_ov063_02118ddc.cpp": ["param:#1 int", "param:#2 char *", "return:int"] }, "func_02012718": { - "include/decl_common.h": ["param:#1 int"], - "src/actors/dMgJump3DMario_c.cpp": ["param:#1 int"], - "src/actors/dScMgCurling2_c.cpp": ["param:#1 int"], - "src/func_ov006_020cb838.cpp": ["param:#1 int"], - "src/func_ov006_020cbd7c.cpp": ["param:#1 int"], - "src/func_ov006_020d1ba0.cpp": ["param:#1 int"], - "src/func_ov006_020e1854.c": ["param:#1 int"], - "src/func_ov006_020e1dc8.cpp": ["param:#1 int"], - "src/func_ov006_020fd17c.c": ["param:#1 int"], - "src/func_ov006_0210076c.c": ["param:#1 int"], - "src/func_ov006_02102d6c.c": ["param:#1 int", "param:#2 unsigned int"], - "src/func_ov006_02125f68.cpp": ["param:#1 int"], - "src/minigames/d_s_mg_trampoline.cpp": ["param:#1 int"] + "src/_ZN12dScMgSlot1_c8BehaviorEv.cpp": ["param:#1 void *"], + "src/func_ov006_020d27dc.cpp": ["param:#1 void *"], + "src/func_ov006_020e20bc.c": ["param:#1 void *"], + "src/func_ov006_020e5450.cpp": ["param:#1 void *"], + "src/func_ov006_020fdaf0.c": ["param:#1 void *"] }, "func_0201277c": { "include/decl_common.h": ["param:#1 int"], @@ -14490,8 +14482,7 @@ "src/minigames/d_s_mg_memory.cpp": ["param:#1 int", "return:void"] }, "func_020127ec": { - "src/func_020126ac.c": ["return:int"], - "src/func_02012718.c": ["param:#2 void *"] + "src/func_020126ac.c": ["return:int"] }, "func_02012dd0": { "src/func_ov004_020aeb24.cpp": ["param:#1 int"], @@ -19174,9 +19165,6 @@ "func_ov006_020e513c": { "src/func_ov006_020e5e3c.c": ["param:#1 char *"] }, - "func_ov006_020e5450": { - "src/func_ov006_020e5b70.c": ["arity:0"] - }, "func_ov006_020e6118": { "src/func_ov006_020e5ffc.c": ["param:#1 char *"] }, diff --git a/config/match_attempts.jsonl b/config/match_attempts.jsonl index 98176ddd6b..a5f17a0fa8 100644 --- a/config/match_attempts.jsonl +++ b/config/match_attempts.jsonl @@ -1697,7 +1697,7 @@ {"schemaVersion":1,"functionId":"ov006:0x020e513c","id":"ov006:0x020e513c","attemptId":"a728fff7fe434b769644da66a49eff3a","parentAttemptId":null,"module":"ov006","addr":34492732,"name":"func_ov006_020e513c","status":"no_progress","kind":"ai","model":"grok-4.6","reasoning":"high","harness":"grok-build","author":"lunavyqo","divergences":291,"improvedNearMiss":false,"srcPath":"scratch/func_ov006_020e513c.c","note":"two-pass 0x30-slot push; s64 scale*0x1a+0x800; prop+SR off for self/off shuffle; frame 0x28 vs 0x1c, idx stacked not fp, z/x load order, size 0x31c vs 0x314","usedNearMissDraft":false,"usedGhidraDraft":true,"base":{"kind":"scratch"},"sessionScope":"focused","batchSize":1} {"schemaVersion":1,"functionId":"ov006:0x020ea914","id":"ov006:0x020ea914","attemptId":"35a672d341e34aab9871d05a45a688c4","parentAttemptId":null,"module":"ov006","addr":34515220,"name":"func_ov006_020ea914","status":"near_miss","kind":"ai","model":"grok-4.6","reasoning":"high","harness":"grok-build","author":"lunavyqo","divergences":113,"prevBestDivergences":999,"improvedNearMiss":true,"srcPath":"try/func_ov006_020ea914.c","note":"size-exact 0x324; first loop byte-OK; i@sb; shape-identical; residual coloring (n4000 spilled, p1000@r4, -1@fp, A@r8, B@r7). SR-off + pts[5][2] + volatile pos.","usedNearMissDraft":false,"usedGhidraDraft":true,"base":{"kind":"matched_sibling"},"sessionScope":"focused","batchSize":1} {"schemaVersion":1,"functionId":"ov006:0x020ea914","id":"ov006:0x020ea914","attemptId":"540a2223d34849d4a09be3526e0ea65d","parentAttemptId":"35a672d341e34aab9871d05a45a688c4","module":"ov006","addr":34515220,"name":"func_ov006_020ea914","status":"no_progress","kind":"ai","model":"grok-4.6","reasoning":"high","harness":"grok-build","author":"lunavyqo","divergences":113,"prevBestDivergences":113,"improvedNearMiss":false,"srcPath":"try/func_ov006_020ea914.c","note":"permuter ~1000it floor score 2020->1220 (size 0x328, not a match.py win). Residual coloring: n4000 spilled vs r4, p1000@r4 vs fp, -1@fp vs stack, A@r8/B@r7 vs r6/r5.","usedNearMissDraft":false,"usedGhidraDraft":true,"base":{"kind":"previous_attempt","attemptId":"35a672d341e34aab9871d05a45a688c4","divergences":113},"sessionScope":"focused","batchSize":1} -{"schemaVersion":1,"functionId":"ov006:0x020e5450","id":"ov006:0x020e5450","attemptId":"0e798b61bcba4bd9a20bba0e038588a3","parentAttemptId":null,"module":"ov006","addr":34493520,"name":"func_ov006_020e5450","status":"near_miss","kind":"ai","model":"grok-4.6","reasoning":"high","harness":"grok-build","author":"lunavyqo","divergences":29,"improvedNearMiss":false,"srcPath":"build/func_ov006_020e5450.c","note":"common_subs off; for-loop with found body inside; slot=self+m forms px/pz; loop guards via p+0x4689 split. Prologue and loop tests byte-ok except branch offsets. Residual: z/x pair load order, frame 0x64 vs 0x7c, size 0x52c vs 0x560, found-body s64/pointer schedule.","usedNearMissDraft":false,"usedGhidraDraft":true,"base":{"kind":"scratch"},"sessionScope":"focused","batchSize":1} +{"schemaVersion": 1, "functionId": "ov006:0x020e5450", "id": "ov006:0x020e5450", "attemptId": "0e798b61bcba4bd9a20bba0e038588a3", "parentAttemptId": null, "module": "ov006", "addr": 34493520, "name": "func_ov006_020e5450", "status": "near_miss", "kind": "ai", "model": "grok-4.6", "reasoning": "high", "harness": "grok-build", "author": "lunavyqo", "divergences": null, "improvedNearMiss": false, "srcPath": "build/func_ov006_020e5450.c", "note": "common_subs off; for-loop with found body inside; slot=self+m forms px/pz; loop guards via p+0x4689 split. Prologue and loop tests byte-ok except branch offsets. Residual: z/x pair load order, frame 0x64 vs 0x7c, size 0x52c vs 0x560, found-body s64/pointer schedule. [CORRECTION 2026-09-13: this row recorded divergences 29. The note above records \"size 0x52c vs 0x560\", i.e. the candidate was 52 bytes shorter than the target, so the 29 was a truncated verdict scored over a window 52 bytes short of the function and is not a divergence count for func_ov006_020e5450. The field is cleared rather than rescored because this attempt's source (build/func_ov006_020e5450.c) is no longer in the tree. The honest measurement at the exact size 0x560 is 191 divergent words of 344, banked in nearmiss/db.jsonl and logged as a separate attempt row.]", "usedNearMissDraft": false, "usedGhidraDraft": true, "base": {"kind": "scratch"}, "sessionScope": "focused", "batchSize": 1, "size": 1376} {"schemaVersion":1,"functionId":"arm9:0x020717c0","id":"arm9:0x020717c0","attemptId":"fab1390a-e07c-47f9-8d16-9ef75722f2c1","parentAttemptId":null,"module":"arm9","addr":34019264,"name":"func_020717c0","status":"near_miss","kind":"ai","model":"grok-4.6","reasoning":"high","harness":"grok-build","author":"lunavyqo","divergences":999,"improvedNearMiss":true,"srcPath":"scratch/func_020717c0.c","note":"0x70 int[28] frame, uninit locals for r4-r11 slots, old-sp as ctx+28, three zero words, call callee. size 0x58 vs 0x4c (stmdb lr + epilogue; slots all r3).","usedNearMissDraft":false,"usedGhidraDraft":false,"base":{"kind":"scratch"},"sessionScope":"focused","batchSize":1} {"schemaVersion":1,"functionId":"arm9:0x020717c0","id":"arm9:0x020717c0","attemptId":"d0ddf7e6-399c-4735-9c48-1cd8b3a71266","parentAttemptId":"fab1390a-e07c-47f9-8d16-9ef75722f2c1","module":"arm9","addr":34019264,"name":"func_020717c0","status":"no_progress","kind":"ai","model":"grok-4.6","reasoning":"high","harness":"grok-build","author":"lunavyqo","divergences":999,"prevBestDivergences":999,"improvedNearMiss":false,"srcPath":"scratch/func_020717c0_inf.c","note":"for(;;) after call drops add/ldm/bx; size 0x50 still vs 0x4c. leftover stmdb lr + b-self; still r3 slots not r4-r11; no str lr / mov ip,sp.","usedNearMissDraft":false,"usedGhidraDraft":false,"base":{"kind":"previous_attempt","attemptId":"fab1390a-e07c-47f9-8d16-9ef75722f2c1","divergences":999},"sessionScope":"focused","batchSize":1} {"schemaVersion":1,"functionId":"arm9:0x020717c0","id":"arm9:0x020717c0","attemptId":"9afdb424-2280-4e56-af1b-4073084e1ca5","parentAttemptId":"fab1390a-e07c-47f9-8d16-9ef75722f2c1","module":"arm9","addr":34019264,"name":"func_020717c0","status":"no_progress","kind":"ai","model":"grok-4.6","reasoning":"high","harness":"grok-build","author":"lunavyqo","divergences":999,"prevBestDivergences":999,"improvedNearMiss":false,"srcPath":"scratch/func_020717c0_throw.cpp","note":"C++ throw; is a 0xc long-call veneer to this symbol, not the body.","usedNearMissDraft":false,"usedGhidraDraft":false,"base":{"kind":"previous_attempt","attemptId":"fab1390a-e07c-47f9-8d16-9ef75722f2c1","divergences":999},"sessionScope":"focused","batchSize":1} @@ -2071,6 +2071,7 @@ {"schemaVersion":1,"functionId":"ov021:0x021116c8","id":"ov021:0x021116c8","attemptId":"97b2e23cebb04fde8edab07ab51a23a5","parentAttemptId":"1ab94e30c7d64f2e8a6159bc347d02fa","module":"ov021","addr":34674376,"name":"_ZN12WorkElevator8BehaviorEv","status":"matched","kind":"human","author":"tangosdev","improvedNearMiss":false,"srcPath":"src/_ZN12WorkElevator8BehaviorEv.cpp","label":"m100-rest3","note":"Converted the tracked NONMATCHING attempt into a relocation-verified C++ method.","usedNearMissDraft":true,"base":{"kind":"previous_attempt","attemptId":"1ab94e30c7d64f2e8a6159bc347d02fa"},"sessionScope":"batch","batchSize":4} {"schemaVersion":1,"functionId":"ov004:0x020ae5c4","id":"ov004:0x020ae5c4","attemptId":"039f4f45697847119e8467c46b7422fa","parentAttemptId":"ae9efdbd99be49839f66a097fe8e19a7","module":"ov004","addr":34268612,"name":"func_ov004_020ae5c4","status":"matched","kind":"human","author":"tangosdev","improvedNearMiss":false,"srcPath":"src/func_ov004_020ae5c4.cpp","label":"m100-rest3","note":"Refined the tracked near-miss to a relocation-verified match.","usedNearMissDraft":true,"base":{"kind":"previous_attempt","attemptId":"ae9efdbd99be49839f66a097fe8e19a7"},"sessionScope":"batch","batchSize":4} {"schemaVersion":1,"functionId":"ov006:0x0212a764","id":"ov006:0x0212a764","attemptId":"5f9e263893044a37b21e12b9eb1cdcf2","parentAttemptId":"b18e76db9d244203b1927b594716d343","module":"ov006","addr":34776932,"name":"func_ov006_0212a764","status":"matched","kind":"human","author":"tangosdev","divergences":0,"prevBestDivergences":44,"improvedNearMiss":true,"srcPath":"src/func_ov006_0212a764.cpp","label":"m100-ov63a","note":"Final exact source from the OV63 lane; relocation-aware header fan-out verification included.","usedNearMissDraft":true,"base":{"kind":"previous_attempt","attemptId":"b18e76db9d244203b1927b594716d343","divergences":44},"sessionScope":"batch","batchSize":4} +{"schemaVersion":1,"functionId":"ov006:0x020e5450","id":"ov006:0x020e5450","attemptId":"dd3f356375e7438d92ac4c9433f6bc77","parentAttemptId":null,"module":"ov006","addr":34493520,"name":"func_ov006_020e5450","status":"near_miss","kind":"ai","model":"claude-opus-5","reasoning":"high","harness":"claude-code","author":"andrewboudreau","divergences":191,"prevBestDivergences":191,"improvedNearMiss":false,"note":"Re-measurement at the EXACT ROM size 0x560 (1376 bytes, 344 words): 191 divergent words of 344 under the banked evaluator 2004/b56 metric 2. Supersedes the cleared 29 on attempt 0e798b61bcba4bd9a20bba0e038588a3, which was scored over a 0x52c candidate against the 0x560 target and was therefore a truncated verdict, not a divergence count. Source is the banked c_source for ov006:0x020e5450 in nearmiss/db.jsonl; the bank row already reads 191 and is unchanged. The structurally better 193 variant (object hash db5e3dcf) is the cell notes/mwccarm-codegen.md section 6cz identifies as schedule-exact but hiding a two-register swap of the two i-loads; 6cz carries that line further to 187, so consult it rather than re-deriving from this row.","usedGhidraDraft":false,"base":{"kind":"near_miss_draft"},"sessionScope":"focused","batchSize":1} {"schemaVersion": 1, "functionId": "ov006:0x0211e72c", "id": "ov006:0x0211e72c", "attemptId": "68ddb5ba2b6b4377ac70616f731c42bd", "parentAttemptId": "05d30e71fc614dd099be509a09fda4e1", "module": "ov006", "addr": 34727724, "name": "func_ov006_0211e72c", "status": "near_miss", "kind": "ai", "model": "claude-opus-5", "harness": "claude-code", "author": "Claude", "divergences": 22, "prevBestDivergences": 26, "improvedNearMiss": true, "usedNearMissDraft": true, "label": "laneC-ov006 e72c-0913", "note": "26 -> 22 (-4 on the attempts ledger; the near-miss bank row was 27 and re-scores to exactly 27 under this evaluator, so -5 there). Source banked in nearmiss/db.jsonl, which carries the full floor prose. Two paying levers: a four-of-six `volatile` mask on the field loads (x/lo/hi/y volatile, gate/flag/priority plain) acting as a SCHEDULING BARRIER that pins load order without changing an emitted instruction, and the mode-select polarity `int mode = 1; if (flag == 0) mode = -1;`. The better row to hand on is NOT the banked 22: a 26-scoring variant (banked source + volatile flag + that mode polarity + inline array subscript instead of a tbl local) reproduces push/sub sp,#0x1c/ldr fp,[pc,#0x90]/epilogue/bx lr byte-exactly and is the ROM function with exactly one callee-saved rank-list element displaced -- the -1 sits at rank 2 and belongs at rank 6. Open question: produce a -1 whose first use is at argument 10 while argument 5 still emits -1. Scope limit measured here: callee-saved rank is set by order of first USE in the loop body, not declaration order, because mwcc constant-propagates function-scope constant locals and erases the declaration before allocation; the declaration rule is still live for the locals that survive to allocation (reversing declaration order moved cnt and tbl, 22 -> 25). Exhausted: the entire callee signature (14 variants, all identical; arity independently settled by the callee's own source and by a module-constrained census of OAM::Render's 131 call sites, 71 arm9-resident, r0-r3 at 131/131), 210 inner declaration permutations, six function-scope orders, twelve spellings of the -1, eleven mode spellings, 20 pragmas, and a 700-sample randomized structural search that peaked at 24.", "base": {"kind": "previous_attempt", "attemptId": "05d30e71fc614dd099be509a09fda4e1", "divergences": 26}, "sessionScope": "single"} {"schemaVersion":1,"functionId":"ov071:0x02121734","id":"ov071:0x02121734","attemptId":"60d147ec2c8c40bebd93fb90446f8719","parentAttemptId":null,"module":"ov071","addr":34740020,"name":"_ZN3MrI13InitResourcesEv","status":"matched","kind":"ai","model":"claude-opus-5","reasoning":"high","harness":"claude-code","author":"andrewboudreau","improvedNearMiss":false,"srcPath":"src/_ZN3MrI13InitResourcesEv.cpp","note":"banked","base":{"kind":"scratch"},"sessionScope":"focused","batchSize":1} {"schemaVersion":1,"functionId":"arm9:0x0202cc0c","id":"arm9:0x0202cc0c","attemptId":"f4bcf77d3d6f4445b520ab5bf714b10c","parentAttemptId":null,"module":"arm9","addr":33737740,"name":"_ZN5Stage13InitResourcesEv","status":"matched","kind":"ai","model":"claude-opus-5","reasoning":"high","harness":"claude-code","author":"tangosdev","improvedNearMiss":false,"srcPath":"src/_ZN5Stage13InitResourcesEv.cpp","note":"banked","base":{"kind":"scratch"},"sessionScope":"focused","batchSize":1} diff --git a/config/tu_manifest.d/ov006/dScMgCurling2_c.json b/config/tu_manifest.d/ov006/dScMgCurling2_c.json index f2e3b3d818..40af465c9b 100644 --- a/config/tu_manifest.d/ov006/dScMgCurling2_c.json +++ b/config/tu_manifest.d/ov006/dScMgCurling2_c.json @@ -8,7 +8,7 @@ "boundary_evidence": [ "PARTIAL RUN, 31 of 52. tools/tu_map.py calls 0x020e3854..0x020e6bf4 one contiguous linker run of 52 function(s) (build/tu_map.json), and queue_audit.py extends it over the zero-gap factory dScMgCurling2_c_classInit at 0x020e6bf4 for 53 in a 0x020e3854..0x020e6c28 span. This TU licenses 0x020e3854..0x020e5450, 31 function(s), ROM ordinals 0..30. The other 21 keep their own shards and their own delinks.txt entries; the 22nd is the sourceless hole in EDGE 1 below, which has neither.", "class label(s): dScMgCurling2_c", - "EDGE 1 -- a sourceless hole splits the run, and it is the only edge. ROM ordinal 31, func_ov006_020e5450 (0x020e5450, size 0x560), has no source anywhere in the tree: it carries a symbols.txt row but NO src/ file and NO entry in config/arm9/overlays/ov006/delinks.txt at all (the blocks jump from 0x020e513c-0x020e5450 straight to 0x020e59b0), so the cartridge's own bytes cover that range. It is a banked near-miss whose best recorded attempt sits at 29 divergences (config/match_attempts.jsonl). It sits in the MIDDLE of the run, and no delink block and no TU manifest in this tree expresses a .text claim with a hole in it, so the run can only be licensed as one of its two contiguous sides.", + "EDGE 1 -- a sourceless hole splits the run, and it is the only edge. ROM ordinal 31, func_ov006_020e5450 (0x020e5450, size 0x560), has no source anywhere in the tree: it carries a symbols.txt row but NO src/ file and NO entry in config/arm9/overlays/ov006/delinks.txt at all (the blocks jump from 0x020e513c-0x020e5450 straight to 0x020e59b0), so the cartridge's own bytes cover that range. It is a banked near-miss measured at 191 divergent words of 344 at the exact size 0x560 (nearmiss/db.jsonl). An older config/match_attempts.jsonl row read 29, but that attempt was scored over a 0x52c candidate against the 0x560 target, so the 29 was a truncated verdict and not a divergence count for this function; that row's divergences field has been cleared. It sits in the MIDDLE of the run, and no delink block and no TU manifest in this tree expresses a .text claim with a hole in it, so the run can only be licensed as one of its two contiguous sides.", "WHY THE LOWER SIDE. This TU is the larger side by member count: 31 below the hole against 21 above it. It is also the side that holds the class's key function -- the destructor, which include/dScMgCurling2_c.h declares out of line and declares FIRST -- so it is the side that can emit and license the class's _ZTV/_ZTI/_ZTS. It is the larger side in bytes too: 0x1bfc against the upper side's 0x1278. The upper side holds four of the six own vtable overrides (InitResources, Behavior, Render, OnYoshiTryEat) and the classInit factory, but not the key function, so a promotion there would carry compiler_only_output: 0 -- the dScMgCoin_c outcome -- and would leave the destructor pair enrolled as shards.", "module sinit corroboration: 31 sinit(s) / 31 .ctor entries, sinit_vs_tu=ok, corroborated=False (module-wide, NOT narrowed to this one TU -- see notes/tu-reconstruction-pilot-report.md sec 2 for the by-hand narrowing step)" ], diff --git a/nearmiss/db.jsonl b/nearmiss/db.jsonl index 5b3ea1404f..3ff210d022 100644 --- a/nearmiss/db.jsonl +++ b/nearmiss/db.jsonl @@ -10,7 +10,7 @@ {"module": "ov002", "addr": 34447340, "name": "_ZN6Player19St_SwingPlayer_MainEv", "size": 964, "lang": "cpp", "divergences": 8, "c_source": "//cpp\ntypedef int s32;\ntypedef short s16;\ntypedef unsigned int u32;\ntypedef unsigned short u16;\ntypedef unsigned char u8;\ntypedef s32 Fix12;\n\nstruct Vec3 { int x, y, z; };\n\n\nextern \"C\" {\nextern int _ZN6Player12FinishedAnimEv(char* c);\nextern void _ZN6Player7SetAnimEji5Fix12IiEj(char* c, u32 anim, int a, s32 b, u32 d);\nextern void func_ov002_020d9c70(char* c);\nextern int func_ov002_020da95c(char* c);\nextern void func_ov002_020da9d4(char* c);\nextern void _Z15ApproachLinear2Rsss(s16* ref, s16 target, s16 step);\nextern u32 _ZN8Particle6System3NewEjj5Fix12IiES2_S2_PK11Vector3_16fPNS_8CallbackE(u32 h, u32 id, s32 x, s32 y, s32 z, void* v, void* cb);\nextern u32 _ZN5Sound8PlayLongEjjjRK7Vector3s(u32 h, u32 a, u32 b, void* v, u32 d);\nextern void _ZN5Sound9PlayBank0EjRK7Vector3(u32 a, void* v);\nextern void func_ov002_020dc174(char* c, void* p, int a, int b, u32 e, u32 f);\nextern void _ZN5dCc_c5ClearEv(char* c);\nextern void _ZN5dCc_c6UpdateEv(char* c);\nextern void _ZN6Player11ChangeStateERNS_5StateE(char* c, void* s);\nextern void Player_AdvanceAnims(char* c);\n\nextern u8 data_020a0e40;\nextern u16 data_0209f49e[];\nextern s16 data_0209f4a0[];\nextern int data_ov002_0211013c[];\n}\n\nextern \"C\" int _ZN6Player19St_SwingPlayer_MainEv(char* c)\n{\n switch (*(u8*)(c + 0x6e3)) {\n case 0:\n if (_ZN6Player12FinishedAnimEv(c)) {\n _ZN6Player7SetAnimEji5Fix12IiEj(c, 0x6d, 0x40000000, 0x1000, 0);\n *(u8*)(c + 0x6e3) = 1;\n }\n *(s16*)(c + 0x8e) += *(s16*)(c + 0x69c);\n break;\n case 1: {\n int arr[3];\n Vec3 v;\n if ((*(u16*)((char*)data_0209f49e + data_020a0e40 * 0x18) & 1) != 0) {\n char* p = *(char**)(c + 0x358);\n if (p != 0) {\n int b = (*(u32*)(p + 0xb0) & 0x200) != 0;\n if (!b) {\n func_ov002_020d9c70(c);\n func_ov002_020da95c(c);\n _ZN6Player7SetAnimEji5Fix12IiEj(c, 0x6e, 0x40000000, 0x1000, 0);\n *(u8*)(c + 0x6e3) = 3;\n } else {\n func_ov002_020da9d4(c);\n }\n }\n return 1;\n }\n if (*(s16*)((char*)data_0209f4a0 + data_020a0e40 * 0x18) != 0) {\n s16 diff = *(s16*)(c + 0x6d2) - *(s16*)(c + 0x6d4);\n s16 av = *(s16*)(c + 0x69c);\n s32 step;\n if (av < 0) av = -av;\n step = (av < 0x800) ? ((diff << 10) >> 16) : ((diff << 9) >> 16);\n if (step != 0) {\n *(s16*)(c + 0x69c) += step;\n if (*(s16*)(c + 0x69c) >= 0x1800)\n *(s16*)(c + 0x69c) = 0x1800;\n else if (*(s16*)(c + 0x69c) <= -0x1800)\n *(s16*)(c + 0x69c) = -0x1800;\n } else {\n _Z15ApproachLinear2Rsss((s16*)(c + 0x69c), 0, 0x20);\n }\n } else {\n _Z15ApproachLinear2Rsss((s16*)(c + 0x69c), 0, 0x80);\n }\n {\n s16 a2 = *(s16*)(c + 0x69c);\n if (a2 < 0) a2 = -a2;\n if (a2 >= 0xf99) {\n u32 id = 0x132;\n v.x = *(int*)(c + 0x5c);\n v.y = *(int*)(c + 0x60);\n v.z = *(int*)(c + 0x64);\n v.y = *(int*)(c + 0x60) + 0x3c000;\n if (*(s16*)(c + 0x69c) > 0)\n id = 0x133;\n *(u32*)(c + 0x628) = _ZN8Particle6System3NewEjj5Fix12IiES2_S2_PK11Vector3_16fPNS_8CallbackE(\n *(u32*)(c + 0x628), id, *(int*)&v.x, *(int*)&v.y, *(int*)&v.z, 0, 0);\n *(u32*)(c + 0x620) = _ZN5Sound8PlayLongEjjjRK7Vector3s(*(u32*)(c + 0x620), 0, 0x1c, c + 0x74, 0);\n }\n if (*(s16*)(c + 0x69c) != 0)\n *(u16*)(c + 0x6a4) = 0xa;\n }\n if (*(u16*)(c + 0x6a4) == 0) {\n _ZN6Player7SetAnimEji5Fix12IiEj(c, 0x6f, 0x40000000, 0x1000, 0);\n *(u8*)(c + 0x6e3) = 2;\n }\n {\n s16 before = *(s16*)(c + 0x8e);\n *(s16*)(c + 0x8e) += *(s16*)(c + 0x69c);\n if ((*(s16*)(c + 0x69c) <= -0x100 && before < *(s16*)(c + 0x8e)) ||\n (*(s16*)(c + 0x69c) >= 0x100 && before > *(s16*)(c + 0x8e)))\n _ZN5Sound9PlayBank0EjRK7Vector3(0x1b, c + 0x74);\n }\n arr[0] = 0;\n arr[1] = 0x32000;\n arr[2] = 0x64000;\n func_ov002_020dc174(c, arr, 0x32000, 0x32000, 0x80, 0);\n _ZN5dCc_c5ClearEv(c + 0x314);\n _ZN5dCc_c6UpdateEv(c + 0x314);\n break;\n }\n case 2:\n if (_ZN6Player12FinishedAnimEv(c))\n _ZN6Player11ChangeStateERNS_5StateE(c, data_ov002_0211013c);\n break;\n case 3:\n if (_ZN6Player12FinishedAnimEv(c))\n _ZN6Player11ChangeStateERNS_5StateE(c, data_ov002_0211013c);\n break;\n }\n\n Player_AdvanceAnims(c);\n return 1;\n}\n", "source": "m100/H2 (admissible rewrite)", "target_hex": "10402de928d04de20040a0e1e316d4e5030051e301f18f90db0000ea020000ea140000eacb0000ead10000ea5e93ffeb000050e30800000a00c0a0e30400a0e16d10a0e30121a0e3013aa0e300c08de5ba93ffeb0100a0e3e306c4e58e2084e2060c84e2f010d2e1fc09d0e1000081e0b000c2e1c40000ea24139fe51800a0e30020d1e51c139fe5920003e0b30091e1010010e21c00000a580394e5000050e31500000ab00090e5020c10e20100a0130000a003000050e30d00001a0400a0e1effeffeb0400a0e1280200eb00c0a0e30400a0e16e10a0e30121a0e3013aa0e300c08de59593ffeb0300a0e3e306c4e5010000ea0400a0e13a0200eb28d08de20100a0e31040bde81eff2fe198029fe5f30090e1000050e32700000a060c84e2f22dd0e1f41dd0e1fcc9d0e1010042e00008a0e100005ce34038a0e100006cb20008a0b140c8a0b1020b5ce30305a0b14038a0b18304a0a14038a0a1000053e30f00000a44029fe5061c84e2002084e0f000d2e1030080e0b000c2e1fc29d1e1060b52e3060ba0a3bc09c1a10f0000aa060ba0e3000060e2000052e1bc09c1d10a0000ea04029fe50010a0e3000084e02020a0e34c83fdeb040000eaec019fe50010a0e3000084e08020a0e34683fdeb060c84e2fc19d0e1000051e3000061b20008a0b14018a0b1c4019fe5000051e11e0000ba5c1094e5060c84e218108de5602094e5ac119fe51c208de5642094e520208de5602094e50f2982e21c208de5fc09d0e120209de5000050e30000a0e300208de504008de508008de578119fc5280694e518209de51c309de5d022fdeb280684e50010a0e300108de5200694e5743084e21c20a0e333e0fceb200684e5060c84e2fc19d0e1000051e30a10a013b41ac011060c84e2b40ad0e1000050e30800001a00c0a0e30400a0e16f10a0e30121a0e3013aa0e300c08de52393ffeb0200a0e3e306c4e58ec084e2060c84e2f030dce1fc29d0e1fee8d4e1ff10e0e3022083e0b020cce1fc29d0e1010052e1020000cafe08d4e100005ee1040000ba010c52e3050000bafe08d4e100005ee1020000da741084e21b00a0e3d3e0fceb322aa0e300c0a0e31909a0e314008de50cc08de510208de58000a0e300008de50c108de20400a0e10230a0e104c08de5900700ebc50f84e23aebfcebc50f84e22bebfceb0c0000ea9392ffeb000050e30900000a54109fe50400a0e1502300eb050000ea8c92ffeb000050e30200000a38109fe50400a0e1492300eb0400a0e19492ffeb0100a0e328d08de21040bde81eff2fe1400e0a029ef40902a0f409029c060000990f000032010000330100003c011102", "cand_size": 964, "evaluator": "2004/b56|m2", "floor": {"class": "build-delta", "evidence": "shape-exact: every instruction matches in mnemonic, operand form and order. Pure two-web permutation, ROM av=ip diff=r3 against our av=r3 diff=r1, the 6bs fresh-register-vs-recycle direction. Swept inert: 15 block spellings, declaration and first-write order both, named-index and stride-in-the-type forms, 20 pragmas in both directions. The previous stored source scored 4 only by calling the 3-argument _Z15ApproachLinear2Rsss through a 4-argument function-pointer cast, which pinned diff to r3 across the call. That call cannot be what the cartridge compiled, so the 4 was never reachable and this 11 is the real floor.", "date": "2026-09-07"}} {"module": "ov003", "addr": "0x020af038", "name": "_ZN12dScStarSel_c8BehaviorEv", "size": 2100, "target_hex": "f0402de904d04de2d4179fe50050a0e1000091e5001090e5141091e531ff2fe1000050e3e801000ab8079fe5000085e0592ffeeb460f85e2572ffeeb1901d5e5000050e30700001a9c079fe5d000d0e13291fdeb0e0050e32a0000da6ee9fdeb000050e32700000a1901d5e5000050e30600000a74079fe574179fe5003085e00020d3e5000091e5000042e00000c3e51901d5e5000050e30700000a48079fe5d000d0e11d91fdeb0e0050e3e80000da59e9fdeb000050e3e500000a0010a0e30120a0e10300a0e390fcfdeb18079fe520279fe520179fe5d000d0e1bc20c1e10e91fdeb0e0050e31511d5d50c079fd5011081d20010c0d500079fc50110a0c30010c0c5d20000ea3501d5e5000050e33800000a40e9fdeb000050e33500000a3311d5e5000051e30b00001a3001d5e5010050e30800009ac4069fe54100d0e5030050e30400001ab8069fe50210a0e33311c5e57f8dfdebbd0000ea3901d5e5000050e3ba00001a010051e30f00001a0500a0e167fbffeb8c169fe5ff2000e288069fe50020c1e50020c0e560069fe53221c5e5001090e50300a0e3910000e01801c5e50200a0e33901c5e50a0000ea0200a0e33301c5e50310a0e330069fe53211c5e5001090e50600a0e3910000e01801c5e50100a0e33901c5e51010a0e31c069fe51911c5e54100d0e53c0080e2588dfdeb960000eaec059fe5d000d0e1c690fdeb0e0050e3910000ca00069fe500369fe50020d0e51541d5e500e0a0e30211d3e70261a0e1000051e33000000a1401d5e50ec0a0e1000050e32c0000da066083e00230d6e50370d6e50c6085e01a61d6e5066043e0086086e2ff6006e2100056e31f00002a280057e31d00002a3161d5e5566ca0e1016016e21900000a000051e30400000a8c059fe50201d0e7000050e30100a0130000001a0000a0e3000050e30100001a0c0054e10400000a3c159fe50300a0e3001091e5910000e01701c5e50c0054e10200000a34059fe50c40a0e11f8dfdeb0000a0e33301c5e501e0a0e3020000ea01c08ce200005ce1d5ffffba00005ee34400001a3501d5e5020050e34100001a3301d5e5000050e33e00001ae8049fe54200d0e5000050e33a00001af4049fe5b020d0e1201012e21900000ab200d0e1201010e20300001a010c85e2b400d0e1000050e32f00001a000051e31010a0130810a003010c85e2b410c0e1000054e32800000a3111d5e5014044e25104a0e1010010e20300001a014044e25104a0e1010010e2fbffff0a70049fe5ef8cfdeb1c0000ea101012e21a00000ab200d0e1101010e20300001a010c85e2b400d0e1000050e31300001a000051e31010a0130810a003010c85e2b410c0e11401d5e5010040e2000054e10a0000aa3111d5e5014084e25104a0e1010010e20300001a014084e25104a0e1010010e2fbffff0af8039fe5d18cfdeb1501d5e5040050e10800000a0408a0e14008a0e11541c5e595bcfdebc0139fe50300a0e3001091e5910000e01701c5e53901d5e5000050e30100001a0500a0e1b2fbffeb90039fe5d000d0e12f90fdeb0e0050e3d80000ca3501d5e5000050e33400001a68e8fdeb000050e30a00001a7c039fe54200d0e5000050e37900001a7c039fe588139fe50000d0e50001a0e1b00091e1f00010e27200000a54039fe5a88cfdeb48039fe54200d0e5000050e30500001a54039fe5b200d0e1300010e20100a0133501c5150100001a0200a0e33501c5e500039fe5d000d0e10b90fdeb0e0050e30000a0d33301c5d55d0000da3001d5e5010050e30b00009af0029fe54100d0e5030050e30700001a0110a0e33311c5e53001d5e5040050e30000a0133401c5153411c5054e0000ea0200a0e33301c5e54b0000ea010050e30500001ac8029fe5b200d0e1000050e30200a0133501c515430000ea94129fe54200d1e5000050e33f00001aa0029fe5b020d0e1c02012e23b00000ab220d0e1400012e21b00000a3301d5e5000050e33500000a80029fe5002085e00000d2e5010040e20000c2e53301d5e5010050e30d00001a3021d5e5010052e30800009a4100d1e5030050e30500001a040052e30000a0133401c5150100a0033401c505010000ea0000a0e33301c5e508029fe5558cfdeb1c0000ea800012e21a00000a3301d5e5020050e31700000a08029fe5002085e00000d2e5010080e20000c2e53301d5e5010050e30d00001a3021d5e5010052e30800009a4100d1e5030050e30500001a040052e30000a0133401c5150100a0033401c505010000ea0200a0e33301c5e590019fe5378cfdeb3001d5e5010050e30300009a78019fe54100d0e5030050e34d00000a011c85e2b800d1e1000050e31000000a422f85e2b000d2e1010040e2b000c2e1b800d1e1000050e34200001a0020a0e3010ba0e3ba20c1e1000060e2be00c1e1fe20d1e10100a0e3bc20c1e13601c5e5380000ea3601d5e5020010e20800001a432f85e2f000d2e1010c80e2b000c2e1fc00d1e1000050e30100a0a33601c5a5070000ea432f85e2f000d2e1010c40e2b000c2e1fc00d1e1000050e30300a0a33601c5a5ec009fe5011c85e2003085e0f020d3e1fc00d1e1000082e0b000c3e13621d5e5010052e30400001afa00d1e1000050e30200a0a33601c5a5150000aa030052e31300001a012c85e2fa00d2e1000050e30f0000ca9c009fe5061da0e3004085e0f030d4e1000061e2801083e2b010c4e1fe10d2e1000051e17800a0a3b800c2a10000a0a3ba00c2a1bc10c2b10100a0b33601c5b5410f85e26b2dfeeb0100a0e304d08de2f040bde81eff2fe1bcf5090217010000102109021901000044ee0802ff7f0000e8f50902f0f10902a0ca09022e0100002821090214210902400e0a02e80d0a02e90d0a02580e0a025a0e0a02330100000a0100000e010000", "lang": "cpp", "divergences": 11, "cand_size": 2100, "c_source": "//cpp\n// @symbol _ZN12dScStarSel_c8BehaviorEv\n// NONMATCHING: 11/525 at exact size 0x834. Real dScStarSel_c method over\n// include/dScStarSel_c.h, vtable slot 6. Declaring the two touch-record globals with\n// their real 4-byte stride (u8 [][4]) is what took 20 to 19: with the stride in the\n// type, the index scale folds into each addressing mode instead of being CSE'd into\n// one live temp, so the second read refolds it off the surviving index exactly as the\n// ROM does (+0x28c ldrb r0,[r1,r0,lsl#2]). See notes 6bv lever 2.\n//\n// 19 to 11 is the declaration block above: `idx` moved to rank 6 AND typed `long`\n// instead of `u8`. That kills the whole first cluster (8 words, +0x214..+0x2ec) -- the\n// ROM's `ldrb r2,[r0]` at +0x214 and the r0/r2 routing of `idx` against `n` that hangs\n// off it. The two edits only work together: the move alone measures 21, `long` alone\n// 31, both 11. `long` and `int` are the same 32-bit signed type here and emit the same\n// instruction, so this is a pure type-NAME rank effect, not a width effect; every other\n// local reverts to its natural type at 11 (measured one at a time).\n//\n// The 11 that remain are ONE cluster, +0x248..+0x278: a clean r6 <-> r7 swap between\n// `ty` and the loop-body scratch chain. `rec` dies at the `ty` load (+0x248), freeing\n// r6, and the scratch web is born one instruction later at +0x24c. Both need a\n// register and their ranges nest, so the pair is {r6, r7}; the ROM gives the recycled\n// r6 to the short loop-local scratch and the fresh r7 to `ty`, which is loop-invariant\n// (it is hoisted into the preheader at +0x248 -- the loop proper starts at +0x24c) and\n// live across the whole loop. We give `ty` the recycled r6 and the scratch r7.\n//\n// Do NOT read the old banner's 6bs verdict here: it claimed both clusters were an\n// unreachable build delta because \"the ROM's compiler will not reuse a register that\n// died on the previous instruction\". That is false on this body in both directions.\n// The ROM itself recycles a just-died register twice in this very block (+0x244\n// `ldrb r3,[r6,#2]` takes r3, dead at +0x240; +0x24c `add r6,r5,ip` takes r6, dead at\n// +0x248), and the first cluster fell to ordinary source-level rank levers.\n//\n// What the two sides actually disagree about is narrower: when a load's BASE register\n// holds a value whose last use is that same load, 2004/b56 takes it as the load's\n// destination, and the ROM's compiler takes it only when base and destination belong\n// to one expression chain. The ROM does dest == base 25 times in this function -- every\n// one a chained read like data_0209caa0[0x41] or the vptr walk at +0x18 -- and refuses\n// it at exactly the two sites where the destination is a distinct named value, +0x214\n// (`idx` off the pool temp) and +0x248 (`ty` off `rec`). Raising a named local's\n// colouring rank overrides our preference, and that is what closed +0x214. At +0x248\n// the value competing with `ty` is a compiler temp with no declaration, so there is no\n// rank to raise, and the sweeps below say so.\n//\n// MEASURED INERT on the remaining cluster, all at div 11 with the schedule intact\n// (SCHED==0 throughout): `ty`'s declaration rank x type name is EXHAUSTIVE at 14 names\n// x 11 ranks and all 187 cells emit the identical `ldrb r6,[r6,#3]`; naming the window\n// temp (8 types x 4 ranks); naming the scratch chain's address and loaded byte as two\n// locals swept over 3 pointer types x 5 value types x 12 ranks (180 cells, one root-2\n// word in all of them); `ty` before `tx`; a `rec` alias copy; `*(u8 *)(rec + 3)` and\n// the other access-expression forms; declaring `ty` or `tx` at the point of use;\n// carrying `ty` in an existing local with a disjoint live range; the three nested-if\n// spellings of the guard (the banner this replaces recorded those as \"did not\n// compile\" -- they compile and they tie); moving the `ty` read into the loop with\n// opt_loop_invariants re-enabled, which keeps SCHED==0 and scores 23; the callee\n// return-type and argument-type axis; the `data_020a0de9` respellings\n// (`data_020a0de8[idx][1]`, flat `[idx * 4]`, struct arrays). Two randomized product\n// scans over declaration order x type names x spellings (1475 cells from the old shape,\n// 1359 from this one) never produce the ROM's `ldrb r7,[r6,#3]`, and neither does a\n// 45-minute permuter run on a plain-C base that compiles byte-identically to this file.\n// A 40-cell additive pragma sweep is inert as well,\n// and both pragmas here are load-bearing: dropping opt_strength_reduction rebuilds the\n// frame (0x830, pushes r8, loses the `sub sp,sp,#4`), dropping opt_loop_invariants\n// keeps the exact schedule and costs 5 more coloring words.\n// Cross-build: 2004/b56 is the ONLY installed build that even reaches 0x834 here\n// (1.2 lands 2008-2012, 2.0 1952, dsi 1764-1784), so the version axis is closed too.\n#pragma opt_loop_invariants off\n#pragma opt_strength_reduction off\n#include \"common.h\"\n#include \"dScStarSel_c.h\"\n#include \"decl_common.h\"\n#include \"Message.h\"\n\nstruct VObj {\n virtual void v0();\n virtual void v1();\n virtual void v2();\n virtual void v3();\n virtual void v4();\n virtual int v5();\n};\n\nextern \"C\" {\nu8 DecIfAbove0_Byte(u8 *p);\nu16 DecIfAbove0_Short(u16 *p);\nvoid func_02012790(int idx);\n\nextern VObj *data_0209f5bc;\nextern s8 data_02092110;\nextern s32 data_0208ee44;\nextern u16 data_0209f5e8[];\nextern u8 data_02092128;\nextern u8 data_0209caa0[];\nextern u8 data_020a0e40;\nextern u8 data_020a0de8[][4];\nextern u8 data_020a0de9[][4];\nextern u16 data_020a0e58[];\nextern u16 data_020a0e5a[];\n}\n\n#define FB(p, o) (*(u8 *)((u8 *)(p) + (o)))\n#define FH(p, o) (*(s16 *)((u8 *)(p) + (o)))\n#define FU(p, o) (*(u16 *)((u8 *)(p) + (o)))\n\ns32 dScStarSel_c::Behavior()\n{\n s32 cur;\n u8 ty;\n s32 found;\n s32 i;\n u8 *rec;\n u8 tx;\n long idx;\n u8 touched;\n s32 hit;\n s32 n;\n s32 pressed;\n\n if (data_0209f5bc->v5() != 0) {\n DecIfAbove0_Byte(&FB(this, 0x117));\n DecIfAbove0_Byte(&FB(this, 0x118));\n if (FB(this, 0x119) != 0 || (SublevelToLevel(data_02092110) > 0xe && IsButtonInputValid() != 0)) {\n if (FB(this, 0x119) != 0) {\n FB(this, 0x119) -= data_0208ee44;\n }\n if (FB(this, 0x119) == 0 || (SublevelToLevel(data_02092110) > 0xe && IsButtonInputValid() != 0)) {\n StartSceneFade(3, 0, 0);\n data_0209f5e8[6] = 0x7fff;\n if (SublevelToLevel(data_02092110) <= 0xe) {\n data_0209f1f0 = FB(this, 0x115) + 1;\n } else {\n data_0209f1f0 = 1;\n }\n }\n } else if (FB(this, 0x135) != 0 && IsButtonInputValid() != 0) {\n u8 mode = FB(this, 0x133);\n if (mode == 0 && FB(this, 0x130) > 1 && data_0209caa0[0x41] == 3) {\n FB(this, 0x133) = 2;\n func_02012790(0x12e);\n } else if (FB(this, 0x139) == 0) {\n if (mode == 1) {\n u8 ch = func_ov003_020adf50((char *)this);\n data_02092128 = ch;\n data_02092114 = ch;\n FB(this, 0x132) = ch;\n FB(this, 0x118) = data_0208ee44 * 3;\n FB(this, 0x139) = 2;\n } else {\n FB(this, 0x133) = 2;\n FB(this, 0x132) = 3;\n FB(this, 0x118) = data_0208ee44 * 6;\n FB(this, 0x139) = 1;\n }\n FB(this, 0x119) = 0x10;\n func_02012790(data_0209caa0[0x41] + 0x3c);\n }\n } else if (SublevelToLevel(data_02092110) <= 0xe) {\n idx = data_020a0e40;\n cur = FB(this, 0x115);\n found = 0;\n touched = data_020a0de8[idx][0];\n if (touched != 0) {\n n = FB(this, 0x114);\n i = 0;\n if (n > 0) {\n rec = data_020a0de8[idx];\n tx = rec[2];\n ty = rec[3];\n do {\n if ((u8)(tx - FB((u8 *)this + i, 0x11a) + 8) < 0x10 && ty < 0x28 && ((FB(this, 0x131) >> i) & 1)) {\n hit = (touched != 0 && data_020a0de9[idx][0] != 0);\n if (hit != 0 || cur != i) {\n FB(this, 0x117) = data_0208ee44 * 3;\n }\n if (cur != i) {\n cur = i;\n func_02012790(0x12e);\n }\n FB(this, 0x133) = 0;\n found = 1;\n break;\n }\n i++;\n } while (i < n);\n }\n }\n if (found == 0 && FB(this, 0x135) == 2 && FB(this, 0x133) == 0 && data_0209caa0[0x42] == 0) {\n if (data_020a0e58[0] & 0x20) {\n pressed = data_020a0e58[1] & 0x20;\n if (pressed != 0 || FU(this, 0x104) == 0) {\n FU(this, 0x104) = pressed ? 0x10 : 8;\n if (cur != 0) {\n u8 mask = FB(this, 0x131);\n cur--;\n while (!((mask >> cur) & 1)) {\n cur--;\n }\n func_02012790(0x12e);\n }\n }\n } else if (data_020a0e58[0] & 0x10) {\n pressed = data_020a0e58[1] & 0x10;\n if (pressed != 0 || FU(this, 0x104) == 0) {\n FU(this, 0x104) = pressed ? 0x10 : 8;\n if (cur < FB(this, 0x114) - 1) {\n u8 mask = FB(this, 0x131);\n cur++;\n while (!((mask >> cur) & 1)) {\n cur++;\n }\n func_02012790(0x12e);\n }\n }\n }\n }\n if (FB(this, 0x115) != cur) {\n FB(this, 0x115) = cur;\n Message::DisplayStarNameForStarSelect((s16)cur);\n FB(this, 0x117) = data_0208ee44 * 3;\n }\n if (FB(this, 0x139) == 0) {\n func_ov003_020ae358((char *)this);\n }\n }\n\n if (SublevelToLevel(data_02092110) <= 0xe) {\n if (FB(this, 0x135) == 0) {\n if (IsButtonInputValid() != 0 || (data_0209caa0[0x42] == 0 && (data_020a0e5a[data_020a0e40 * 2] & 0xf0))) {\n func_02012790(0x12e);\n if (data_0209caa0[0x42] == 0 && (data_020a0e58[1] & 0x30)) {\n FB(this, 0x135) = 1;\n } else {\n FB(this, 0x135) = 2;\n }\n if (SublevelToLevel(data_02092110) <= 0xe) {\n FB(this, 0x133) = 0;\n } else if (FB(this, 0x130) > 1 && data_0209caa0[0x41] == 3) {\n FB(this, 0x133) = 1;\n if (FB(this, 0x130) != 4) {\n FB(this, 0x134) = 0;\n } else {\n FB(this, 0x134) = 1;\n }\n } else {\n FB(this, 0x133) = 2;\n }\n }\n } else if (FB(this, 0x135) == 1) {\n if (data_020a0e58[1] != 0) {\n FB(this, 0x135) = 2;\n }\n } else if (data_0209caa0[0x42] == 0 && (data_020a0e58[0] & 0xc0)) {\n u16 keys = data_020a0e58[1];\n if (keys & 0x40) {\n if (FB(this, 0x133) != 0) {\n FB(this, 0x133) -= 1;\n if (FB(this, 0x133) == 1) {\n if (FB(this, 0x130) > 1 && data_0209caa0[0x41] == 3) {\n if (FB(this, 0x130) != 4) {\n FB(this, 0x134) = 0;\n } else {\n FB(this, 0x134) = 1;\n }\n } else {\n FB(this, 0x133) = 0;\n }\n }\n func_02012790(0x12e);\n }\n } else if (keys & 0x80) {\n if (FB(this, 0x133) != 2) {\n FB(this, 0x133) += 1;\n if (FB(this, 0x133) == 1) {\n if (FB(this, 0x130) > 1 && data_0209caa0[0x41] == 3) {\n if (FB(this, 0x130) != 4) {\n FB(this, 0x134) = 0;\n } else {\n FB(this, 0x134) = 1;\n }\n } else {\n FB(this, 0x133) = 2;\n }\n }\n func_02012790(0x12e);\n }\n }\n }\n\n if (FB(this, 0x130) <= 1 || data_0209caa0[0x41] != 3) {\n if (FU(this, 0x108) != 0) {\n FU(this, 0x108) -= 1;\n if (FU(this, 0x108) == 0) {\n FH(this, 0x10a) = 0;\n FH(this, 0x10e) = -0x400;\n FH(this, 0x10c) = FH(this, 0x10e);\n FB(this, 0x136) = 1;\n }\n } else {\n if (!(FB(this, 0x136) & 2)) {\n FH(this, 0x10c) += 0x100;\n if (FH(this, 0x10c) >= 0) {\n FB(this, 0x136) = 1;\n }\n } else {\n FH(this, 0x10c) -= 0x100;\n if (FH(this, 0x10c) >= 0) {\n FB(this, 0x136) = 3;\n }\n }\n FH(this, 0x10a) += FH(this, 0x10c);\n if (FB(this, 0x136) == 1 && FH(this, 0x10a) >= 0) {\n FB(this, 0x136) = 2;\n } else if (FB(this, 0x136) == 3 && FH(this, 0x10a) <= 0) {\n FH(this, 0x10e) += 0x80;\n if (FH(this, 0x10e) >= -0x180) {\n FU(this, 0x108) = 0x78;\n FH(this, 0x10a) = 0;\n } else {\n FH(this, 0x10c) = FH(this, 0x10e);\n FB(this, 0x136) = 1;\n }\n }\n }\n }\n }\n }\n DecIfAbove0_Short(&FU(this, 0x104));\n return 1;\n}\n", "source": "fanout", "evaluator": "2004/b56|m2"} {"module": "ov074", "addr": "0x02121380", "name": "func_ov074_02121380", "size": 884, "target_hex": "f04f2de974d04de260139fe51c308de20060a0e1070091e8070083e8843096e50108a0e300c060e20509a0e314008de52d09a0e310008de54109a0e3c32fa0e10c008de50209a0e1801096e50349a0e1028ba0e305b8a0e3230780e1089094e00040a0e22906a0e191ab89e00050a0e308008de5040a80e10040e0e308a09ae018408de5919529e008008de544008de548008de5c10fa0e1909b29e02aa6a0e10090a9e209aa8ae118909de538a08de53ca08de593bc8ae093a92ae092ac2ae008b09be00090aae22ba6a0e109aa8ae196eaa0e32ca08de530a08de5939e8ae093a52ae0089099e092ae2ae02996a0e100a0aae200908de50a9a89e15a7aa0e300908de591978ae091a52ae0089099e02996a0e190a72ae004908de504709de50090aae2097a87e104708de514709de50640a0e1937789e0087097e027a6a0e1939529e014709de5929729e00070a9e207aa8ae110709de528a08de5919787e0917527e010109de528a08de2907127e0081099e00000a7e22116a0e1001a81e10c009de534108de5930081e0087090e0931521e00c009de534908de2921021e00000a1e22716a0e1001a81e140108de564708de240808de21c008de2052190e70700a0e10610a0e148ffffeb64109de50501a0e1ac1384e568109de5b01384e56c109de5b41384e505119ae7b0b394e5015085e201108be0ac3394e5b42394e500c099e705b386e014c18be5000098e7030055e318018be544318be548118be50c4084e24c218be5e2ffffba603096e55c4096e5642096e504009de54a1aa0e3140186e500009de5180186e508009de5444186e5000083e0480186e54c2186e5000061e2843096e50010e0e3935084e0934124e0c31fa0e1914024e0022ba0e3022095e02236a0e10000a4e2003a83e1c81396e5bc2396e5600096e5031081e0000051e1032082e00000a0e3070000aa0016d6e5000051e30100a003fe05c605fe05c6150100a0e30006c6e5010000ea0006c6e5fe05c6e5600096e5000052e1080000aa0106d6e5000050e30100a003ff05c6050000a013ff05c6150100a0e30106c6e5020000ea0000a0e30106c6e5ff05c6e50106d6e5000050e36a1f86020000910520008003000081056a1f8612000091152000c013000081150006d6e5000050e37a1f86020000910520008003000081057a1f8612000091152000c0130000811574d08de2f04fbde81eff2fe1242e1202", "lang": "c", "divergences": 11, "c_source": "// @symbol func_ov074_02121380\n/* recovered: daKuriKing_c (Goomboss) rebuilds his collision cylinders and reads\n * the ground under them. Called unconditionally from the boss's Behavior after\n * the state dispatch, so the whole fight's collision runs through it.\n *\n * Four cylinders. Three follow the animated model: for each of bones 1, 8 and\n * 0xa it asks func_ov074_02121270 for that bone's world position, caches it in\n * the bonepos[3] array at c+0x3ac, and writes a radius, a height and a centre\n * into the record at c + (i + 1) * 0x40 + 0x114. The fourth is the boss body\n * itself, written at c+0x114 from his own position. Every radius is the x\n * scale times a constant and every height the y scale times a constant, so the\n * cylinders track him as he grows and shrinks.\n *\n * Then the ground test: bonepos[1].y and bonepos[2].y, each biased by the y\n * scale times -0x4a000, are compared against his own y. Each comparison drives\n * a latch byte (c+0x600, c+0x601) and an edge byte (c+0x5fe, c+0x5ff) that is\n * set only on the frame the foot first goes below, and each latch then flips\n * bit 0x20 of a render word (c+0x1a8, c+0x1e8).\n */\n// NONMATCHING: div 11 of 221 words. mwccarm 2004/b56, --module ov074,\n// @ 0x02121380 size 0x374. Size and the 0x74 stack frame are exact, the whole\n// prologue and the whole tail are byte-exact, and the residue is 11 words in\n// the middle of the bone loop.\n//\n// Two scorers, two numbers, both reported because they measure different\n// things. tools/match.py --strict-relocs and tools/wallcrack.py both say **11**,\n// comparing word against word at the same offset -- that is the merge gate's\n// metric and the authoritative one. tools/nearmiss_db.py says **9**, because it\n// scores a difflib alignment over the reloc-wildcarded disassembly, which\n// charges a merely REORDERED block once instead of at every offset it moved.\n// Both sides wildcard the same two reloc slots (+0x1c8, +0x370), so the gap is\n// the alignment, not the wildcarding. Neither is wrong; the gate is the one\n// that decides a merge.\n//\n// Independently re-derived from the ROM listing. A near-miss row for this\n// address already existed at div 297 from a `fanout-opus` run; it was not used\n// -- structure, externs and frame layout here are a fresh derivation.\n//\n// LEVER (notes/mwccarm-codegen.md section 6bq): the rank of the loop-invariant\n// array base pointers follows the SOURCE ORDER OF THE STORES that consume them.\n// The five record stores go to five distinct offsets off one base, so all 120\n// orders are semantically identical and the scheduler re-emits them freely --\n// but the order the source presents them in decides which array base gets which\n// callee-saved register. Only 0x114, 0x144, 0x118, 0x148, 0x14c, paired with\n// computing the position temps z, y, x, reproduces the cartridge's colouring\n// (yoff->sl, rad->sb, hgt->r8, out->r7); the natural 0x114, 0x118, 0x144, 0x148,\n// 0x14c never does, and that order is worth 25 -> 11. Do not \"tidy\" it.\n//\n// FLOOR: a two-attractor pin of the 6bn shape. The store order that gives the\n// cartridge's REGISTERS emits the 0x144 store three slots early; the store\n// order that gives the cartridge's SCHEDULE gives the rotated registers. No\n// shape reaches both. Measured closed, on this body, through the gate: all 120\n// record-store orders x 6 position-temp orders x 6 bone-store orders (4320\n// cells); the full 246-name verified pragma vocabulary at on and off on BOTH\n// attractors, then crossed with the whole order space (5040 cells) per 6bo;\n// 6bp's named-address lever in both directions (deleting `p`'s name is free and\n// changes nothing, deleting `q`'s costs 8 bytes, and naming the three array\n// bases costs more); 6bp's statement-RELOCATION neighbourhood climbed to a\n// local optimum from both attractors; 24 declaration permutations; 125 element\n// type combinations; four spellings of the frame region; four loop forms; three\n// address-expression trees; struct-copy spellings of the bone-position traffic;\n// a one-variable reuse of the y temp and the record base (which inverts WHICH\n// store order colours right, but not the floor); and all 25 archived mwccarm\n// builds, of which only 2004/b56 even reaches the right size.\n//\n// The permuter is the wrong tool for this residue and was measured saying so:\n// ~16000 iterations over four runs on two structurally different seeds, and on\n// the div-11 seed every candidate it scored BETTER than the base (445 and 575\n// against 665) is size-drifted to 0x378/0x37c. That is 6bn addendum 4's hazard\n// reproduced -- with an ordering residue the permuter's score and the byte\n// oracle point in opposite directions.\n//\n// AUDIT: differential execution against the cartridge, exhaustive over the\n// 2700-state discriminating lattice (three bone heights x below/on/above the\n// compare threshold, both ground latches, five x-scales, five y-scales):\n// IDENTICAL on every state -- same call sequence with the same arguments, same\n// final value of all 216 written bytes, same return. Every one of the 12 branch\n// arms is exercised (coverage reported, none unreached). The harness is trusted\n// only because it was made to FAIL first: 8 deliberately broken, SIZE-NEUTRAL\n// controls -- wrong stored value, wrong store address, wrong load address,\n// branch boundary, wrong RMW mask, wrong call argument, wrong latch, wrong\n// component -- are all caught, and building them exposed three real harness\n// bugs (unimplemented ldm/stm, both sides reading the ROM's data image through\n// the pooled address instead of their own, and seeding that never reached the\n// >= arm or the exact compare boundary). The harness is not shipped in-tree,\n// same as the ov034 one it was adapted from; it is saved with this run's\n// artefacts as audit.py.\n//\n// PLACEHOLDER, NOT RECOVERED SOURCE: `struct Vector3 v[3]` with `&v[2]` passed\n// to the bone getter. The cartridge's frame carries 24 bytes between hgt[] and\n// the output vector that no instruction touches, plus a word above it. mwccarm\n// drops a local nothing references -- checked against unused scalars, unused\n// structs, `volatile` unused locals, arrays whose every store is dead, and\n// address-taken-but-folded forms, none of which reserve a byte -- so those bytes\n// have to belong to an object that IS used, and the only shapes that reproduce\n// the frame put them in the same object as the output vector. `Vector3 out[3]`\n// with &out[2], a three-member struct with its last member passed, and\n// `int buf[9]` with the vector at buf[6] all compile identically. The bytes are\n// right; the declaration behind them is a guess and should not be read as\n// recovered source.\n//\n// Counts as decompiled, not matched.\n#include \"common.h\"\n\nextern void func_ov074_02121270(struct Vector3* out, char* c, int i);\n\n#define FX(a, b) (int)(((long long)(a) * (long long)(b) + 0x800) >> 12)\n\nvoid func_ov074_02121380(char* c) {\n int bone[3] = {1, 8, 0xa};\n int yoff[3], rad[3], hgt[3];\n struct Vector3 v[3];\n int i;\n int h0, r0, y0;\n int d, a, b;\n char* q;\n int tx, ty, tz;\n\n y0 = FX(*(int*)(c + 0x84), 0x40000);\n rad[1] = FX(*(int*)(c + 0x80), 0x50000);\n hgt[1] = FX(*(int*)(c + 0x84), 0x40000);\n yoff[1] = FX(*(int*)(c + 0x84), -0x10000);\n rad[2] = FX(*(int*)(c + 0x80), 0x50000);\n hgt[2] = FX(*(int*)(c + 0x84), 0x40000);\n yoff[2] = FX(*(int*)(c + 0x84), -0x10000);\n h0 = FX(*(int*)(c + 0x84), 0x96000);\n r0 = FX(*(int*)(c + 0x80), 0x5a000);\n yoff[0] = FX(*(int*)(c + 0x84), 0x14000);\n rad[0] = FX(*(int*)(c + 0x80), 0xb4000);\n hgt[0] = FX(*(int*)(c + 0x84), 0x104000);\n q = c;\n for (i = 0; i < 3; i++) {\n char* p;\n int ax, ay, az;\n func_ov074_02121270(&v[2], c, bone[i]);\n *(int*)(q + 0x3ac) = v[2].x;\n *(int*)(q + 0x3b0) = v[2].y;\n *(int*)(q + 0x3b4) = v[2].z;\n az = *(int*)(q + 0x3b4);\n ay = *(int*)(q + 0x3b0) + yoff[i];\n ax = *(int*)(q + 0x3ac);\n p = c + (i + 1) * 0x40;\n *(int*)(p + 0x114) = rad[i];\n *(int*)(p + 0x144) = ax;\n *(int*)(p + 0x118) = hgt[i];\n *(int*)(p + 0x148) = ay;\n *(int*)(p + 0x14c) = az;\n q += 0xc;\n }\n\n tx = *(int*)(c + 0x5c);\n ty = *(int*)(c + 0x60) + y0;\n tz = *(int*)(c + 0x64);\n *(int*)(c + 0x114) = r0;\n *(int*)(c + 0x118) = h0;\n *(int*)(c + 0x144) = tx;\n *(int*)(c + 0x148) = ty;\n *(int*)(c + 0x14c) = tz;\n\n d = FX(*(int*)(c + 0x84), -0x4a000);\n a = *(int*)(c + 0x3c8) + d;\n b = *(int*)(c + 0x3bc) + d;\n if (a < *(int*)(c + 0x60)) {\n if (*(unsigned char*)(c + 0x600) == 0) {\n *(unsigned char*)(c + 0x5fe) = 1;\n } else {\n *(unsigned char*)(c + 0x5fe) = 0;\n }\n *(unsigned char*)(c + 0x600) = 1;\n } else {\n *(unsigned char*)(c + 0x600) = 0;\n *(unsigned char*)(c + 0x5fe) = 0;\n }\n if (b < *(int*)(c + 0x60)) {\n if (*(unsigned char*)(c + 0x601) == 0) {\n *(unsigned char*)(c + 0x5ff) = 1;\n } else {\n *(unsigned char*)(c + 0x5ff) = 0;\n }\n *(unsigned char*)(c + 0x601) = 1;\n } else {\n *(unsigned char*)(c + 0x601) = 0;\n *(unsigned char*)(c + 0x5ff) = 0;\n }\n if (*(unsigned char*)(c + 0x601) == 0) {\n *(int*)(c + 0x1a8) |= 0x20;\n } else {\n *(int*)(c + 0x1a8) &= ~0x20;\n }\n if (*(unsigned char*)(c + 0x600) == 0) {\n *(int*)(c + 0x1e8) |= 0x20;\n } else {\n *(int*)(c + 0x1e8) &= ~0x20;\n }\n}\n", "source": "vsdec-ov74-siege", "floor": {"class": "store-rank-conflict", "evidence": "2026-08-30 (Opus-5, two sieges ~34k compiles + ~18.2k permuter iterations across 4 runs/2 seeds, notes 6bq + addendum). Residue = the two-shape conflict: hoisted array-base rank follows store consumer source order, so the order that colors correctly (yoff->sl rad->sb hgt->r8 out->r7, byte-identical adds proven) emits the 0x144 store three slots early, and the order that schedules correctly rotates three scratch registers. Full 246-pragma x both-attractor x 120-store-order x 6-temp-order product swept; 6bp name-deletion free-but-no-effect; 6bn narrowing NOT APPLICABLE (no narrowed value exists); relocation climbs plateau at 11. Body ships as declared NONMATCHING with a 2700-state exhaustive differential-execution audit (all 12 arms, 8 size-neutral controls caught).\n\n[2026-09-12 link100 wave 7 lane FLOORS append] LEVERS (a) MEMBER-RMW-FOLD AND (b) MISSING-RETURN-VALUE APPLIED 2026-09-12, run link100 wave 7, lane FLOORS, mwccarm 2004/b56, base 02cb1f3d1. Lever (a) HAS sites here and they are already correct. The four member read-modify-writes are *(int*)(c+0x1a8) |= 0x20 and &= ~0x20, and *(int*)(c+0x1e8) |= 0x20 and &= ~0x20, and the ROM MATERIALISES the address at all four: add r1,r6,#0x1a8 at +0x31c and +0x32c, add r1,r6,#0x1e8 at +0x344 and +0x354, all four already OK in the shipped draft. Applying the fold (the plain same-type cast on the read, or WIDEN) removes one instruction per site and drops the function to 0x364, sixteen bytes short of 0x374. The lever exists here and points the wrong way, so the draft's plain compound-assignment spelling is the one to keep. Spellings that do not fold (*(int *)&, a char* re-cast, the long-hand x = x | 0x20) all reproduce the same 11. The store-rank residue in the loop at +0x1ec to +0x218 is untouched.\n\n[2026-09-13 link100 crack wave 9 lane CRK-P append] ALL FIVE WAVE-9 LEVERS APPLIED, mwccarm 2004/b56, base origin/main 5b4acd75d, ~2900 new compiles. Residue re-confirmed at 11 by BOTH scorers from a clean tree (match.py --version 2004/b56 and wallcrack agree; the DBPRUNE 9->11 correction is right). 6cc INERT: 1024 cells of {int,long,unsigned int,unsigned long}^3 on yoff/rad/hgt CROSSED jointly with {int,long}^3 on ax/ay/az, on both attractors, every cell exactly 11 at 884 bytes; 6cc's own bound explains it, the residue's webs are the four hoisted array BASES (compiler temps with no declaration) and the arrays are stack objects that never reach the allocator as register webs. 6cd INERT: 1036 cells, 8 dead-store targets x 21 value sources x 2 positions, plus 364 more with ax/ay/az/p hoisted to function scope and dead-assigned in the preamble (6cd's own shape); mwccarm deletes the dead store outright, every cell 884 bytes at 11 or 25. 6cb lever 1 INERT/DESTRUCTIVE: block depth is byte-identical (mwccarm flattens the scopes, as 6cb's addendum records for func_ov075_0211afb0); the one real anonymous CSE web is the scaled index at +0x1d0 and naming it forces the (char*)rad + k access form, which kills the loop-invariant hoist and blows the body to 1020 bytes; naming the bases costs 28 bytes (912). 6cb lever 2 NO SITE (the only + in the window is two plain registers; transposing it is byte-identical). 6ce NO SITE (no switch, no pool address in the body). ALSO: the array declaration order is pinned by the frame -- of 6 orders x 3 placements of v[3] only (yoff, rad, hgt) with v after keeps the cartridge's stack offsets -- so 6cc's rank axis is not even free here. Call-argument spellings (&v[2], v + 2, (struct Vector3*)&v[2].x) byte-identical. Attractor B (natural store order 0x114,0x118,0x144,0x148,0x14c) re-measured at 25 with the ROM's loop SCHEDULE exact and only the four hoisted bases rotated (ROM sl=yoff sb=rad r7=v[2] r8=hgt at +0x168/+0x198/+0x1b0/+0x1b4; ours sl=rad r8=v[2] r7=yoff sb=hgt at the same four offsets). The 6bq two-attractor floor stands.\n\n[2026-09-13 bank audit, lane REAUDIT append] CORRECTION to this row's own evidence. The claim \"removing the position temps costs 4 words\" is wrong and was measured on the three temps as a set. Bisected: inlining ax alone, ay alone, ax+az or ay+az each assembles to 0x364 (SIXTEEN bytes short, a redundant load elided), inlining all three assembles to 0x380 (TWELVE bytes long), and only az alone is size-neutral -- it scores 25 because it pulls the hoisted-base rotation onto attractor A. ax+ay is size-neutral at 24. So no single temp removal is a 4-word edit and none is size-neutral except az. ALSO NEW, all size-exact: the preamble assignment order is NOT a free axis (yoff-first per group assembles 0x360, all-yoff-then-rad-then-hgt 0x35c -- reordering makes the repeated FX() expressions adjacent and mwccarm CSEs them); naming the q+0x3b0 load is byte-inert across all eight temp-order x store-order crossings; source temp order (ay,ax,az) -- the ROM's own EMISSION order -- scores 14, and (ax,ay,az) and (ay,az,ax) score 26 by pulling the base rotation onto attractor A. The two attractors stand at 11 and 25.", "date": "2026-09-13"}, "evaluator": "2004/b56|m2", "cand_size": 884} -{"module": "ov006", "addr": "0x020d27dc", "name": "func_ov006_020d27dc", "size": 3656, "target_hex": "f04f2de964d04de20090a0e1011989e2c82691e50040a0e3000052e30a0000dae40d9fe5042189e0003082e0002093e5014084e2000052e3012042c2002083c5c82691e5020054e1f5ffffba000052e30080a0e364d08dd2f04fbdd81eff2fd1d700a0e320008de5cf00a0e31c008de5c700a0e318008de5bf00a0e314008de5e000a0e310008de50200a0e334008de50500a0e330008de50700a0e338008de5070da0e30c808de560808de55c808de558808de554808de550808de54c808de548808de544808de540808de50160a0e304b0a0e30640a0e324008de50350a0e33c808de52c808de528808de5080189e0010980e2b80690e5000050e33a0300ca080d9fe5887189e0002087e0010989e2001092e5000790e5000051e15e0100daec0c9fe5081089e0000081e008008de50000d0e5010050e32b03000a0900a0e1001090e50ca09de5901091e531ff2fe1000050e33100000ab81c9fe50720a0e1017082e0080189e0001097e5010980e2a40690e5600051e3040000ca600051e3110000aa200051e30800000a4f0000eaa00051e3020000caa00051e31100000a4a0000eae00051e31500000a470000ea011989e2141791e5000051e1050a891206a0a0019863c015400000ea011989e2181791e5000051e1050a891206a0a0019963c015390000ea011989e21c1791e5000051e1050a891206a0a0019a63c015320000ea011989e2201791e5000051e1050a891206a0a0019b63c0152b0000eaf00b9fe50000b7e7600050e3040000ca600050e3110000aa200050e30800000a220000eaa00050e3020000caa00050e31100000a1d0000eae00050e31500000a1a0000ea010989e2140790e5010050e3050a891206a0a0019863c015130000ea010989e2180790e5010050e3050a891206a0a0019963c0150c0000ea010989e21c0790e5010050e3050a891206a0a0019a63c015050000ea010989e2200790e5010050e3050a891206a0a0019b63c01501005ae3b300001a0900a0e1001090e5901091e531ff2fe1000050e35300000a010989e2d506d0e5000050e32100001a001097e510009de50116a0e10afffceb080189e0010980e2a40690e5030050e300f18f901b0000ea020000ea060000ea0a0000ea0e0000ea001097e514009de50116a0e1fcfefceb120000ea001097e518009de50116a0e1f7fefceb0d0000ea001097e51c009de50116a0e1f2fefceb080000ea001097e520009de50116a0e1edfefceb030000ea001097e5880a9fe50116a0e1e8fefceb08009de50060c0e5780a9fe5002089e0001092e5010989e2011081e2001082e5cc2690e5c81690e5010052e1880200bad506d0e5000050e31400001a480a9fe5481a9fe5003089e0000093e5012089e0010080e2000083e5001092e5050a89e2011081e2001082e5e82390e5201a9fe564d08de2010052e1e81380c5050a89e27810a0e3e01380e5f04fbde81eff2fe1050a89e21e10a0e3e01380e564d08de2f04fbde81eff2fe1d0099fe5881189e0007081e0001097e510009de50116a0e1b7fefceb001097e5c8099fe50116a0e1b3fefceb08009de50060c0e5a4099fe5002089e0001092e5010989e2011081e2001082e5cc1690e5c80690e5000051e1530200ba80099fe580199fe5003089e0000093e5012089e0010080e2000083e5001092e5050a89e2011081e2001082e5e82390e558199fe5010052e1e81380c5050a89e2d42390e51c10a0e3920103e044199fe5031091e7000051e31200000a010051e30600000a020051e32c099f0500108900000091050500800200008105090000ea740390e5a01fa0e1800f61e0e00f91e00400001a00099fe5001089e0000091e5050080e2000081e5050a89e2681390e5640051e36410a0c3681380c5050a89e2741390e5050051e3090000ba3c10a0e3c01380e5010989e20210a0e3d01680e50110a0e3d416c0e564d08de2f04fbde81eff2fe1010989e20010a0e3d01680e564d08de2f04fbde81eff2fe10900a0e1001090e5901091e531ff2fe1000050e32500000a0500a0e30500fdeb010989e2d506d0e5000050e30600001a880189e0010980e2601690e550089fe50116a0e152fefceb050000ea880189e0010980e2601690e514089fe50116a0e14bfefceb08009de50120a0e30020c0e5010989e2fc179fe5d526c0e5012089e0001092e564d08de2011081e2001082e5cc1690e5c80690e5000051e1050a89a23c10a0a3e01380a5f04fbde81eff2fe1880189e0010980e2601690e5e100a0e30116a0e132fefceb050a89e23c10a0e3c01380e5010989e20210a0e3d01680e50110a0e3d516c0e564d08de2f04fbde81eff2fe1bf30e0e3030051e1010000ba980051e3030000ba000092e5010080e2000082e5ca0100ea78379fe5087089e003a087e00030dae5010053e30c00008a010081e2000082e50900a0e10810a0e10520a0e1cbfdffeb000050e3bc01001a0900a0e10810a0e10b20a0e1c5fdffebb70100ead42081e2d41080e27d0fa0e3920000e0399ffceb04008de518079fe5081189e0007081e0000097e5070050e300f18f90aa0100ea060000ea410000ea5f0000ea9a0000ead40000ea0e0100ea490100ea670100ea880189e0010980e2600690e5210050e30500000a610050e30300000aa10050e30100000ae10050e31000001a84069fe5881189e00000b1e7010040e2000081e5004087e50060cae5000091e50006a0e1d5fdfceb00008de504309de524009de528209de50410a0e1c0fdfceb860100ea2c209de50900a0e10810a0e18ffdffeb000050e38001001a0900a0e10810a0e10620a0e189fdffeb000050e37a01001a0900a0e10810a0e10520a0e183fdffeb000050e37401001a30209de50900a0e10810a0e17dfdffeb000050e36e01001a34209de50900a0e10810a0e177fdffeb000050e338009d0500008705660100ea0900a0e10810a0e10620a0e16ffdffeb000050e36001001a3c209de50900a0e10810a0e169fdffeb000050e35a01001a34209de50900a0e10810a0e163fdffeb000050e35401001a0900a0e10810a0e10520a0e15dfdffeb000050e34e01001a0900a0e10810a0e10b20a0e157fdffeb000050e300408705470100ea880189e0010980e2600690e51f0050e30500000a5f0050e30300000a9f0050e30100000adf0050e31000001a18059fe5881189e00000b1e7010080e2000081e5004087e50060cae5000091e50006a0e17afdfceb00008de504309de524009de540209de50410a0e165fdfceb2b0100ea34209de50900a0e10810a0e134fdffeb000050e32501001a0900a0e10810a0e10620a0e12efdffeb000050e31f01001a0900a0e10810a0e10b20a0e128fdffeb000050e31901001a44209de50900a0e10810a0e122fdffeb000050e31301001a38209de50900a0e10810a0e11cfdffeb000050e330009d05000087050b0100ea880189e0010980e2600690e5210050e30500000a610050e30300000aa10050e30100000ae10050e31000001a28049fe5881189e00000b1e7010040e2000081e5004087e50060cae5000091e50006a0e13efdfceb00008de504309de524009de548209de50410a0e129fdfcebef0000ea0900a0e10810a0e10520a0e1f8fcffeb000050e3e900001a4c209de50900a0e10810a0e1f2fcffeb000050e3e300001a30209de50900a0e10810a0e1ecfcffeb000050e3dd00001a0900a0e10810a0e10620a0e1e6fcffeb000050e3d700001a0900a0e10810a0e10420a0e1e0fcffeb000050e300b08705d00000ea880189e0010980e2600690e51f0050e30500000a5f0050e30300000a9f0050e30100000adf0050e31000001a3c039fe5881189e00000b1e7010080e2000081e5004087e50060cae5000091e50006a0e103fdfceb00008de504309de524009de550209de50410a0e1eefcfcebb40000ea0900a0e10810a0e10b20a0e1bdfcffeb000050e3ae00001a34209de50900a0e10810a0e1b7fcffeb000050e3a800001a38209de50900a0e10810a0e1b1fcffeb000050e3a200001a0900a0e10810a0e10620a0e1abfcffeb000050e39c00001a0900a0e10810a0e10420a0e1a5fcffeb000050e300508705950000ea880189e0010980e2600690e5210050e30500000a610050e30300000aa10050e30100000ae10050e31000001a50029fe5881189e00000b1e7010040e2000081e5004087e50060cae5000091e50006a0e1c8fcfceb00008de504309de524009de554209de50410a0e1b3fcfceb790000ea30209de50900a0e10810a0e182fcffeb000050e37300001a0900a0e10810a0e10420a0e17cfcffeb000050e36d00001a0900a0e10810a0e10520a0e176fcffeb000050e36700001a58209de50900a0e10810a0e170fcffeb000050e36100001a38209de50900a0e10810a0e16afcffeb000050e334009d0500008705590000ea0900a0e10810a0e10420a0e162fcffeb000050e35300001a30209de50900a0e10810a0e15cfcffeb000050e34d00001a38209de50900a0e10810a0e156fcffeb000050e34700001a0900a0e10810a0e10520a0e150fcffeb000050e34100001a0900a0e10810a0e10b20a0e14afcffeb000050e3006087053a0000ea880189e0010980e2600690e51f0050e30500000a5f0050e30300000a9f0050e30100000adf0050e31000001ae4009fe5881189e00000b1e7010080e2000081e5004087e50060cae5000091e50006a0e16dfcfceb00008de504309de524009de55c209de50410a0e158fcfceb1e0000ea38209de50900a0e10810a0e127fcffeb000050e31800001a0900a0e10810a0e10420a0e121fcffeb000050e31200001a0900a0e10810a0e10b20a0e11bfcffeb000050e30c00001a30209de50900a0e10810a0e115fcffeb000050e30600001a34209de50900a0e10810a0e10ffcffeb000050e360009d0500008705018088e2010989e2c80690e5000058e1bafcffba64d08de2f04fbde81eff2fe1b846000064460000b446000060460000c3010000cc46000074530000e85300000f270000c1010000c0e1120268530000c20100008046000084460000", "lang": "cpp", "divergences": 17, "cand_size": 3656, "c_source": "//cpp\n#pragma opt_strength_reduction off\n#pragma opt_common_subs off\n\ntypedef unsigned char u8;\ntypedef unsigned short u16;\ntypedef unsigned int u32;\ntypedef int s32;\n\nextern \"C\" {\nextern void func_02012718(int a, int b);\nextern void func_02012dbc(int a);\nextern int func_ov006_020d25fc(void *thiz, int idx, u32 val);\nextern int func_020126e8(int a);\nextern void func_020126ac(int a0, int a1, int a2, int a3, int a4);\nextern int data_ov006_0212e1c0[];\n}\n\nstruct Obj {\n virtual void m00(); virtual void m04(); virtual void m08(); virtual void m0c();\n virtual void m10(); virtual void m14(); virtual void m18(); virtual void m1c();\n virtual void m20(); virtual void m24(); virtual void m28(); virtual void m2c();\n virtual void m30(); virtual void m34(); virtual void m38(); virtual void m3c();\n virtual void m40(); virtual void m44(); virtual void m48(); virtual void m4c();\n virtual void m50(); virtual void m54(); virtual void m58(); virtual void m5c();\n virtual void m60(); virtual void m64(); virtual void m68(); virtual void m6c();\n virtual void m70(); virtual void m74(); virtual void m78(); virtual void m7c();\n virtual void m80(); virtual void m84(); virtual void m88(); virtual void m8c();\n virtual int m90();\n};\n\nextern \"C\" void func_ov006_020d27dc(void *arg0)\n{\n char *p = (char *)arg0;\n s32 var_r4;\n s32 idx;\n s32 count;\n\n for (var_r4 = 0; var_r4 < (count = *(s32 *)(p + 0x46c8)); ) {\n s32 *slot = (s32 *)((int)p + var_r4 * 4 + 0x46b8);\n s32 v = *slot;\n var_r4++;\n if (v > 0) {\n *slot = v - 1;\n }\n }\n\n idx = 0;\n if (count <= 0) {\n return;\n }\n\n {\n s32 v20 = 0xd7;\n s32 v1c = 0xcf;\n s32 v18 = 0xc7;\n s32 v14 = 0xbf;\n s32 v10 = 0xe0;\n s32 v34 = 2;\n s32 v30 = 5;\n s32 v38 = 7;\n s32 vC = 0;\n s32 v60 = 0;\n s32 v5c = 0;\n s32 v58 = 0;\n s32 v54 = 0;\n s32 v50 = 0;\n s32 v4c = 0;\n s32 v48 = 0;\n s32 v44 = 0;\n s32 v40 = 0;\n s32 c1 = 1;\n s32 c4 = 4;\n s32 c6 = 6;\n s32 v24 = 0x1c0;\n s32 c3 = 3;\n s32 v3c = 0;\n s32 v2c = 0;\n s32 v28 = 0;\n\n do {\n if (*(s32 *)(p + idx * 4 + 0x46b8) > 0) {\n continue;\n }\n\n {\n int ent = (int)p + idx * 8;\n s32 tmp;\n s32 *distp = (s32 *)(ent + 0x4664);\n s32 dist = *distp;\n s32 lim = *(s32 *)(p + 0x4700);\n\n if (dist > lim) {\n u8 *flag = (u8 *)(p + idx + 0x46b4);\n if (*flag != 1) {\n s32 sl = vC;\n s32 *dirSlot;\n s32 dirVal;\n\n if (((struct Obj *)p)->m90() != 0) {\n u32 want = *(u32 *)(p + idx * 4 + 0x46a4);\n dirSlot = (s32 *)(p + idx * 8 + 0x4660);\n dirVal = *dirSlot;\n switch (dirVal) {\n case 0x20:\n if (*(s32 *)(p + 0x4714) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5398) = c1;\n }\n break;\n case 0x60:\n if (*(s32 *)(p + 0x4718) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5399) = c1;\n }\n break;\n case 0xa0:\n if (*(s32 *)(p + 0x471c) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539a) = c1;\n }\n break;\n case 0xe0:\n if (*(s32 *)(p + 0x4720) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539b) = c1;\n }\n break;\n }\n } else {\n dirSlot = (s32 *)(ent + 0x4660);\n dirVal = *dirSlot;\n switch (dirVal) {\n case 0x20:\n if (*(s32 *)(p + 0x4714) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5398) = c1;\n }\n break;\n case 0x60:\n if (*(s32 *)(p + 0x4718) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5399) = c1;\n }\n break;\n case 0xa0:\n if (*(s32 *)(p + 0x471c) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539a) = c1;\n }\n break;\n case 0xe0:\n if (*(s32 *)(p + 0x4720) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539b) = c1;\n }\n break;\n }\n }\n\n if (sl == 1) {\n if (((struct Obj *)p)->m90() != 0) {\n if (*(u8 *)(p + 0x46d5) == 0) {\n func_02012718(v10, *dirSlot << 0xc);\n u32 w2 = *(u32 *)(p + idx * 4 + 0x46a4);\n switch (w2) {\n default:\n break;\n case 0:\n func_02012718(v14, *dirSlot << 0xc);\n break;\n case 1:\n func_02012718(v18, *dirSlot << 0xc);\n break;\n case 2:\n func_02012718(v1c, *dirSlot << 0xc);\n break;\n case 3:\n func_02012718(v20, *dirSlot << 0xc);\n break;\n }\n } else {\n func_02012718(0x1c3, *dirSlot << 0xc);\n }\n *flag = c1;\n *(s32 *)(p + 0x46cc) += 1;\n if (*(s32 *)(p + 0x46cc) >= *(s32 *)(p + 0x46c8)) {\n if (*(u8 *)(p + 0x46d5) == 0) {\n *(s32 *)((int)p + 0x5374) += 1;\n *(s32 *)(p + 0x53e8) += 1;\n if (*(s32 *)(p + 0x53e8) > 0x270f) {\n *(s32 *)(p + 0x53e8) = 0x270f;\n }\n *(s32 *)(p + 0x53e0) = 0x78;\n return;\n }\n *(s32 *)(p + 0x53e0) = 0x1e;\n return;\n }\n continue;\n }\n\n {\n s32 *d2 = (s32 *)((int)(p + idx * 8) + 0x4660);\n func_02012718(v10, *d2 << 0xc);\n func_02012718(0x1c1, *d2 << 0xc);\n }\n *flag = c1;\n *(s32 *)(p + 0x46cc) += 1;\n if (*(s32 *)(p + 0x46cc) >= *(s32 *)(p + 0x46c8)) {\n s32 t;\n *(s32 *)((int)p + 0x5374) += 1;\n *(s32 *)(p + 0x53e8) += 1;\n if (*(s32 *)(p + 0x53e8) > 0x270f) {\n *(s32 *)(p + 0x53e8) = 0x270f;\n }\n t = *(s32 *)((char *)data_ov006_0212e1c0 + *(s32 *)(p + 0x53d4) * 0x1c);\n switch (t) {\n case 0:\n break;\n case 1:\n if ((*(s32 *)(p + 0x5374) % 2) == 0) {\n *(s32 *)(p + 0x5368) += 5;\n }\n break;\n case 2:\n *(s32 *)(p + 0x5368) += 5;\n break;\n }\n if (*(s32 *)(p + 0x5368) > 0x64) {\n *(s32 *)(p + 0x5368) = 0x64;\n }\n if (*(s32 *)((int)p + 0x5374) >= 5) {\n *(s32 *)(p + 0x53c0) = 0x3c;\n *(s32 *)(p + 0x46d0) = 2;\n *(u8 *)(p + 0x46d4) = 1;\n return;\n }\n *(s32 *)(p + 0x46d0) = 0;\n return;\n }\n continue;\n }\n\n if (((struct Obj *)p)->m90() != 0) {\n func_02012dbc(5);\n if (*(u8 *)(p + 0x46d5) == 0) {\n func_02012718(0x1c2, *(s32 *)(p + idx * 8 + 0x4660) << 0xc);\n } else {\n func_02012718(0x1c3, *(s32 *)(p + idx * 8 + 0x4660) << 0xc);\n }\n *flag = 1;\n *(u8 *)(p + 0x46d5) = 1;\n *(s32 *)(p + 0x46cc) += 1;\n if (*(s32 *)(p + 0x46cc) >= *(s32 *)(p + 0x46c8)) {\n *(s32 *)(p + 0x53e0) = 0x3c;\n }\n return;\n }\n func_02012718(0xe1, *(s32 *)(p + idx * 8 + 0x4660) << 0xc);\n *(s32 *)(p + 0x53c0) = 0x3c;\n *(s32 *)(p + 0x46d0) = 2;\n *(u8 *)(p + 0x46d5) = 1;\n return;\n }\n continue;\n }\n\n if (dist < -0xc0 || dist >= 0x98) {\n *distp += 1;\n } else {\n u8 *flag2 = (u8 *)(p + idx + 0x4680);\n if ((u32)*flag2 <= 1) {\n *distp = dist + 1;\n if (func_ov006_020d25fc(p, idx, c3) == 0) {\n func_ov006_020d25fc(p, idx, c4);\n }\n } else {\n tmp = ((dist + 0xd4) * 0x1f4) / (lim + 0xd4);\n s32 *statePtr = (s32 *)(p + idx * 4 + 0x4684);\n u32 state = *statePtr;\n switch (state) {\n default:\n break;\n case 0:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x21 || *(s32 *)(p + idx * 8 + 0x4660) == 0x61 ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0xa1 || *(s32 *)(p + idx * 8 + 0x4660) == 0xe1) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp -= 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v28, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v2c) == 0 && func_ov006_020d25fc(p, idx, c1) == 0 &&\n func_ov006_020d25fc(p, idx, c3) == 0 && func_ov006_020d25fc(p, idx, v30) == 0) {\n if (func_ov006_020d25fc(p, idx, v34) == 0) {\n *statePtr = v38;\n }\n }\n break;\n case 1:\n if (func_ov006_020d25fc(p, idx, c1) == 0 && func_ov006_020d25fc(p, idx, v3c) == 0 &&\n func_ov006_020d25fc(p, idx, v34) == 0 && func_ov006_020d25fc(p, idx, c3) == 0) {\n if (func_ov006_020d25fc(p, idx, c4) == 0) {\n *statePtr = c6;\n }\n }\n break;\n case 2:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x1f || *(s32 *)(p + idx * 8 + 0x4660) == 0x5f ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0x9f || *(s32 *)(p + idx * 8 + 0x4660) == 0xdf) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp += 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v40, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v34) == 0 && func_ov006_020d25fc(p, idx, c1) == 0 &&\n func_ov006_020d25fc(p, idx, c4) == 0 && func_ov006_020d25fc(p, idx, v44) == 0) {\n if (func_ov006_020d25fc(p, idx, v38) == 0) {\n *statePtr = v30;\n }\n }\n break;\n case 3:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x21 || *(s32 *)(p + idx * 8 + 0x4660) == 0x61 ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0xa1 || *(s32 *)(p + idx * 8 + 0x4660) == 0xe1) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp -= 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v48, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, c3) == 0 && func_ov006_020d25fc(p, idx, v4c) == 0 &&\n func_ov006_020d25fc(p, idx, v30) == 0 && func_ov006_020d25fc(p, idx, c1) == 0) {\n if (func_ov006_020d25fc(p, idx, c6) == 0) {\n *statePtr = c4;\n }\n }\n break;\n case 4:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x1f || *(s32 *)(p + idx * 8 + 0x4660) == 0x5f ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0x9f || *(s32 *)(p + idx * 8 + 0x4660) == 0xdf) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp += 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v50, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, c4) == 0 && func_ov006_020d25fc(p, idx, v34) == 0 &&\n func_ov006_020d25fc(p, idx, v38) == 0 && func_ov006_020d25fc(p, idx, c1) == 0) {\n if (func_ov006_020d25fc(p, idx, c6) == 0) {\n *statePtr = c3;\n }\n }\n break;\n case 5:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x21 || *(s32 *)(p + idx * 8 + 0x4660) == 0x61 ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0xa1 || *(s32 *)(p + idx * 8 + 0x4660) == 0xe1) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp -= 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v54, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v30) == 0 && func_ov006_020d25fc(p, idx, c6) == 0 &&\n func_ov006_020d25fc(p, idx, c3) == 0 && func_ov006_020d25fc(p, idx, v58) == 0) {\n if (func_ov006_020d25fc(p, idx, v38) == 0) {\n *statePtr = v34;\n }\n }\n break;\n case 6:\n if (func_ov006_020d25fc(p, idx, c6) == 0 && func_ov006_020d25fc(p, idx, v30) == 0 &&\n func_ov006_020d25fc(p, idx, v38) == 0 && func_ov006_020d25fc(p, idx, c3) == 0) {\n if (func_ov006_020d25fc(p, idx, c4) == 0) {\n *statePtr = c1;\n }\n }\n break;\n case 7:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x1f || *(s32 *)(p + idx * 8 + 0x4660) == 0x5f ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0x9f || *(s32 *)(p + idx * 8 + 0x4660) == 0xdf) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp += 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v5c, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v38) == 0 && func_ov006_020d25fc(p, idx, c6) == 0 &&\n func_ov006_020d25fc(p, idx, c4) == 0 && func_ov006_020d25fc(p, idx, v30) == 0 &&\n func_ov006_020d25fc(p, idx, v34) == 0) {\n *statePtr = v60;\n }\n break;\n }\n }\n }\n }\n } while (++idx < *(s32 *)(p + 0x46c8));\n }\n}\n", "source": "m100", "evaluator": "2004/b56|m2"} +{"module": "ov006", "addr": "0x020d27dc", "name": "func_ov006_020d27dc", "size": 3656, "target_hex": "f04f2de964d04de20090a0e1011989e2c82691e50040a0e3000052e30a0000dae40d9fe5042189e0003082e0002093e5014084e2000052e3012042c2002083c5c82691e5020054e1f5ffffba000052e30080a0e364d08dd2f04fbdd81eff2fd1d700a0e320008de5cf00a0e31c008de5c700a0e318008de5bf00a0e314008de5e000a0e310008de50200a0e334008de50500a0e330008de50700a0e338008de5070da0e30c808de560808de55c808de558808de554808de550808de54c808de548808de544808de540808de50160a0e304b0a0e30640a0e324008de50350a0e33c808de52c808de528808de5080189e0010980e2b80690e5000050e33a0300ca080d9fe5887189e0002087e0010989e2001092e5000790e5000051e15e0100daec0c9fe5081089e0000081e008008de50000d0e5010050e32b03000a0900a0e1001090e50ca09de5901091e531ff2fe1000050e33100000ab81c9fe50720a0e1017082e0080189e0001097e5010980e2a40690e5600051e3040000ca600051e3110000aa200051e30800000a4f0000eaa00051e3020000caa00051e31100000a4a0000eae00051e31500000a470000ea011989e2141791e5000051e1050a891206a0a0019863c015400000ea011989e2181791e5000051e1050a891206a0a0019963c015390000ea011989e21c1791e5000051e1050a891206a0a0019a63c015320000ea011989e2201791e5000051e1050a891206a0a0019b63c0152b0000eaf00b9fe50000b7e7600050e3040000ca600050e3110000aa200050e30800000a220000eaa00050e3020000caa00050e31100000a1d0000eae00050e31500000a1a0000ea010989e2140790e5010050e3050a891206a0a0019863c015130000ea010989e2180790e5010050e3050a891206a0a0019963c0150c0000ea010989e21c0790e5010050e3050a891206a0a0019a63c015050000ea010989e2200790e5010050e3050a891206a0a0019b63c01501005ae3b300001a0900a0e1001090e5901091e531ff2fe1000050e35300000a010989e2d506d0e5000050e32100001a001097e510009de50116a0e10afffceb080189e0010980e2a40690e5030050e300f18f901b0000ea020000ea060000ea0a0000ea0e0000ea001097e514009de50116a0e1fcfefceb120000ea001097e518009de50116a0e1f7fefceb0d0000ea001097e51c009de50116a0e1f2fefceb080000ea001097e520009de50116a0e1edfefceb030000ea001097e5880a9fe50116a0e1e8fefceb08009de50060c0e5780a9fe5002089e0001092e5010989e2011081e2001082e5cc2690e5c81690e5010052e1880200bad506d0e5000050e31400001a480a9fe5481a9fe5003089e0000093e5012089e0010080e2000083e5001092e5050a89e2011081e2001082e5e82390e5201a9fe564d08de2010052e1e81380c5050a89e27810a0e3e01380e5f04fbde81eff2fe1050a89e21e10a0e3e01380e564d08de2f04fbde81eff2fe1d0099fe5881189e0007081e0001097e510009de50116a0e1b7fefceb001097e5c8099fe50116a0e1b3fefceb08009de50060c0e5a4099fe5002089e0001092e5010989e2011081e2001082e5cc1690e5c80690e5000051e1530200ba80099fe580199fe5003089e0000093e5012089e0010080e2000083e5001092e5050a89e2011081e2001082e5e82390e558199fe5010052e1e81380c5050a89e2d42390e51c10a0e3920103e044199fe5031091e7000051e31200000a010051e30600000a020051e32c099f0500108900000091050500800200008105090000ea740390e5a01fa0e1800f61e0e00f91e00400001a00099fe5001089e0000091e5050080e2000081e5050a89e2681390e5640051e36410a0c3681380c5050a89e2741390e5050051e3090000ba3c10a0e3c01380e5010989e20210a0e3d01680e50110a0e3d416c0e564d08de2f04fbde81eff2fe1010989e20010a0e3d01680e564d08de2f04fbde81eff2fe10900a0e1001090e5901091e531ff2fe1000050e32500000a0500a0e30500fdeb010989e2d506d0e5000050e30600001a880189e0010980e2601690e550089fe50116a0e152fefceb050000ea880189e0010980e2601690e514089fe50116a0e14bfefceb08009de50120a0e30020c0e5010989e2fc179fe5d526c0e5012089e0001092e564d08de2011081e2001082e5cc1690e5c80690e5000051e1050a89a23c10a0a3e01380a5f04fbde81eff2fe1880189e0010980e2601690e5e100a0e30116a0e132fefceb050a89e23c10a0e3c01380e5010989e20210a0e3d01680e50110a0e3d516c0e564d08de2f04fbde81eff2fe1bf30e0e3030051e1010000ba980051e3030000ba000092e5010080e2000082e5ca0100ea78379fe5087089e003a087e00030dae5010053e30c00008a010081e2000082e50900a0e10810a0e10520a0e1cbfdffeb000050e3bc01001a0900a0e10810a0e10b20a0e1c5fdffebb70100ead42081e2d41080e27d0fa0e3920000e0399ffceb04008de518079fe5081189e0007081e0000097e5070050e300f18f90aa0100ea060000ea410000ea5f0000ea9a0000ead40000ea0e0100ea490100ea670100ea880189e0010980e2600690e5210050e30500000a610050e30300000aa10050e30100000ae10050e31000001a84069fe5881189e00000b1e7010040e2000081e5004087e50060cae5000091e50006a0e1d5fdfceb00008de504309de524009de528209de50410a0e1c0fdfceb860100ea2c209de50900a0e10810a0e18ffdffeb000050e38001001a0900a0e10810a0e10620a0e189fdffeb000050e37a01001a0900a0e10810a0e10520a0e183fdffeb000050e37401001a30209de50900a0e10810a0e17dfdffeb000050e36e01001a34209de50900a0e10810a0e177fdffeb000050e338009d0500008705660100ea0900a0e10810a0e10620a0e16ffdffeb000050e36001001a3c209de50900a0e10810a0e169fdffeb000050e35a01001a34209de50900a0e10810a0e163fdffeb000050e35401001a0900a0e10810a0e10520a0e15dfdffeb000050e34e01001a0900a0e10810a0e10b20a0e157fdffeb000050e300408705470100ea880189e0010980e2600690e51f0050e30500000a5f0050e30300000a9f0050e30100000adf0050e31000001a18059fe5881189e00000b1e7010080e2000081e5004087e50060cae5000091e50006a0e17afdfceb00008de504309de524009de540209de50410a0e165fdfceb2b0100ea34209de50900a0e10810a0e134fdffeb000050e32501001a0900a0e10810a0e10620a0e12efdffeb000050e31f01001a0900a0e10810a0e10b20a0e128fdffeb000050e31901001a44209de50900a0e10810a0e122fdffeb000050e31301001a38209de50900a0e10810a0e11cfdffeb000050e330009d05000087050b0100ea880189e0010980e2600690e5210050e30500000a610050e30300000aa10050e30100000ae10050e31000001a28049fe5881189e00000b1e7010040e2000081e5004087e50060cae5000091e50006a0e13efdfceb00008de504309de524009de548209de50410a0e129fdfcebef0000ea0900a0e10810a0e10520a0e1f8fcffeb000050e3e900001a4c209de50900a0e10810a0e1f2fcffeb000050e3e300001a30209de50900a0e10810a0e1ecfcffeb000050e3dd00001a0900a0e10810a0e10620a0e1e6fcffeb000050e3d700001a0900a0e10810a0e10420a0e1e0fcffeb000050e300b08705d00000ea880189e0010980e2600690e51f0050e30500000a5f0050e30300000a9f0050e30100000adf0050e31000001a3c039fe5881189e00000b1e7010080e2000081e5004087e50060cae5000091e50006a0e103fdfceb00008de504309de524009de550209de50410a0e1eefcfcebb40000ea0900a0e10810a0e10b20a0e1bdfcffeb000050e3ae00001a34209de50900a0e10810a0e1b7fcffeb000050e3a800001a38209de50900a0e10810a0e1b1fcffeb000050e3a200001a0900a0e10810a0e10620a0e1abfcffeb000050e39c00001a0900a0e10810a0e10420a0e1a5fcffeb000050e300508705950000ea880189e0010980e2600690e5210050e30500000a610050e30300000aa10050e30100000ae10050e31000001a50029fe5881189e00000b1e7010040e2000081e5004087e50060cae5000091e50006a0e1c8fcfceb00008de504309de524009de554209de50410a0e1b3fcfceb790000ea30209de50900a0e10810a0e182fcffeb000050e37300001a0900a0e10810a0e10420a0e17cfcffeb000050e36d00001a0900a0e10810a0e10520a0e176fcffeb000050e36700001a58209de50900a0e10810a0e170fcffeb000050e36100001a38209de50900a0e10810a0e16afcffeb000050e334009d0500008705590000ea0900a0e10810a0e10420a0e162fcffeb000050e35300001a30209de50900a0e10810a0e15cfcffeb000050e34d00001a38209de50900a0e10810a0e156fcffeb000050e34700001a0900a0e10810a0e10520a0e150fcffeb000050e34100001a0900a0e10810a0e10b20a0e14afcffeb000050e3006087053a0000ea880189e0010980e2600690e51f0050e30500000a5f0050e30300000a9f0050e30100000adf0050e31000001ae4009fe5881189e00000b1e7010080e2000081e5004087e50060cae5000091e50006a0e16dfcfceb00008de504309de524009de55c209de50410a0e158fcfceb1e0000ea38209de50900a0e10810a0e127fcffeb000050e31800001a0900a0e10810a0e10420a0e121fcffeb000050e31200001a0900a0e10810a0e10b20a0e11bfcffeb000050e30c00001a30209de50900a0e10810a0e115fcffeb000050e30600001a34209de50900a0e10810a0e10ffcffeb000050e360009d0500008705018088e2010989e2c80690e5000058e1bafcffba64d08de2f04fbde81eff2fe1b846000064460000b446000060460000c3010000cc46000074530000e85300000f270000c1010000c0e1120268530000c20100008046000084460000", "lang": "cpp", "divergences": 17, "cand_size": 3656, "c_source": "//cpp\n#pragma opt_strength_reduction off\n#pragma opt_common_subs off\n\ntypedef unsigned char u8;\ntypedef unsigned short u16;\ntypedef unsigned int u32;\ntypedef int s32;\n\nextern \"C\" {\nextern void func_02012718(int a, int b);\nextern void func_02012dbc(int a);\nextern int func_ov006_020d25fc(void *thiz, int idx, u32 val);\nextern int func_020126e8(int a);\nextern void func_020126ac(int a0, int a1, int a2, int a3, int a4);\nextern int data_ov006_0212e1c0[];\n}\n\nstruct Obj {\n virtual void m00(); virtual void m04(); virtual void m08(); virtual void m0c();\n virtual void m10(); virtual void m14(); virtual void m18(); virtual void m1c();\n virtual void m20(); virtual void m24(); virtual void m28(); virtual void m2c();\n virtual void m30(); virtual void m34(); virtual void m38(); virtual void m3c();\n virtual void m40(); virtual void m44(); virtual void m48(); virtual void m4c();\n virtual void m50(); virtual void m54(); virtual void m58(); virtual void m5c();\n virtual void m60(); virtual void m64(); virtual void m68(); virtual void m6c();\n virtual void m70(); virtual void m74(); virtual void m78(); virtual void m7c();\n virtual void m80(); virtual void m84(); virtual void m88(); virtual void m8c();\n virtual int m90();\n};\n\nextern \"C\" void func_ov006_020d27dc(void *arg0)\n{\n char *p = (char *)arg0;\n s32 var_r4;\n s32 idx;\n s32 count;\n\n for (var_r4 = 0; var_r4 < (count = *(s32 *)(p + 0x46c8)); ) {\n s32 *slot = (s32 *)((int)p + var_r4 * 4 + 0x46b8);\n s32 v = *slot;\n var_r4++;\n if (v > 0) {\n *slot = v - 1;\n }\n }\n\n idx = 0;\n if (count <= 0) {\n return;\n }\n\n {\n s32 v20 = 0xd7;\n s32 v1c = 0xcf;\n s32 v18 = 0xc7;\n s32 v14 = 0xbf;\n s32 v10 = 0xe0;\n s32 v34 = 2;\n s32 v30 = 5;\n s32 v38 = 7;\n s32 vC = 0;\n s32 v60 = 0;\n s32 v5c = 0;\n s32 v58 = 0;\n s32 v54 = 0;\n s32 v50 = 0;\n s32 v4c = 0;\n s32 v48 = 0;\n s32 v44 = 0;\n s32 v40 = 0;\n s32 c1 = 1;\n s32 c4 = 4;\n s32 c6 = 6;\n s32 v24 = 0x1c0;\n s32 c3 = 3;\n s32 v3c = 0;\n s32 v2c = 0;\n s32 v28 = 0;\n\n do {\n if (*(s32 *)(p + idx * 4 + 0x46b8) > 0) {\n continue;\n }\n\n {\n int ent = (int)p + idx * 8;\n s32 tmp;\n s32 *distp = (s32 *)(ent + 0x4664);\n s32 dist = *distp;\n s32 lim = *(s32 *)(p + 0x4700);\n\n if (dist > lim) {\n u8 *flag = (u8 *)(p + idx + 0x46b4);\n if (*flag != 1) {\n s32 sl = vC;\n s32 *dirSlot;\n s32 dirVal;\n\n if (((struct Obj *)p)->m90() != 0) {\n u32 want = *(u32 *)(p + idx * 4 + 0x46a4);\n dirSlot = (s32 *)(p + idx * 8 + 0x4660);\n dirVal = *dirSlot;\n switch (dirVal) {\n case 0x20:\n if (*(s32 *)(p + 0x4714) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5398) = c1;\n }\n break;\n case 0x60:\n if (*(s32 *)(p + 0x4718) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5399) = c1;\n }\n break;\n case 0xa0:\n if (*(s32 *)(p + 0x471c) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539a) = c1;\n }\n break;\n case 0xe0:\n if (*(s32 *)(p + 0x4720) == (s32)want) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539b) = c1;\n }\n break;\n }\n } else {\n dirSlot = (s32 *)(ent + 0x4660);\n dirVal = *dirSlot;\n switch (dirVal) {\n case 0x20:\n if (*(s32 *)(p + 0x4714) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5398) = c1;\n }\n break;\n case 0x60:\n if (*(s32 *)(p + 0x4718) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x5399) = c1;\n }\n break;\n case 0xa0:\n if (*(s32 *)(p + 0x471c) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539a) = c1;\n }\n break;\n case 0xe0:\n if (*(s32 *)(p + 0x4720) == 1) {\n sl = c1;\n } else {\n *(u8 *)(p + 0x539b) = c1;\n }\n break;\n }\n }\n\n if (sl == 1) {\n if (((struct Obj *)p)->m90() != 0) {\n if (*(u8 *)(p + 0x46d5) == 0) {\n func_02012718(v10, *dirSlot << 0xc);\n u32 w2 = *(u32 *)(p + idx * 4 + 0x46a4);\n switch (w2) {\n default:\n break;\n case 0:\n func_02012718(v14, *dirSlot << 0xc);\n break;\n case 1:\n func_02012718(v18, *dirSlot << 0xc);\n break;\n case 2:\n func_02012718(v1c, *dirSlot << 0xc);\n break;\n case 3:\n func_02012718(v20, *dirSlot << 0xc);\n break;\n }\n } else {\n func_02012718(0x1c3, *dirSlot << 0xc);\n }\n *flag = c1;\n *(s32 *)(p + 0x46cc) += 1;\n if (*(s32 *)(p + 0x46cc) >= *(s32 *)(p + 0x46c8)) {\n if (*(u8 *)(p + 0x46d5) == 0) {\n *(s32 *)((int)p + 0x5374) += 1;\n *(s32 *)(p + 0x53e8) += 1;\n if (*(s32 *)(p + 0x53e8) > 0x270f) {\n *(s32 *)(p + 0x53e8) = 0x270f;\n }\n *(s32 *)(p + 0x53e0) = 0x78;\n return;\n }\n *(s32 *)(p + 0x53e0) = 0x1e;\n return;\n }\n continue;\n }\n\n {\n s32 *d2 = (s32 *)((int)(p + idx * 8) + 0x4660);\n func_02012718(v10, *d2 << 0xc);\n func_02012718(0x1c1, *d2 << 0xc);\n }\n *flag = c1;\n *(s32 *)(p + 0x46cc) += 1;\n if (*(s32 *)(p + 0x46cc) >= *(s32 *)(p + 0x46c8)) {\n s32 t;\n *(s32 *)((int)p + 0x5374) += 1;\n *(s32 *)(p + 0x53e8) += 1;\n if (*(s32 *)(p + 0x53e8) > 0x270f) {\n *(s32 *)(p + 0x53e8) = 0x270f;\n }\n t = *(s32 *)((char *)data_ov006_0212e1c0 + *(s32 *)(p + 0x53d4) * 0x1c);\n switch (t) {\n case 0:\n break;\n case 1:\n if ((*(s32 *)(p + 0x5374) % 2) == 0) {\n *(s32 *)(p + 0x5368) += 5;\n }\n break;\n case 2:\n *(s32 *)(p + 0x5368) += 5;\n break;\n }\n if (*(s32 *)(p + 0x5368) > 0x64) {\n *(s32 *)(p + 0x5368) = 0x64;\n }\n if (*(s32 *)((int)p + 0x5374) >= 5) {\n *(s32 *)(p + 0x53c0) = 0x3c;\n *(s32 *)(p + 0x46d0) = 2;\n *(u8 *)(p + 0x46d4) = 1;\n return;\n }\n *(s32 *)(p + 0x46d0) = 0;\n return;\n }\n continue;\n }\n\n if (((struct Obj *)p)->m90() != 0) {\n func_02012dbc(5);\n if (*(u8 *)(p + 0x46d5) == 0) {\n func_02012718(0x1c2, *(s32 *)(p + idx * 8 + 0x4660) << 0xc);\n } else {\n func_02012718(0x1c3, *(s32 *)(p + idx * 8 + 0x4660) << 0xc);\n }\n *flag = 1;\n *(u8 *)(p + 0x46d5) = 1;\n *(s32 *)(p + 0x46cc) += 1;\n if (*(s32 *)(p + 0x46cc) >= *(s32 *)(p + 0x46c8)) {\n *(s32 *)(p + 0x53e0) = 0x3c;\n }\n return;\n }\n func_02012718(0xe1, *(s32 *)(p + idx * 8 + 0x4660) << 0xc);\n *(s32 *)(p + 0x53c0) = 0x3c;\n *(s32 *)(p + 0x46d0) = 2;\n *(u8 *)(p + 0x46d5) = 1;\n return;\n }\n continue;\n }\n\n if (dist < -0xc0 || dist >= 0x98) {\n *distp += 1;\n } else {\n u8 *flag2 = (u8 *)(p + idx + 0x4680);\n if ((u32)*flag2 <= 1) {\n *distp = dist + 1;\n if (func_ov006_020d25fc(p, idx, c3) == 0) {\n func_ov006_020d25fc(p, idx, c4);\n }\n } else {\n tmp = ((dist + 0xd4) * 0x1f4) / (lim + 0xd4);\n s32 *statePtr = (s32 *)(p + idx * 4 + 0x4684);\n u32 state = *statePtr;\n switch (state) {\n default:\n break;\n case 0:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x21 || *(s32 *)(p + idx * 8 + 0x4660) == 0x61 ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0xa1 || *(s32 *)(p + idx * 8 + 0x4660) == 0xe1) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp -= 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v28, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v2c) == 0 && func_ov006_020d25fc(p, idx, c1) == 0 &&\n func_ov006_020d25fc(p, idx, c3) == 0 && func_ov006_020d25fc(p, idx, v30) == 0) {\n if (func_ov006_020d25fc(p, idx, v34) == 0) {\n *statePtr = v38;\n }\n }\n break;\n case 1:\n if (func_ov006_020d25fc(p, idx, c1) == 0 && func_ov006_020d25fc(p, idx, v3c) == 0 &&\n func_ov006_020d25fc(p, idx, v34) == 0 && func_ov006_020d25fc(p, idx, c3) == 0) {\n if (func_ov006_020d25fc(p, idx, c4) == 0) {\n *statePtr = c6;\n }\n }\n break;\n case 2:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x1f || *(s32 *)(p + idx * 8 + 0x4660) == 0x5f ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0x9f || *(s32 *)(p + idx * 8 + 0x4660) == 0xdf) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp += 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v40, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v34) == 0 && func_ov006_020d25fc(p, idx, c1) == 0 &&\n func_ov006_020d25fc(p, idx, c4) == 0 && func_ov006_020d25fc(p, idx, v44) == 0) {\n if (func_ov006_020d25fc(p, idx, v38) == 0) {\n *statePtr = v30;\n }\n }\n break;\n case 3:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x21 || *(s32 *)(p + idx * 8 + 0x4660) == 0x61 ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0xa1 || *(s32 *)(p + idx * 8 + 0x4660) == 0xe1) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp -= 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v48, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, c3) == 0 && func_ov006_020d25fc(p, idx, v4c) == 0 &&\n func_ov006_020d25fc(p, idx, v30) == 0 && func_ov006_020d25fc(p, idx, c1) == 0) {\n if (func_ov006_020d25fc(p, idx, c6) == 0) {\n *statePtr = c4;\n }\n }\n break;\n case 4:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x1f || *(s32 *)(p + idx * 8 + 0x4660) == 0x5f ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0x9f || *(s32 *)(p + idx * 8 + 0x4660) == 0xdf) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp += 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v50, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, c4) == 0 && func_ov006_020d25fc(p, idx, v34) == 0 &&\n func_ov006_020d25fc(p, idx, v38) == 0 && func_ov006_020d25fc(p, idx, c1) == 0) {\n if (func_ov006_020d25fc(p, idx, c6) == 0) {\n *statePtr = c3;\n }\n }\n break;\n case 5:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x21 || *(s32 *)(p + idx * 8 + 0x4660) == 0x61 ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0xa1 || *(s32 *)(p + idx * 8 + 0x4660) == 0xe1) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp -= 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v54, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v30) == 0 && func_ov006_020d25fc(p, idx, c6) == 0 &&\n func_ov006_020d25fc(p, idx, c3) == 0 && func_ov006_020d25fc(p, idx, v58) == 0) {\n if (func_ov006_020d25fc(p, idx, v38) == 0) {\n *statePtr = v34;\n }\n }\n break;\n case 6:\n if (func_ov006_020d25fc(p, idx, c6) == 0 && func_ov006_020d25fc(p, idx, v30) == 0 &&\n func_ov006_020d25fc(p, idx, v38) == 0 && func_ov006_020d25fc(p, idx, c3) == 0) {\n if (func_ov006_020d25fc(p, idx, c4) == 0) {\n *statePtr = c1;\n }\n }\n break;\n case 7:\n if (*(s32 *)(p + idx * 8 + 0x4660) == 0x1f || *(s32 *)(p + idx * 8 + 0x4660) == 0x5f ||\n *(s32 *)(p + idx * 8 + 0x4660) == 0x9f || *(s32 *)(p + idx * 8 + 0x4660) == 0xdf) {\n {\n s32 *dirp = (s32 *)((int)(p + idx * 8) + 0x4660);\n *dirp += 1;\n *statePtr = c6;\n *flag2 = c1;\n func_020126ac(v24, c6, v5c, tmp, func_020126e8(*dirp << 0xc));\n }\n } else if (func_ov006_020d25fc(p, idx, v38) == 0 && func_ov006_020d25fc(p, idx, c6) == 0 &&\n func_ov006_020d25fc(p, idx, c4) == 0 && func_ov006_020d25fc(p, idx, v30) == 0 &&\n func_ov006_020d25fc(p, idx, v34) == 0) {\n *statePtr = v60;\n }\n break;\n }\n }\n }\n }\n } while (++idx < *(s32 *)(p + 0x46c8));\n }\n}\n", "source": "m100", "evaluator": "2004/b56|m2", "floor": {"class": "cond_opt", "evidence": "If-conversion floor, re-measured 2026-09-13. The stored c_source spells *(s32 *)((int)p + 0x5374) at line 241; the ROM addresses that site as 'add r0,sb,#0x5000 / ldr r1,[r0,#0x374]', while the cast forces 'ldr r0,[pc,#0x8c4] / ldr r0,[sb,r0]' plus a literal-pool word. Dropping that one cast yields 3652 bytes, md5 8462f11dba034fd64356bc06233a65cf, byte-equal to the ROM outside a single word with the whole literal pool identical; the same cast at lines 40/197/220 is byte-inert (identical object, 3656, md5 163fe692d7ce77134ede8bc0db9f5f08). Sole residue is the ROM's blt at +0x564, where mwccarm predicates the three-instruction '< 5' arm because that arm is laid out as the fall-through. Budget is exactly +1 word: corrected object 3652 against the ROM's 3656. The corrected source is deliberately NOT stored here: evaluate_full sentinels its size mismatch at 999 and the strictly-improving upsert refuses it against the stored 17, and the stored 17 is size-exact only by virtue of that spurious pool word. A 14-divergence size-exact variant exists but is logically wrong (it stores to p+0x46d4, which the ROM's low arm does not do) and is not banked. Refuted this pass: refusal condition (d) is not the mechanism, ROM +0x590 has exactly one predecessor; join-form layouts J1/J2/J3 all compile to 3652 byte-identical; volatile on the low arm, the high arm or the condition all compile to 3652 byte-identical. Price table and the two matched precedents are in notes/mwccarm-codegen.md section 6cn.", "date": "2026-09-13"}} {"module": "ov006", "addr": "0x0210c9e0", "name": "_ZN12dScMgSlot1_c8BehaviorEv", "size": 2076, "target_hex": "f04f2de904d04de20040a0e1012984e2b41692e50d0051e301f18f90d10100ea0c0000ea270000ea330000ea3a0000eaf30000ea2a0100ea390100ea4b0100eab00100ea7c0100eabd0100ea7a0100eabb0100ea970100ea0010a0e30130a0e3010084e0010980e2011081e20237c0e5030051e3f9ffffba010984e20020a0e30527c0e50a27c0e50b27c0e51c179fe5b43680e5010084e015feffebc400d4e53c10a0e3000050e30100a003c300c405c400c4050000a003b00cc401010984e20c17c0e5a70100eae4069fe5000084e0c7b8fceb000050e3a201001a160ea0e32317fceb010984e21e10a0e30c17c0e50210a0e3b41680e59a0100eab0069fe5000084e0bab8fceb000050e3010984020310a003b4168005920100ea0090a0e30980a0e18c669fe50930a0e188069fe588b69fe588169fe588269fe5085084e002a085e00050dae5010055e30400000a085184e0015985e2a45695e5000055e32000000a015984e20857d5e5087184e0019089e208c085e00150b7e70cc196e70c5045e0005087e5005097e5000055e3140000aa0050dae5010055e3003087151000001a20569fe508a084e005508ae000a0d5e501a08ae200a0c5e500c0d5e590accee04ee1a0e1acafa0e10ee08ae09beecae00ee04ce000e0c5e5005097e5015785e2005087e5018088e2030058e3d1ffffba000059e30700000a010984e2b00690e5c4259fe50210a0e30030a0e33316fceb011984e2b00681e5010984e20507d0e5030050e34000002aa0059fe5a0159fe50020d0e50030a0e30201d1e70211a0e1000050e30300000a88059fe50100d0e7000050e30130a013000053e34001000a6c059fe50211a0e1010080e00290d0e50360d0e560859fe544259fe50050a0e31f10e0e3050084e00230f0e7010053e32100001a853188e0857198e7043093e5077049e0200057e3033046e01a0000ca010057e1180000ba200053e3160000ca010053e1140000ba10159fe50030a0e30030c0e5012084e00010d2e5010984e2011081e20010c2e57116d0e5000051e30300000a7136c0e5a80094e5b41094e5ac82feebd0149fe5d4049fe5851191e70116a0e18616fceb110100ea015085e2030055e3d6ffffba0d0100ea0130a0e30020a0e30210a0e1020184e0010980e2a40690e5012082e2000050e30130a011030052e3f7ffffba010053e30001001a0400a0e1ecfdffeb011984e20a07c1e50000a0e3b80681e50a07d1e5000050e30700000a0927d1e558049fe558149fe5003084e00200d1e7001093e5000081e0000083e5010984e20b27d0e5000052e30500000a030052e328049f3500108430000091358200803000008135010984e2a83094e5b82690e57c0690e5b41094e5923020e07382feeb010984e20410a0e3b41680e53c10a0e30c17c0e5d80000eaa8039fe5000084e0f8b7fceb000050e3d300001a010984e20a17d0e5000051e30800000a0927d0e5c0039fe5c0139fe50231a0e1bc239fe5f31091e1f32092e1000084e0fafcffeb010984e20b07d0e5000050e30a00000a030050e30800002a010040e290139fe50031a0e18c239fe58c039fe5f31091e1f32092e1000084e0ebfcffeb011984e2b80691e5000050e30900000a6c039fe50520a0e3b42681e56420a0e3000084e00c27c1e5bafcffeb2600a0e33c16fceb050000ea0700a0e3b40681e53c20a0e30e00a0e30c27c1e53516fceb0000a0e3c300c4e5a00000eac8029fe5000084e0c0b7fceb000050e39b00001a011984e2ac029fe5b81691e5000084e0f4fcffeb010984e23c10a0e30c17c0e50610a0e3b41680e5900000ea800692e5000050e30100a0030000a013000050e38a00000aa80094e5fd82feeb68029fe5000084e0a8b7fceb000050e38300001a0400a0e1002090e50410a0e3482092e532ff2fe17d0000ea3c029fe5000084e09db7fceb000050e37800001aa80094e5000050e3050000da0400a0e1002090e50510a0e3482092e532ff2fe16f0000ea0450a0e10060a0e30d10a0e308729fe50c829fe5f8019fe5f8b19fe5062184e0079082e0003099e5062084e0013783e2003089e5083082e00020d3e5016086e2030056e3012082e20020c3e50020d3e59092cae04aa1a0e1a29fa0e10aa089e09b9acae009a042e000a0c3e50020d3e5022085e0012982e2c016c2e5155085e2e5ffffba010984e20910a0e3b41680e54a0000ea80019fe5091041e2c150a0e1003084e0051193e7050184e0021a41e2051183e7011980e2a40691e5000050e33e0000aa0030a0e398019fe5a43681e50a10a0e30c17c2e5002084e0001092e550019fe5011081e2001082e5851190e7590fa0e30116a0e1a415fceb000055e32e00001a0200a0e37784feeb2b0000ea54019fe5001084e0000091e5020a40e2000081e5ac0692e5000050e3230000aa0000a0e3ac0682e53c00a0e30c07c2e50810a0e3ec009fe5b41682e5101090e5590fa0e30116a0e18c15fceb170000eaa4009fe5000084e037b7fceb000050e31200001af4009fe53684fcebec009fe50210a0e3e286fceb0010a0e30120a0e10500a0e38984fceb080000ea68009fe5000084e028b7fceb000050e3b4009f050010840000009105010080020000810540009fe5000084e0001090e5001091e531ff2fe170009fe5000084e043fcffeb78009fe5000084e040fcffeb70009fe5000084e009fcffeb0100a0e304d08de2f04fbde81eff2fe1604600000c47000000e61302310cc33015000000a446000002470000ff46000061010000400e0a02e80d0a02e90d0a023ce613020547000062010000b8460000d8e413028446000054e6130256e61302f8e41302fae41302904600009c460000b4460000ac4600001cf60902", "lang": "cpp", "divergences": 19, "cand_size": 2076, "c_source": "//cpp\r\n#include \"dScMgSlot1_c.h\"\r\n\r\nextern \"C\" {\r\nextern u8 DecIfAbove0_Byte(u8 *p);\r\nextern int Sound_PlayIfNotActive(int handle, int a, int b, int c);\r\nextern void func_02012718(int a, int b);\r\nextern void func_02012790(int a);\r\nextern void func_0202ec9c(void *fader, int a);\r\nextern void func_ov004_020ad79c(int a, int b);\r\nextern void func_ov004_020adb1c(int a);\r\nextern void func_ov004_020ae274(int a);\r\nextern void func_ov006_0210c180(void *o);\r\nextern void func_ov006_0210c1a8(void *o);\r\nextern void func_ov006_0210c218(void *o, s16 x, s16 y);\r\nextern void func_ov006_0210c278(void *o);\r\nextern void func_ov006_0210c2c0(void *o, int v);\r\nextern void func_ov006_0210c2d4(void *o);\r\nextern int func_ov006_0210c500(void *self);\r\nextern u8 data_020a0e40;\r\nextern u8 data_020a0de8[];\r\nextern u8 data_020a0de9[];\r\nextern int data_ov006_0213e600[];\r\nextern int data_ov006_0213e63c[][2];\r\nextern u8 data_ov006_0213e4d8[];\r\nextern s16 data_ov006_0213e654[][2];\r\nextern s16 data_ov006_0213e656[][2];\r\nextern s16 data_ov006_0213e4f8[][2];\r\nextern s16 data_ov006_0213e4fa[][2];\r\nextern struct FaderBrightness data_0209f61c;\r\n}\r\n\r\nnamespace Sound { void PlayBank2_2D(unsigned int); }\r\n\r\ns32 dScMgSlot1_c::Behavior()\r\n{\r\n char *c = (char *)this;\r\n int i;\r\n\r\n switch (unk_46b4) {\r\n case 0:\r\n for (i = 0; i < 3; i++) {\r\n unk_4702[i] = 1;\r\n }\r\n *(u8 *)(c + 0x4705) = 0;\r\n unk_470a = 0;\r\n unk_470b = 0;\r\n unk_46b4 = 1;\r\n func_ov006_0210c2d4(&mBetIcon);\r\n if (mPromptBlinkCount == 0) {\r\n mPromptEnabled = 1;\r\n mPromptBlinkCount = 1;\r\n mPromptBlinkTimer = 0;\r\n }\r\n *(u8 *)(c + 0x470c) = 0x3c;\r\n break;\r\n case 1:\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n Sound::PlayBank2_2D(0x160);\r\n *(u8 *)(c + 0x470c) = 0x1e;\r\n unk_46b4 = 2;\r\n }\r\n break;\r\n case 2:\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n unk_46b4 = 3;\r\n }\r\n break;\r\n case 3: {\r\n int moving = 0;\r\n for (i = 0; i < 3; i++) {\r\n if (unk_4702[i] == 1 || unk_46a4[i] != 0) {\r\n moving++;\r\n unk_46a4[i] -= data_ov006_0213e600[*(u8 *)(c + 0x4708) + i];\r\n if ((int)unk_46a4[i] < 0) {\r\n if (unk_4702[i] == 1) {\r\n unk_46ff[i]++;\r\n unk_46ff[i] %= 21;\r\n unk_46a4[i] += 0x40000;\r\n } else {\r\n unk_46a4[i] = 0;\r\n }\r\n }\r\n }\r\n }\r\n if (moving != 0) {\r\n *(int *)(c + 0x46b0) = Sound_PlayIfNotActive(*(int *)(c + 0x46b0), 2, 0x161, 0);\r\n }\r\n if (*(u8 *)(c + 0x4705) < 3) {\r\n int hit = 0;\r\n u8 idx = data_020a0e40;\r\n if (data_020a0de8[idx * 4] != 0) {\r\n if (data_020a0de9[idx * 4] != 0) {\r\n hit = 1;\r\n }\r\n }\r\n if (hit != 0) {\r\n u16 off = idx * 4;\r\n u8 *q = &data_020a0de8[off];\r\n int tx = q[2];\r\n int ty = q[3];\r\n for (i = 0; i < 3; i++) {\r\n if (unk_4702[i] == 1) {\r\n int dy = ty - data_ov006_0213e63c[i][1];\r\n int dx = tx - data_ov006_0213e63c[i][0];\r\n if (dx <= 0x20 && dx >= -0x20 && dy <= 0x20 && dy >= -0x20) {\r\n unk_4702[i] = 0;\r\n (*(u8 *)(c + 0x4705))++;\r\n if (mBetIcon.unk_011 != 0) {\r\n mBetIcon.unk_011 = 0;\r\n func_ov004_020ad79c(unk_0a8, mHudScore);\r\n }\r\n func_02012718(0x162, data_ov006_0213e63c[i][0] << 12);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n int stopped = 1;\r\n for (i = 0; i < 3; i++) {\r\n if (unk_46a4[i] != 0) {\r\n stopped = 0;\r\n }\r\n }\r\n if (stopped == 1) {\r\n unk_470a = func_ov006_0210c500(this);\r\n *(int *)(c + 0x46b8) = 0;\r\n if (unk_470a != 0) {\r\n *(int *)(c + 0x46b8) += data_ov006_0213e4d8[unk_4709];\r\n }\r\n if (unk_470b != 0 && unk_470b < 3) {\r\n *(int *)(c + 0x46b8) += unk_470b << 1;\r\n }\r\n func_ov004_020ad79c(unk_0a8 + *(int *)(c + 0x46b8) * mBetIcon.unk_01c, mHudScore);\r\n unk_46b4 = 4;\r\n *(u8 *)(c + 0x470c) = 0x3c;\r\n }\r\n }\r\n break;\r\n }\r\n case 4:\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n if (unk_470a != 0) {\r\n func_ov006_0210c218(c + 0x4684, data_ov006_0213e654[unk_4709][0], data_ov006_0213e656[unk_4709][0]);\r\n }\r\n if (unk_470b != 0 && unk_470b < 3) {\r\n func_ov006_0210c218(c + 0x4690, data_ov006_0213e4f8[unk_470b - 1][0], data_ov006_0213e4fa[unk_470b - 1][0]);\r\n }\r\n if (*(int *)(c + 0x46b8) != 0) {\r\n unk_46b4 = 5;\r\n *(u8 *)(c + 0x470c) = 0x64;\r\n func_ov006_0210c180(c + 0x469c);\r\n func_02012790(0x26);\r\n } else {\r\n unk_46b4 = 7;\r\n *(u8 *)(c + 0x470c) = 0x3c;\r\n func_02012790(0xe);\r\n }\r\n mPromptEnabled = 0;\r\n }\r\n break;\r\n case 5:\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n func_ov006_0210c2c0(&mBetIcon, *(int *)(c + 0x46b8));\r\n *(u8 *)(c + 0x470c) = 0x3c;\r\n unk_46b4 = 6;\r\n }\r\n break;\r\n case 6: {\r\n int done = (mBetIcon.unk_020 == 0) ? 1 : 0;\r\n if (done != 0) {\r\n func_ov004_020adb1c(unk_0a8);\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n OnYoshiTryEat(4);\r\n }\r\n }\r\n break;\r\n }\r\n case 7:\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n if (unk_0a8 > 0) {\r\n OnYoshiTryEat(5);\r\n } else {\r\n int j;\r\n char *p = c;\r\n for (j = 0; j < 3; j++) {\r\n unk_46a4[j] += 0x40000;\r\n unk_46ff[j]++;\r\n unk_46ff[j] %= 21;\r\n *(u8 *)(p + unk_46ff[j] + 0x46c0) = 0xd;\r\n p += 0x15;\r\n }\r\n unk_46b4 = 9;\r\n }\r\n }\r\n break;\r\n case 9:\r\n case 11: {\r\n int idx = (unk_46b4 - 9) >> 1;\r\n unk_46a4[idx] -= 0x2000;\r\n if ((int)unk_46a4[idx] < 0) {\r\n unk_46a4[idx] = 0;\r\n *(u8 *)(c + 0x470c) = 0xa;\r\n unk_46b4++;\r\n func_02012718(0x164, data_ov006_0213e63c[idx][0] << 12);\r\n if (idx == 0) {\r\n func_ov004_020ae274(2);\r\n }\r\n }\r\n break;\r\n }\r\n case 13:\r\n unk_46a4[2] -= 0x2000;\r\n if ((int)unk_46a4[2] < 0) {\r\n unk_46a4[2] = 0;\r\n *(u8 *)(c + 0x470c) = 0x3c;\r\n unk_46b4 = 8;\r\n func_02012718(0x164, data_ov006_0213e63c[2][0] << 12);\r\n }\r\n break;\r\n case 8:\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n dScene_c::SetFaders(&data_0209f61c);\r\n func_0202ec9c(&data_0209f61c, 2);\r\n dScene_c::StartSceneFade(5, 0, 0);\r\n }\r\n break;\r\n case 10:\r\n case 12:\r\n if (DecIfAbove0_Byte((u8 *)(c + 0x470c)) == 0) {\r\n unk_46b4++;\r\n }\r\n break;\r\n }\r\n mBetIcon.Behavior();\r\n func_ov006_0210c278(c + 0x4684);\r\n func_ov006_0210c278(c + 0x4690);\r\n func_ov006_0210c1a8(c + 0x469c);\r\n return 1;\r\n}\r\n", "source": "m100", "evaluator": "2004/b56|m2", "note": "equal-count text swap, run link100 crack wave 10 lane CRK2-H, 2026-09-13: same 19 divergences and the same 0x81c size as the draft it replaces, but a better-shaped residue (5 SCHED + 14 regperm against the old 9 + 11, tools/wallcrack.py). The lever is a u16-typed scaled index inside the hit block, which makes 2004/b56 emit the truncation as a separate shift instead of folding it into the add; notes 6cm.", "floor": {"class": "coloring (regperm, no nameable web left)", "evidence": "run link100 crack wave 10 lane CRK2-H, 2026-09-13, notes 6cm (which this wave rewrote in place). Residue 19 of 519 = 5 SCHED + 14 regperm, verified here with tools/wallcrack.py on the swapped draft. The scaled-index axis has four cells and 2004/b56 reaches three: before the guards 0x814, between the guards and the 'if (hit)' 0x81c, inside the block 0x818 (the shift folds into the addressing mode), and the ROM's cell (the shift materialised INSIDE the block and not folded) is unreached. A u16-typed index is the only size-neutral way to stop the fold and is what took the row 20 -> 19. The eleven regperm words in the loop are identical in all three drafts this function has ever had. 6cc has nothing to grip: a one-compile handle test (name each competing temp once, read the size) moves four of the five competing webs off the target size, and the exhaustive form (720 declaration orders x int/long on four types, 11,520 cells) is flat at the baseline, as are 6cd's dead-assignment lever in its own shape (26 targets x 2 slots x 3 insertion points), 420 pragma cells over 68 opt_ names on three shapes, six pragma pairs, the wider-index half (20,736 cells), and all 25 installed builds (every non-2004 build is structurally different here, 0x728 to 0x7e4).", "date": "2026-09-13"}} {"module": "ov075", "addr": "0x02116128", "name": "func_ov075_02116128", "size": 244, "target_hex": "f0402de904d04de2dc009fe50160a0e10070d0e50250a0e108fcfceb0040a0e10600a0e1016afceb041067e20123a0e18112a0e10a0080e20008a0e1842082e2a01081e2962121e0812084e02038a0e1000055e3040043120008a0112038a011b004d2e184409fe5033ea0e1040000e0230880e1b004c2e1b058d2e12308a0e10010a0e3045005e0235885e1b058c2e1be56d2e1045005e0235885e1be56c2e1be5ad2e1045005e0233885e1be3ac2e1b030d2e1011081e2180051e3043003e0003083e1b030c2e1b03cd2e1043003e0003083e1b03cc2e1022082e2f3ffffba04d08de2f040bde81eff2fe150fc0902ff0f0000", "lang": "c", "divergences": 20, "c_source": "unsigned short *_ZN2G212GetBG1ScrPtrEv();\nint func_02030958(int val);\nextern unsigned char data_0209fc50;\n\n/* Sets the 4-bit palette field (bits 12..15) of the border of a 24x4 BG map box:\n * the two left/right column entries on rows 1 and 2, then rows 0 and 3 across.\n * The box for slot `slot` starts at row 4 + 2n, column 4, with a row pitch of\n * 5 + n rows, where n = 4 - data_0209fc50 (the player count). */\n#pragma opt_lifetimes off\nvoid func_ov075_02116128(int unused, int slot, int dim)\n{\n unsigned int w;\n unsigned int hi;\n int t;\n int b;\n unsigned short *p;\n int a;\n unsigned short *bg;\n unsigned int angle;\n int m;\n int i;\n\n b = data_0209fc50;\n bg = _ZN2G212GetBG1ScrPtrEv();\n a = func_02030958(slot);\n t = 4 - b;\n m = slot * (t * 0x20 + 0xa0) + (t * 0x40 + 0x84);\n angle = (unsigned short)(a + 0xa);\n hi = angle;\n if (dim != 0)\n hi = (unsigned short)(hi - 4);\n p = bg + m;\n w = hi << 0x1c;\n hi = w >> 16;\n p[0x20] = (unsigned short)((p[0x20] & 0xfff) | hi);\n p[0x40] = (unsigned short)((p[0x40] & 0xfff) | hi);\n p[0x37] = (unsigned short)((p[0x37] & 0xfff) | hi);\n p[0x57] = (unsigned short)((p[0x57] & 0xfff) | hi);\n for (i = 0; i < 0x18; i++) {\n p[0] = (unsigned short)((p[0] & 0xfff) | hi);\n p[0x60] = (unsigned short)((p[0x60] & 0xfff) | hi);\n p++;\n }\n}\n", "source": "vsdec-c128", "evaluator": "2004/b56|m2", "cand_size": 244, "floor": {"class": "coalescing", "evidence": "[2026-09-13 link100 crack wave 9 lane CRK-P append] WAVE-9 LEVERS APPLIED TO 6bo FAMILY B, mwccarm 2004/b56, base origin/main 5b4acd75d, ~7000 new compiles plus a 90-minute 4335-iteration permuter run. NEW: the pragma is not load-bearing on family B (the in-place shift scores 31 with and without #pragma opt_lifetimes off), and one declaration move (i first) takes family B from 31 to 24 with ZERO SCHED words. NEW, the residue named by ROLE instead of by count: p +0x48 ROM r2 ours r2 (correct at 24), the palette value hi +0x4c ROM r3 ours r0, the loop invariant hi>>16 +0x7c ROM r0 ours r1, the counter i +0x80 ROM r1 ours r3 -- one 3-cycle r0->r3->r1->r0, and it all hangs on ONE coalescing decision: the ROM is born at +0x4c as lsr r3,r0,#0x10 into a FRESH register, every 244-byte source we can write is born in place as lsr r0,r0,#0x10, coalesced onto the r0 chain that starts at the callee return and add r0,r0,#0xa. 6cc INERT AND NOW BOUNDED BY ROLE: a 400-order declaration-rank census finds exactly TWO role signatures in the entire space (p r3/hi r0/inv r1/i r2 at 31, and p r2/hi r0/inv r1/i r3 at 24); hi is r0 in 100% of cells, so rank only picks which of r2/r3 holds p and the ROM's signature is not in the space at all. A joint rank x type-name hill climb (6 restarts) and a 4359-cell plateau random walk over rank x type x eight structural axes both stop at 24. PRAGMAS re-swept BY ROLE: the full verified 246-name vocabulary at on/off (492 compiles, 451 at 244 bytes) gives ONE role signature in every cell. 6cb lever 1 INERT: family B does have the anonymous CSE web family A lacks (the loop invariant hi>>16); naming it at all 11 ranks and at two positions is 24 everywhere. 6cb lever 2, 6cd, 6ce: NO SITE. THE ONE SPELLING THAT REACHES THE ROM's r3: spelling the dim branch truncation as a two-name shift chain, if (dim != 0) { w = (hi - 4) << 16; hi = w >> 16; }, breaks the coalesce and puts hi on r3 -- but mwccarm folds (x<<16)>>16 to x & 0xffff, which needs 0xffff in the literal pool and costs one pool word (248 bytes). 249 further entry x branch x invariant spellings: every 244-byte cell has hi on r0 and every hi-on-r3 cell is 248. Parameter-list shape (8 variants) inert; 9 entry-block rewrites all canonicalise to 24; all 24 single-store site orders and both loop-store orders are 24 or worse. PERMUTER (90 min, 4335 iterations, seeded with the div-24 schedule-exact family B): base 185, best 40, and the best IS the semantics trap the file's banner warns about -- output-40-1 sinks hi = hi << 0x1c below the four single stores so they compute angle >> 16 (zero for any 16-bit palette) and write a zero palette field. Rejected, not banked. The 6bo floor stands, now with the mechanism named as a coalescing decision rather than as 'the shifted value never reaches r3'.", "date": "2026-09-13"}} {"module": "ov006", "addr": "0x0211e72c", "name": "func_ov006_0211e72c", "size": 172, "target_hex": "f04f2de91cd04de20060a0e10050a0e390b09fe50570a0e10190a0e30040e0e3018aa0e3010986e27a16d0e5000051e31500000a76a6d0e5602690e57de6d0e57ec6d0e5641690e57b06d0e50730a0e39ce32ee000408de504008de508808de50c808de504c0a0e100005ae309c0a01110708de514c08de54136a0e10e119be74226a0e10900a0e17608fceb015085e2100055e3246086e2e1ffffba1cd08de2f04fbde81eff2fe164a91302", "lang": "cpp", "divergences": 22, "cand_size": 172, "c_source": "//cpp\n// NEAR-MISS DRAFT (22/43 words) -- func_ov006_0211e72c at 0x0211e72c (ov006, size 0xac).\nextern \"C\" {\nvoid _ZN3OAM6RenderEbP7OamAttriiii5Fix12IiES3_ii(\n int draw, void *attr, int x, int y, int palette, int priority,\n int sx, int sy, int a9, int a10);\nextern void *data_ov006_0213a964[];\n}\n\nextern \"C\" void func_ov006_0211e72c(char *base)\n{\n char *ptr = base;\n int cnt = 0;\n void **tbl = data_ov006_0213a964;\n for (; cnt < 0x10; cnt++) {\n char *o = ptr + 0x4000;\n if (*(unsigned char *)(o + 0x67a) != 0) {\n int flag = *(unsigned char *)(o + 0x676);\n int x = *(volatile int *)(o + 0x660);\n int lo = *(volatile unsigned char *)(o + 0x67d);\n int hi = *(volatile unsigned char *)(o + 0x67e);\n int y = *(volatile int *)(o + 0x664);\n int idx = hi * 7 + lo;\n int prio = *(unsigned char *)(o + 0x67b);\n int mode = -1;\n if (flag != 0) mode = 1;\n _ZN3OAM6RenderEbP7OamAttriiii5Fix12IiES3_ii(\n 1, tbl[idx], x >> 0xc, y >> 0xc, -1, prio,\n 0x1000, 0x1000, 0, mode);\n }\n ptr += 0x24;\n }\n}\n", "source": "laneC-ov006 e72c-0913", "evaluator": "2004/b56|m2", "note": "[2026-09-13 lane laneC-ov006, branch match/e72c-0913] 27 -> 22 (-5). The previously stored draft re-scores to exactly 27 under this evaluator, and a separate lane independently reconfirmed a 26 floor, so 22 is a real improvement on both. NOT MATCHED.\n\nTWO PAYING LEVERS, both transferable.\n(1) A four-of-six `volatile` mask on the field loads -- x (0x660), lo (0x67d), hi (0x67e), y (0x664) volatile; the 0x67a gate, the 0x676 flag and the 0x67b priority plain. `volatile` here is a SCHEDULING BARRIER: it pins the relative order of the loads without changing a single emitted instruction, and it reproduces the ROM's load order flag,x,lo,hi,y,prio (+0x38/+0x3c/+0x40 go OK). A 128-subset sweep of the mask: this one = 22, adding the flag = 27, all six = 33, none = 26.\n(2) Mode polarity. `int mode = 1; if (flag == 0) mode = -1;` ranks the constant 1 ahead of the constant -1; the opposite spelling ranks -1 first. This is the only lever found that moves -1 in the rank list at all, and it moves it exactly one place.\n\nTHE RECOMMENDED HANDOFF CANDIDATE IS NOT THE BANKED SOURCE. It scores 26 but has the frame right, and it is one rank-list element from the ROM. Reconstruct it from the banked source with exactly three edits: (a) qualify the 0x676 flag load `volatile` too; (b) spell the mode select `int mode = 1; if (flag == 0) mode = -1;`; (c) delete the `tbl` local and subscript data_ov006_0213a964[idx] inline at the call. Verified: that reconstruction scores 26/43.\nIts evidence: push {r4,r5,r6,r7,r8,sb,sl,fp,lr} OK, sub sp,sp,#0x1c OK, ldr fp,[pc,#0x90] OK (exact word, exact literal-pool offset), add sp,sp,#0x1c OK, pop {...,fp,lr} OK, bx lr OK. Every remaining prologue word differs only in WHICH callee-saved register holds which value.\n\nTHE OPEN QUESTION, stated so the next lane does not re-derive it. Callee-saved rank lists (pool r4,r5,r6,r7,r8,sb,sl with rank 0 taking the highest, and fp taking the last rank when there are eight webs):\n ROM flag(sl) one(sb) thou(r8) zero(r7) ptr(r6) cnt(r5) neg(r4) tbl(fp)\n handoff candidate flag(sl) one(sb) neg(r8) thou(r7) zero(r6) ptr(r5) cnt(r4) tbl(fp)\nOne element displaced: the -1 sits at rank 2 and belongs at rank 6. Concretely: PRODUCE A -1 WHOSE FIRST USE IS AT ARGUMENT 10 WHILE ARGUMENT 5 STILL EMITS -1. The -1 is both the palette (stack argument 5, evaluated first of the stack arguments) and the default of the mode select (argument 10), and it is argument 5 that anchors its web early.\n\nWHY RANK IS NOT DECLARATION ORDER HERE (scope limit on the banked rule, measured). On this function callee-saved rank is set by order of first USE inside the loop body, not by declaration order, because mwcc constant-propagates every function-scope constant local and erases the declaration before allocation. The rule IS still live for the locals that survive to allocation: reversing the declaration order moved cnt and tbl between r4 and r5 (22 -> 25) while leaving all four propagated constants exactly where they were. So: scoped to non-propagated locals, dead for constants.\n\nEXHAUSTED -- do not re-buy. The entire callee signature: 14 variants (return void/int; parameters 1/7/8/9 as int vs void* with matching (void*)0x1000 casts, copied from the matched sibling src/func_ov006_020fa7b8.cpp; argument 1 as 0 vs 1) all score IDENTICALLY on both bases. Arity is independently settled by the callee's own source file, which declares 10 parameters (4 register + 6 stack) -- and a module-constrained ROM-wide call-site census over OAM::Render's 131 sites (71 of them arm9-resident) has r0-r3 set at 131/131. Also inert: all 210 inner declaration permutations; six function-scope declaration orders including the exact ROM rank order; hoisting any inner local to function scope; twelve spellings of the -1 (~0, 0-1, (int)0xffffffff, -1L, unsigned, (void*)-1, narrowing casts, a separate pal variable copied into mode, pal as the if-arm value); eleven mode-select spellings; 20 pragmas. Harmful: duplicated call in if/else arms (size error), mode from a static const int[2] (size error), 2-D array spellings (32-33), opt_propagation off (size error), pointer-typed palette in any 8-web regime (28-33). A 700-sample randomized structural search over volatile masks x mode spellings x palette typings x declaration orders peaked at 24 -- it never reached the hand-derived 22.\n\nGENERATOR HAZARD worth having: the Windows filesystem is case-insensitive, so sweep tags that differ only in case collapse onto one file (_F_ and _f_ overwrote each other's saved .cpp). Measurements were safe because each cell writes then measures immediately, but the SAVED artifact was the wrong one -- a 26 candidate re-read as 31. Give generated candidate files case-insensitively distinct tags."} diff --git a/notes/data/class-facts/dScMgCurling2_c.json b/notes/data/class-facts/dScMgCurling2_c.json index 0c4f156dad..996f9c04ba 100644 --- a/notes/data/class-facts/dScMgCurling2_c.json +++ b/notes/data/class-facts/dScMgCurling2_c.json @@ -817,7 +817,7 @@ } ], "unproven": [ - "Whether func_ov006_020e5450 can be matched. The best recorded attempt sits at 29 divergences with a byte-clean prologue, but no matched source exists and the banked draft is at 324.", + "Whether func_ov006_020e5450 can be matched. The honest measurement is 191 divergent words of 344 at the exact size 0x560, which is what nearmiss/db.jsonl banks, with a byte-clean prologue; no matched source exists. An older config/match_attempts.jsonl row read 29, but it was scored over a 0x52c candidate against the 0x560 target and was a truncated verdict, not a divergence count; that field has been cleared.", "Whether any of the five pragma directives is load-bearing. That is a delete-outright control the writer runs; nothing here measures it.", "The original identifiers and member-versus-file-local form of the 21 direct-call-only helpers. Direct calls preserve targets and arguments, not source-level linkage.", "The original names of the 25 nonvirtual member callbacks reached through the pointer-to-member records, and the gameplay semantics of the seven BSS destination arrays.", @@ -1041,7 +1041,7 @@ "note": "The BANKED draft is much worse (324) than the best ATTEMPT (29). The 29-divergence grok-4.6 attempt is recorded in config/match_attempts.jsonl only -- its source is not in the bank, so a writer wanting it must regenerate from the attempt note." }, "attempt_note": "common_subs off; for-loop with found body inside; slot=self+m forms px/pz; loop guards via p+0x4689 split. Prologue and loop tests byte-ok except branch offsets. Residual: z/x pair load order, frame 0x64 vs 0x7c, size 0x52c vs 0x560, found-body s64/pointer schedule.", - "writer_guidance": "29 divergences with the prologue and loop tests already byte-clean is a live match candidate, not a wall. But it is the ONLY thing splitting this run in two: matching it merges segments A and B into one 53-function TU. Cutting around it means shipping a 31- or 21-function partial." + "writer_guidance": "191 of 344 words at the exact size 0x560, with the prologue and loop tests already byte-clean, is a live match candidate, not a wall. Start from notes/mwccarm-codegen.md section 6cz, which carries this line further; do not re-derive it. Do not plan against the old 29: it was a truncated verdict over a 0x52c candidate and has been cleared. But it is the ONLY thing splitting this run in two: matching it merges segments A and B into one 53-function TU. Cutting around it means shipping a 31- or 21-function partial." }, "other_run_entries": [ { diff --git a/notes/mwccarm-codegen.md b/notes/mwccarm-codegen.md index 2e3b00de5f..a64663e6ee 100644 --- a/notes/mwccarm-codegen.md +++ b/notes/mwccarm-codegen.md @@ -5172,11 +5172,35 @@ the same region. On a two-line probe over a `struct S *p`, canonical flags, whol The second store is the whole difference: `add #0x5000` once, then `[r2,#0x3c0]`, which is the ROM's shape at that site. The bound, and it is why this reads as inert if you probe it in the -wrong place: **the cast only matters when the base is not already byte-strided.** In the -banked `func_ov006_020d27dc` candidate the base is a `char *`, and there both spellings -compile to the same 3652 bytes, md5 `8462f11dba034fd64356bc06233a65cf`, at both surviving -sites. `(int)p + k` and `p + k` on a `char *` are the same expression after canonicalisation, -the same way index arithmetic is canonicalised in 6bv item 2. +wrong place: **a byte-strided base does not make the cast inert, it makes it inert at most +sites, which is not the same thing.** Re-measured 2026-09-13 against the banked +`func_ov006_020d27dc` candidate, whose base is a `char *` and which spells `(int)p` on five +source lines -- 40, 87, 197, 220 and 241, of which 87 is a genuine int-typed local that cannot +drop the cast: + +``` +cast kept at 40/197/220/241 3656 md5 163fe692d7ce77134ede8bc0db9f5f08 +cast dropped at 40, at 197, at 220, or at all three 3656 md5 163fe692d7ce77134ede8bc0db9f5f08 +cast dropped at 241, alone or with the other three 3652 md5 8462f11dba034fd64356bc06233a65cf +``` + +Three of the four removable sites are byte-inert: on either spelling they canonicalise to the +ROM's `add rN,sb,#0x5000` with an immediate offset, and both objects carry seventeen of those. +The fourth is worth four bytes. The cast object emits exactly one `ldr rN,[sb,rM]` in the whole +914-instruction function, at +0x55c, and that register-offset load plus the literal-pool word it +needs is the entire size difference: + +``` +ROM add r0,sb,#0x5000 / ldr r1,[r0,#0x374] / cmp r1,#5 / blt +(int)p ldr r0,[pc,#0x8c4] / ldr r0,[sb,r0] / cmp r0,#5 / addlt +p add r0,sb,#0x5000 / ldr r1,[r0,#0x374] / cmp r1,#5 / addlt +``` + +The md5 `8462f11dba034fd64356bc06233a65cf` recorded here previously as what *both* spellings +produce is the cast-dropped object alone; the banked source produces `163fe692...` at 3656. +Line 241 is the site whose loaded value feeds the compare of the if-converted block, which is +why a site-local probe of this lever can return either answer. Probe it at the site that feeds +the divergence, not at a convenient one. That lever carried `func_ov006_020d27dc` from 17 divergences to a single instruction, and the one that remains is the notes 6d / 6bv item 8 if-conversion floor: mwccarm predicates a @@ -5184,6 +5208,12 @@ six-instruction else arm and duplicates the epilogue where the ROM emits `blt` a unpredicated block. It is now evidenced over 119 pragma settings, 5 optimisation levels, 20 source spellings and all 20 installed builds. The endpoint source is size-wrong by four bytes, so it does not belong in `src/`, and by item 1 it does not belong in the DB either. +The corollary is the uncomfortable half: the banked row is size-exact at 3656 only because of +that one spurious pool word, so its 17 is a score on a source that is wrong at line 241, and +`evaluate_full` sentinels the corrected 3652-byte object at 999 on the size mismatch. The +correction therefore cannot be ingested as an improvement -- the upsert is strictly improving +and 999 is worse than 17 -- so the row keeps its stored source and carries a floor mark +instead. The residue that actually remains is one word, not a size-exact 17. **4. The reversed-sense ternary, and a launder that is not needed.** diff --git a/src/_ZN20cMgSmartball_board_c12SaveSnapshotEv.cpp b/src/_ZN20cMgSmartball_board_c12SaveSnapshotEv.cpp index 45dd239fc4..3a353591a3 100644 --- a/src/_ZN20cMgSmartball_board_c12SaveSnapshotEv.cpp +++ b/src/_ZN20cMgSmartball_board_c12SaveSnapshotEv.cpp @@ -23,7 +23,7 @@ extern "C" void func_ov006_0211470c(int *a, int *b); extern "C" int func_ov006_02111dcc(char *p, int val); extern "C" void func_ov006_02114800(void *c, int *p, int f); extern "C" void func_ov006_0210ef48(void *c, int i); -extern "C" void func_02012718(void *a, int b); +extern "C" void func_02012718(int a, int b); namespace Sound { void PlayBank2_2D(u32 id); } static inline u8 *GetObj(char *g, int i) @@ -113,11 +113,11 @@ void cMgSmartball_board_c::SaveSnapshot() func_ov006_02114800((char *)mpManager, (int *)&a, 0); SetV2(&b, (j * 0x18 + 0x10) << 12, 0x78000); func_ov006_02114800((char *)mpManager, (int *)&b, 0); - func_02012718((void *)0x1be, j * 0x18000 + 0x10000); + func_02012718(0x1be, j * 0x18000 + 0x10000); } else { SetV2(&d, (j * 0x18 + 0x10) << 12, 0x78000); func_ov006_02114800((char *)mpManager, (int *)&d, 1); - func_02012718((void *)0x17a, j * 0x18000 + 0x10000); + func_02012718(0x17a, j * 0x18000 + 0x10000); } func_ov006_0210ef48(this, j); break; diff --git a/src/_ZN21cMgSmartball_kinoko_c12SaveSnapshotEv.cpp b/src/_ZN21cMgSmartball_kinoko_c12SaveSnapshotEv.cpp index a0183951a0..0b7143fe79 100644 --- a/src/_ZN21cMgSmartball_kinoko_c12SaveSnapshotEv.cpp +++ b/src/_ZN21cMgSmartball_kinoko_c12SaveSnapshotEv.cpp @@ -14,7 +14,7 @@ typedef struct { int x, y; } V2; extern "C" void func_ov006_02115598(void *c, int *src, int v2, int v3, int v5); extern "C" void func_ov006_02115008(void *p); -extern "C" void func_02012718(void *a, int b); +extern "C" void func_02012718(int a, int b); extern "C" void func_ov006_0211470c(int *a, int *b); extern "C" void Vec2_Sub(int *o, int *a, int *b); extern "C" int Vec2_Len(const void *v); @@ -37,7 +37,7 @@ void cMgSmartball_kinoko_c::SaveSnapshot() pair.y = mCurrent1; func_ov006_02115598((void *)mpManager, (int *)&pair, 0x12c, 0, 1); func_ov006_02115008((void *)mpManager); - func_02012718((void *)0x19f, mCurrent0); + func_02012718(0x19f, mCurrent0); } mWasHit = 0; if (mVariant == 1) diff --git a/src/_ZN21cMgSmartball_pakkun_c12SaveSnapshotEv.cpp b/src/_ZN21cMgSmartball_pakkun_c12SaveSnapshotEv.cpp index 816250ee26..65b6571cfb 100644 --- a/src/_ZN21cMgSmartball_pakkun_c12SaveSnapshotEv.cpp +++ b/src/_ZN21cMgSmartball_pakkun_c12SaveSnapshotEv.cpp @@ -16,7 +16,7 @@ extern "C" void func_ov006_0211470c(int *a, int *b); extern "C" void Vec2_Sub(int *o, int *a, int *b); extern "C" Fix12i Vec2_Len(const void *v); extern "C" void func_ov006_0210d8bc(char *c); -extern "C" void func_02012718(void *a, int b); +extern "C" void func_02012718(int a, int b); inline int *GetObj(char *g, int i) { @@ -47,7 +47,7 @@ void cMgSmartball_pakkun_c::SaveSnapshot() unk_031 = 0; func_ov006_0210d8bc(*(char **)((char *)mpManager + 0x4780)); *((char *)GetObj((char *)mpManager, i) + 0x30) = 0; - func_02012718((void *)0x1a0, mCurrent0); + func_02012718(0x1a0, mCurrent0); return; } } diff --git a/src/actors/dScMgCurling2_c.cpp b/src/actors/dScMgCurling2_c.cpp index 5b82ca2126..d2d16e4671 100644 --- a/src/actors/dScMgCurling2_c.cpp +++ b/src/actors/dScMgCurling2_c.cpp @@ -10,8 +10,13 @@ * tree -- it carries a symbols.txt row but NO src/ file and NO entry in * config/arm9/overlays/ov006/delinks.txt at all (the blocks jump from * 0x020e513c-0x020e5450 straight to 0x020e59b0), so the cartridge's own bytes - * cover that range. It is a banked near-miss whose best recorded attempt sits - * at 29 divergences (config/match_attempts.jsonl). It sits in the MIDDLE of + * cover that range. It is a banked near-miss, and the honest measurement is + * 191 divergent words out of 344 at the exact ROM size 0x560 (nearmiss/db.jsonl); + * notes/mwccarm-codegen.md section 6cz carries that line further. + * An older row in config/match_attempts.jsonl reads 29, but that attempt's own + * note records "size 0x52c vs 0x560": it was scored against a candidate 52 bytes + * short of the target, so the 29 is a truncated verdict over a shorter window and + * is not a divergence count for this function at all. It sits in the MIDDLE of * the run, and nothing in this tree can express a .text claim with a hole in * it, so the run has to be licensed as one of its two contiguous sides. * diff --git a/src/func_02012718.c b/src/func_02012718.c index 80159b3a0f..eb89267aff 100644 --- a/src/func_02012718.c +++ b/src/func_02012718.c @@ -1,5 +1,5 @@ extern int func_020126e8(int); -extern void func_020127ec(int, void*, int, int, int, int); -void func_02012718(void *a, int b){ +extern void func_020127ec(int, int, int, int, int, int); +void func_02012718(int a, int b){ func_020127ec(2, a, 4, 0, 0, func_020126e8(b)); } diff --git a/src/func_ov006_020cb2b4.c b/src/func_ov006_020cb2b4.c index 695a23286d..93fb9c89ba 100644 --- a/src/func_ov006_020cb2b4.c +++ b/src/func_ov006_020cb2b4.c @@ -17,7 +17,7 @@ extern int _ZN9Animation8FinishedEv(void *); extern void _ZN9ModelAnim7SetAnimEP8BCA_Filei5Fix12IiEj(void *, void *, int, int, unsigned int); extern void _Z14ApproachLinearRiii(int *, int, int); extern void _Z15ApproachLinear2Rsss(short *, short, short); -extern void func_02012718(void *, int); +extern void func_02012718(int, int); extern void func_ov006_020bfff8(char *, void *, int *, int *); extern int func_ov004_020b04c0(void); extern void func_ov006_02120d0c(int, int); @@ -59,7 +59,7 @@ void func_ov006_020cb2b4(void *self) if (u <= 0x90000 && u >= -0x90000) return; - func_02012718((void *)0x1be, 0x100000); + func_02012718(0x1be, 0x100000); _Z14ApproachLinearRiii(&data_ov006_02140588, 0x270f, 1); data_ov006_0214058c -= 1; data_ov006_0214055c -= 1; diff --git a/src/func_ov006_020d7f5c.c b/src/func_ov006_020d7f5c.c index 8ffdad7667..02c4ebc78d 100644 --- a/src/func_ov006_020d7f5c.c +++ b/src/func_ov006_020d7f5c.c @@ -2,7 +2,7 @@ void func_ov006_020d6b88(char *this, int idx); void func_ov006_020d6c90(char *this, int idx); void func_ov006_020d6e8c(char *this, int idx); -void func_02012718(void *a, int b); +void func_02012718(int a, int b); int func_020126e8(int a); int func_02012468(int a, int b, int c, int d, int e, int f, int g, short h); @@ -57,7 +57,7 @@ void func_ov006_020d7f5c(char *this, int idx) } if (was == 0 && *(u8 *)(B + 0x69e) != 0) { - func_02012718((void *)0x1e4, *(int *)(B + 0x660)); + func_02012718(0x1e4, *(int *)(B + 0x660)); } *(int *)(B + 0x688) = func_02012468(*(int *)(B + 0x688), 2, 0x1e5, 4, 0, 0, diff --git a/src/func_ov006_020e1b54.c b/src/func_ov006_020e1b54.c index 536dd41af1..e076b1335f 100644 --- a/src/func_ov006_020e1b54.c +++ b/src/func_ov006_020e1b54.c @@ -1,5 +1,5 @@ #include "types.h" -extern void func_02012718(void *a, int b); +extern void func_02012718(int a, int b); extern u8 data_020a0e40; extern u8 data_020a0de8[]; extern u8 data_020a0de9[]; @@ -31,7 +31,7 @@ void func_ov006_020e1b54(char *c) *((u16 *) (c + 0x4ede)) = 0xc000; if ((*((u8 *) (c + 0x4ee9))) == 0) { - func_02012718((void *) 0x1d2, *((int *) (c + 0x4eb0))); + func_02012718(0x1d2, *((int *) (c + 0x4eb0))); *((u8 *) (c + 0x4ee9)) = 6; } *((int *) (c + 0x4ecc)) = 0; diff --git a/src/func_ov006_020e5b70.c b/src/func_ov006_020e5b70.c index 48a2779abc..bd7125ebac 100644 --- a/src/func_ov006_020e5b70.c +++ b/src/func_ov006_020e5b70.c @@ -1,8 +1,19 @@ /* func_ov006_020e5b70 @ 0x20e5b70 (ov006) -- tail-call veneer to func_ov006_020e5450 (0x20e5450). * ldr ip, [pc]; bx ip; .word 0x20e5450 + * + * The veneer forwards r0/r1 untouched, so its own parameter list is the target's. + * func_ov006_020e5450's prologue is `mov sb,r1; mov sl,r0`, which proves two + * parameters; src/func_ov006_020e5b7c.c spells the same arity. The old + * no-parameter spelling here was wrong and merely happened to emit the same bytes. + * + * The first parameter is a `this`, and src/func_ov006_020e5450.cpp names its type + * `dScMgCurling2_c *` -- a C++ class this C shard cannot spell. `void *` is the + * honest spelling for it here: it carries the arity, which is the byte-relevant + * part, and declines to contradict the definition's pointee type rather than + * asserting a `char *` the definition does not say. */ -extern void func_ov006_020e5450(void); +extern void func_ov006_020e5450(void *c, int a); -void func_ov006_020e5b70(void) { - func_ov006_020e5450(); +void func_ov006_020e5b70(void *c, int a) { + func_ov006_020e5450(c, a); } diff --git a/src/func_ov006_020fca1c.c b/src/func_ov006_020fca1c.c index 5e79cca1bb..7a6d101b10 100644 --- a/src/func_ov006_020fca1c.c +++ b/src/func_ov006_020fca1c.c @@ -3,7 +3,7 @@ extern void func_ov006_020fb8fc(char *c, int a2, int a3, int a4, int a5, int a6); extern void func_ov006_020fc1b4(char *base, int val); -extern void func_02012718(void *a, int b); +extern void func_02012718(int a, int b); void func_ov006_020fca1c(char *c, int idx) { @@ -36,7 +36,7 @@ void func_ov006_020fca1c(char *c, int idx) *(int *)(c + i * 0xc + 0x5bd0), 2, 0, i + 1); func_ov006_020fc1b4(c, 0); - func_02012718((void *)0x18c, *(int *)(c + n + 0x4000 + 0x660)); + func_02012718(0x18c, *(int *)(c + n + 0x4000 + 0x660)); return; } } diff --git a/src/func_ov006_020fcd8c.c b/src/func_ov006_020fcd8c.c index 1580c110e8..12bbac1b72 100644 --- a/src/func_ov006_020fcd8c.c +++ b/src/func_ov006_020fcd8c.c @@ -1,4 +1,4 @@ -void func_02012718(void *a, int b); +void func_02012718(int a, int b); void func_ov006_020fcd8c(char *this, int idx) { unsigned char *flag = (unsigned char*)(this + 0x4695) + idx * 0x38; @@ -7,5 +7,5 @@ void func_ov006_020fcd8c(char *this, int idx) { e = this + idx * 0x38; if ((*(int*)(e + 0x4664) >> 0xc) < -0xf2) return; *flag = *flag + 1; - func_02012718((void*)0x184, *(int*)(e + 0x4660)); + func_02012718(0x184, *(int*)(e + 0x4660)); } diff --git a/src/func_ov006_020fce04.c b/src/func_ov006_020fce04.c index b30c4aebec..7f4dd1e30a 100644 --- a/src/func_ov006_020fce04.c +++ b/src/func_ov006_020fce04.c @@ -1,5 +1,5 @@ extern void func_ov006_020fb8fc(char *c, int a2, int a3, int a4, int a5, int a6); -extern void func_02012718(void *a, int b); +extern void func_02012718(int a, int b); extern unsigned short data_ov006_0213d954[]; void func_ov006_020fce04(char *c, int i) @@ -16,7 +16,7 @@ void func_ov006_020fce04(char *c, int i) 2, data_ov006_0213d954[0], 0); - func_02012718((void *)0x18b, *(int *)(c + 0x4660 + k)); + func_02012718(0x18b, *(int *)(c + 0x4660 + k)); return; } *(unsigned char *)((c + k) + 0x4000 + 0x68c) = 0; diff --git a/src/func_ov006_02102d6c.c b/src/func_ov006_02102d6c.c index 60711abe07..56a5a3f8cc 100644 --- a/src/func_ov006_02102d6c.c +++ b/src/func_ov006_02102d6c.c @@ -24,7 +24,7 @@ struct Obj { struct Entry entries[1]; /* 0x4660 */ }; -extern void func_02012718(int soundId, u32 handle); +extern void func_02012718(int soundId, int handle); void func_ov006_02102d6c(struct Obj *self, int i) { diff --git a/src/func_ov006_021115cc.c b/src/func_ov006_021115cc.c index 24e3db38dc..3d6b3bbea9 100644 --- a/src/func_ov006_021115cc.c +++ b/src/func_ov006_021115cc.c @@ -1,7 +1,7 @@ extern void func_ov006_02114800(int a, void* p, int c); extern void func_ov006_02115598(int a, void* p, int c, int d, int e); extern void func_ov006_02114fec(int a); -extern void func_02012718(void *a, int b); +extern void func_02012718(int a, int b); void func_ov006_021115cc(char* c); void func_ov006_021115cc(char* c){ int tmp1[2]; @@ -15,5 +15,5 @@ void func_ov006_021115cc(char* c){ tmp2[1] = *(int*)(c + 0xc); func_ov006_02115598(*(int*)(c + 4), tmp2, 0x7d0, 0, 1); func_ov006_02114fec(*(int*)(c + 4)); - func_02012718((void*)0xe0, *(int*)(c + 8)); + func_02012718(0xe0, *(int*)(c + 8)); } diff --git a/src/func_ov006_02112ad8.c b/src/func_ov006_02112ad8.c index 12aef4a53a..25800f13c6 100644 --- a/src/func_ov006_02112ad8.c +++ b/src/func_ov006_02112ad8.c @@ -87,7 +87,7 @@ extern int Vec2_Len(V2 *p); extern void func_0203d480(V2 *out, V2 *in); extern int RandomIntInternal(int *seed); extern void func_ov006_021146f4(V2 *out, void *obj); -extern void func_02012718(void *id, int x); +extern void func_02012718(int id, int x); extern int func_020126e8(int x); extern void func_020126ac(int id, int type, int volume, int arg3, int arg4); extern void func_ov006_02111b90(Obj *self, int id, V2 *vel); @@ -567,8 +567,8 @@ void func_ov006_02112ad8(Obj *self) if (self->soundTimer == 0) { if (self->velZ < -0x6000) { - func_02012718((void *)0x16d, self->pos[0]); - func_02012718((void *)0x16e, self->pos[0]); + func_02012718(0x16d, self->pos[0]); + func_02012718(0x16e, self->pos[0]); } else { volume = (-self->velZ << 7) / 0x6000; if (volume > 0x7f) @@ -586,7 +586,7 @@ void func_ov006_02112ad8(Obj *self) if (self->soundPlayed != 0) return; if (self->velZ < -0x6000) - func_02012718((void *)0x16e, self->pos[0]); + func_02012718(0x16e, self->pos[0]); self->soundPlayed = 1; return; } diff --git a/src/func_ov006_02114ec0.c b/src/func_ov006_02114ec0.c index 597eb5ee8c..eef84fbef8 100644 --- a/src/func_ov006_02114ec0.c +++ b/src/func_ov006_02114ec0.c @@ -4,7 +4,7 @@ */ extern void func_ov006_02111e7c(int *o); extern void func_ov006_0211470c(int *a, int *b); -extern void func_02012718(void *a, int b); +extern void func_02012718(int a, int b); typedef struct { int *p[13]; } Arr; static inline int *get(char *self, int i){ return i >= 13 ? 0 : ((Arr*)(self + 0x4688))->p[i]; } void func_ov006_02114ec0(char *self){ @@ -14,6 +14,6 @@ void func_ov006_02114ec0(char *self){ if (*(unsigned char *)((char *)get(self, i) + 0x121) != 0) continue; func_ov006_02111e7c(get(self, i)); func_ov006_0211470c(t, get(self, i)); - func_02012718((void *)0x1a5, t[0]); return; + func_02012718(0x1a5, t[0]); return; } } diff --git a/src/func_ov006_0211e8a8.c b/src/func_ov006_0211e8a8.c index ad819ce299..0d974727c8 100644 --- a/src/func_ov006_0211e8a8.c +++ b/src/func_ov006_0211e8a8.c @@ -3,7 +3,7 @@ extern int data_ov006_0212efec[]; extern int* _ZN3G2S13GetBG0CharPtrEv(void); extern void func_ov006_0211e55c(char* c, int idx); -extern void func_02012718(void* a, int b); +extern void func_02012718(int a, int b); #define A(a) (*(u8*)(a)) @@ -48,7 +48,7 @@ void func_ov006_0211e8a8(char* c, int idx) *(s16*)&((char (*)[0x24])c)[idx][0x466e] = 0x40; A(c + 0x4c21)++; func_ov006_0211e55c(c, idx); - func_02012718((void*)0x1f0, *(int*)(c + off + 0x4660)); + func_02012718(0x1f0, *(int*)(c + off + 0x4660)); if (*(u8*)(c + 0x4c26) == 0xff) *(u8*)(c + 0x4c26) = (u8)idx; }