drawMap() into an image has problems if the map is unloaded before the next update() call
-
Sorry, I've been abusing your systems again :)
Project share code (pending): 517C7MND51
The project has two maps. "empty" is just empty with no media configured, "full" has some trees in it from "Ansimuz/TinyRPGForestObjectTiles".
The code loads the "full" map, renders it into img1, then loads "empty", renders it into img2, then "full" again, rendering it into img3.
Then img1 and img3 are drawn to the screen. For img1, the trees are corrupted.
All operations on img3 can be removed, the corruption persists.
Only a call to update() before loading the map "empty"Code:
function test() w = 640 loadMap("full") img1 = createImage(w,w,false,image_rgb) setDrawTarget(img1) drawMap() // uncommenting this fixes the problem // update() loadMap("empty") img2 = createImage(w,w,false,image_rgb) setDrawTarget(img2) drawMap() loadMap("full") img3 = createImage(w,w,false,image_rgb) setDrawTarget(img3) drawMap() setDrawTarget(frameBuffer) clear() drawImage(img1,0,0,1) drawImage(img2,w,0,1) update() sleep(20) return void test()
Guessing: It's documented that all draw operations only execute once update() is called. That probably includes drawing to the image targets. The only problem there is that the assets "full" is using are probably thrown out when "empty" is loaded (assets shared by the two maps don't cause problems, the map loading code is smart enough to just keep them), so when the drawing operations need them, they're no longer available. Or at least not available where they're expected in the case that "full" is loaded again.
Even simpler code that triggers the bug for me; as with all use-after-free bugs, the results are a bit nondeterministic:
function test2() w = 640 loadMap("full") drawMap() unloadMap() img2 = createImage(w,w,false,image_rgb) update() sleep(20) return void test2()
So the crucial ingredients seem to be that you need to unload the map (and its assets) between drawMap() and update(), and something between unloading the map and update() needs to get lucky and corrupt the memory where the assets had been.
No rush! I definitely don't want to swap between maps in a single frame! Nobody should even think about that!