Skip to content

Adding support for fast reads from memory to ctypes.Structure objects #69

Description

@blayyyyyk

It seems like this repo is no longer being actively worked on but nonetheless,

I've been messing around with your library and it seems you aren't fully utilizing the capability of the dll that you built from desmume source.

By accessing the ARM9 main memory region MMU.MAIN_MEM, you can pull it directly into a memoryview in python then map that memoryview directly to predefined classes that implement the ctypes.Structure class.

Or more generally, you can slice parts of memory in constant time instead of your current implementation which is linear scale in time complexity.

Below is a simple example of an extension I made locally to test performance gains.

from ctypes import Structure
import ctypes
from desmume.emulator import (
    DeSmuME as D,
    DeSmuME_Memory as DM,
)
from typing import Type, TypeVar, cast
from typing_extensions import override


class MMUPrefix(ctypes.Structure):
    _fields_ = [
        ("ARM9_ITCM", ctypes.c_uint8 * 0x8000),
        ("ARM9_DTCM", ctypes.c_uint8 * 0x4000),
        ("MAIN_MEM", ctypes.c_uint8 * (16 * 1024 * 1024)),
        # ...
    ]


T = TypeVar('T', bound=Structure)
        

class DeSmuME_Memory(DM):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        assert self.emu.lib is not None
        self.memoryview = memoryview(MMUPrefix.in_dll(self.emu.lib, "MMU").MAIN_MEM)
        
    def read_struct(self, struct_t: Type[T], addr: int) -> T:
        struct = struct_t.from_buffer(self.memoryview, addr - 0x02000000) # main memory region 
        return struct

class DeSmuME(D):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._memory = DeSmuME_Memory(self)
        
    @property
    @override
    def memory(self) -> DeSmuME_Memory:
        return cast(DeSmuME_Memory, self._memory)

I'm happy to open a PR if this is a feature you're interested in adding :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions