{"kind":"hwanse-map-animation-draw-tile-transform-review","status":"draw-time-tile-transform-negative-for-visible-animation","source":["Hwanse2.exe","tools/build_map_animation_draw_tile_transform_review.py","out/map_animation_redraw_consumer_review.json"],"summary":{"rowRendererGrounded":true,"drawWrapperGrounded":true,"tileIdToSourceRectConverterGrounded":true,"tileGridFormula":"sourceX=(tileId % columns) * tileWidth; sourceY=(tileId / columns) * tileHeight","usesLayer1AnimatedFlag0x40":false,"usesFrameCounter":false,"usesPerMapAnimationSequence":false,"drawTimeVisibleMotionTransformFound":false,"decision":"The inspected draw path maps the current live layer0 tile id to a source rect by fixed grid math. It does not provide the missing fire/waterfall frame loop."},"landmarks":[{"name":"dirty row renderer","va":4346211,"endVa":4346489,"role":"Reads live layer0 tile id and calls the generic draw wrapper.","vaHex":"0x00425163","endVaHex":"0x00425279","byteSnippet":"55 8b ec 83 ec 08 53 56 57 c7 45 f8 00 00 00 00 e9 03 00 00 00 ff 45 f8 83 7d f8 25 0f 83 f0 00 00 00 8b 45 08 25 ff ff 00 00 8b c8 8d 04 c0 8d 04 81 8b 4d f8 33 d2 8a 94 08 d0 57 59 00 33 c0 66 a1 88 b5 55 00 85 d0"},{"name":"generic draw wrapper","va":4290003,"endVa":4290144,"role":"Copies draw arguments into a temporary object and dispatches draw.","vaHex":"0x004175d3","endVaHex":"0x00417660","byteSnippet":"55 8b ec 83 ec 08 53 56 57 8b 45 08 a3 38 aa 55 00 8b 45 18 a3 3c aa 55 00 8b 45 10 a3 2c aa 55 00 8b 45 14 a3 30 aa 55 00 83 7d 1c 00 0f 84 20 00 00 00 8b 45 1c 8b 00 a3 40 aa 55 00 8b 45 1c 8b 40 04 a3 44 aa 55 00"},{"name":"draw object dispatcher","va":4289659,"endVa":4289974,"role":"Extracts surface slot from the packed tile descriptor and calls the surface draw method.","vaHex":"0x0041747b","endVaHex":"0x004175b6","byteSnippet":"55 8b ec 83 ec 20 53 56 57 c7 05 cc 76 46 00 00 00 00 00 8b 45 08 8b 40 1c 99 81 e2 ff ff 00 00 03 c2 c1 f8 10 89 45 e4 8b 45 08 8b 40 20 99 81 e2 ff ff 00 00 03 c2 c1 f8 10 89 45 e8 8b 45 08 8b 40 28 c1 e8 10 0f b7"},{"name":"tile id to source rect converter","va":4299168,"endVa":4299648,"role":"Converts a tile id to x/y/w/h source rect by columns and tile dimensions.","vaHex":"0x004199a0","endVaHex":"0x00419b80","byteSnippet":"55 8b ec 83 ec 1c 53 56 57 81 65 0c ff ff 00 00 8b 45 08 0f bf 48 32 8b 45 0c 99 f7 f9 8b c2 8b 4d 08 0f bf 49 2e 0f af c1 89 45 e4 8b 45 08 0f bf 48 32 8b 45 0c 99 f7 f9 8b 4d 08 0f bf 49 30 0f af c1 89 45 e8 8b 45"}],"steps":[{"step":"pack tile id with surface slot","vaHex":"0x004251e5","evidence":"Row renderer reads WORD [index*2+0x00595af0], ORs it with WORD 0x0055b580 << 16, then passes that packed descriptor to 0x004175d3.","meaning":"The live layer0 tile id is carried forward unchanged in the low word."},{"step":"store draw descriptor into temporary object","vaHex":"0x004175dc","evidence":"0x004175d3 stores the packed descriptor at temporary object offset +0x28 and x/y at +0x1c/+0x20.","meaning":"The wrapper prepares a generic draw object; it does not inspect layer1 0x40 or a frame counter."},{"step":"select surface by high word","vaHex":"0x004174bb","evidence":"0x0041747b shifts object +0x28 by 16, masks to 0xff, and indexes surface table 0x0055abd8.","meaning":"The high word selects the loaded CNS/surface slot."},{"step":"convert tile id to source rect","vaHex":"0x004199a9","evidence":"0x004199a0 masks the descriptor to low 16 bits, divides by surface +0x32 columns, and multiplies by +0x2e/+0x30 tile width/height.","meaning":"This is ordinary grid rect math: x=(tile%columns)*w, y=(tile/columns)*h."},{"step":"no animation selector observed","vaHex":"0x004199a0","evidence":"The inspected converter uses tile id, columns, tile width/height, clipping/scaling flags, and draw object flags only.","meaning":"No layer1 0x40, animation-map identity, frame counter, or alternate-tile sequence is consumed here."}],"nextFrontier":["Search for a producer/tick path that mutates live layer0 0x00595af0 before redraw.","Search for another specialized map-animation draw callback outside the generic tile converter.","If static scans stay negative, runtime-watch live layer0 values during map1_01a/map1_02b animation."]}