"""DIMENSION 1 / query 8: THE WRITERS of screen+0x290.

Instruction scan found exactly two writes to +0x290 inside the store-screen
cluster:
    0x18007d3ba  FUN_18007d1a0  MOV dword ptr [R14 + 0x290],EBP
    0x18007f0c0  FUN_18007e7f0  MOV dword ptr [R15 + 0x290],EAX
Everything else at that displacement in CardsDLL is a vtable CALL/JMP or an
unrelated object.

QUESTION: what value do those two store? If it is a number that came out of the
Flash message (the tile's ASSET_ID) rather than the group ordinal, then
displayGroupAssetId is being used as a group ordinal and non-contiguous ids
break the drill-down.

CONTROL: FUN_18007dab0 (the reader, already decompiled) is in the same cluster
and uses the same object; the two writers must be seen to operate on an object
that also touches +0x294 / +0x2c8, otherwise they are a different class that
merely shares the offset.
"""
import traceback

OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/store/q8_out.txt"
buf = []
def P(*a):
    s = " ".join(str(x) for x in a)
    buf.append(s)
    print(s)

def C(a, label, show_callers=True):
    P("=" * 78)
    P(label, hex(a))
    P("=" * 78)
    s = dec(a)
    P("len(src) =", len(s))
    P(s)
    if show_callers:
        P("--- callers ---")
        for ent, nm in callers(a):
            P("   %-30s %s" % (nm, hex(ent)))

try:
    C(0x18007d1a0, "*** WRITER 1  FUN_18007d1a0 ***")
    C(0x18007e7f0, "*** WRITER 2  FUN_18007e7f0 ***")
    C(0x1800144a0, "FUN_1800144a0  CATEGORY_LOCACTION by server id")
    C(0x180014ee0, "FUN_180014ee0  IS_AVAILABLE by server id")
except Exception:
    P(traceback.format_exc())

open(OUT, "w").write("\n".join(buf))
print("WROTE", OUT)
