sourcehold-maps icon indicating copy to clipboard operation
sourcehold-maps copied to clipboard

Add easier tilemap memory modification code

Open gynt opened this issue 6 months ago • 0 comments

Perhaps something like this:

import ctypes, numpy

addr = 0x401000 # example
addr_type = ctypes.POINTER(ctypes.c_int * 101) # example

pObj = ctypes.cast(addr, addr_type)
obj = pObj.contents

mv = memoryview(obj)
# Optional fix:
mv = mv.cast("B", (mv.nbytes,)).cast("i", mv.shape) # because python is being annoying by inserting a unreadable '<' in the format

Now this mv object can be passed to for example numpy to create a by-reference interface to the memory.

arr = numpy.frombuffer(mv2, dtype='int32')

Sourcehold should provide a layerdata_to_matrix(data) -> matrix function for both 400x400 and 800x800 The data argument can be a memoryview, or anything that implements the __buffer__ interface, like a io.BytesIO or a bytearray.

It should work well with the three possible interaction modes:

  1. File manipulation
  2. Memory manipulation externally
  3. Embedded

The snippet above is for embedded use cases, e.g. a game memory pointer is cast. Since external memory manipulation uses read/write function calls, the with logic should be used for that situation.

layer = shc.getMapLayer(1003) # Returns a ExternalMapLayer object
layer = game.getMapLayer(1003) # Gets a EmbeddedMapLayer
layer = map.getMapLayer(1003) # Gets a FileMapLayer

with layer:
  m = layer.as_matrix() # Does a read internally via __enter__
  # do stuff with the 400x400 matrix here
# __enter__ and __leave__ are used to do the read and write for ExternalMapLayer

gynt avatar Jul 01 '25 14:07 gynt