all repos — mgba @ 04ebc6a06e654f5205b5df3f69c08cc9e93d4784

mGBA Game Boy Advance Emulator

Python: Export memory search
Vicki Pfau vi@endrift.com
Sun, 11 Jun 2017 14:02:40 -0700
commit

04ebc6a06e654f5205b5df3f69c08cc9e93d4784

parent

eff48a77f1760287a74c6a5040f624c0fbe207a0

M src/platform/python/CMakeLists.txtsrc/platform/python/CMakeLists.txt

@@ -1,12 +1,12 @@

find_program(PYTHON python) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py) - get_property(INCLUDE_DIRECTORIES DIRECTORY PROPERTY INCLUDE_DIRECTORIES) set(INCLUDE_FLAGS) foreach(DIR IN LISTS INCLUDE_DIRECTORIES) list(APPEND INCLUDE_FLAGS "-I${DIR}") endforeach() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py) add_custom_command(OUTPUT build/lib/${BINARY_NAME}/__init__.py COMMAND BINDIR=${CMAKE_CURRENT_BINARY_DIR}/.. CPPFLAGS="${INCLUDE_FLAGS}" ${PYTHON} ${CMAKE_CURRENT_BINARY_DIR}/setup.py build --build-base ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
M src/platform/python/_builder.hsrc/platform/python/_builder.h

@@ -28,6 +28,7 @@

#include "flags.h" #include <mgba/core/core.h> +#include <mgba/core/mem-search.h> #include <mgba/core/tile-cache.h> #define PYEXPORT extern "Python+C"
M src/platform/python/_builder.pysrc/platform/python/_builder.py

@@ -21,6 +21,7 @@ #include "flags.h"

#include <mgba-util/common.h> #include <mgba/core/core.h> #include <mgba/core/log.h> +#include <mgba/core/mem-search.h> #include <mgba/core/tile-cache.h> #include <mgba/internal/arm/arm.h> #include <mgba/internal/gba/gba.h>
M src/platform/python/mgba/memory.pysrc/platform/python/mgba/memory.py

@@ -67,10 +67,53 @@ def rawWrite(self, address, value, segment=-1):

self._addrCheck(address) self._rawWrite(self._core, self._base + address, segment, value & self._mask) + +class MemorySearchResult(object): + def __init__(self, memory, result): + self.address = result.address + self.segment = result.segment + self.guessDivisor = result.guessDivisor + self.type = result.type + + if result.type == Memory.SEARCH_8: + self._memory = memory.u8 + elif result.type == Memory.SEARCH_16: + self._memory = memory.u16 + elif result.type == Memory.SEARCH_32: + self._memory = memory.u32 + elif result.type == Memory.SEARCH_STRING: + self._memory = memory.u8 + else: + raise ValueError("Unknown type: %X" % result.type) + + @property + def value(self): + if self.type == Memory.SEARCH_STRING: + raise ValueError + return self._memory[self.address] * self.guessDivisor + + @value.setter + def value(self, v): + if self.type == Memory.SEARCH_STRING: + raise IndexError + self._memory[self.address] = v // self.guessDivisor + + class Memory(object): + SEARCH_32 = lib.mCORE_MEMORY_SEARCH_32 + SEARCH_16 = lib.mCORE_MEMORY_SEARCH_16 + SEARCH_8 = lib.mCORE_MEMORY_SEARCH_8 + SEARCH_STRING = lib.mCORE_MEMORY_SEARCH_STRING + SEARCH_GUESS = lib.mCORE_MEMORY_SEARCH_GUESS + + READ = lib.mCORE_MEMORY_READ + WRITE = lib.mCORE_MEMORY_READ + RW = lib.mCORE_MEMORY_RW + def __init__(self, core, size, base=0): self.size = size self.base = base + self._core = core self.u8 = MemoryView(core, 1, size, base, "u") self.u16 = MemoryView(core, 2, size, base, "u")

@@ -81,3 +124,32 @@ self.s32 = MemoryView(core, 4, size, base, "s")

def __len__(self): return self._size + + def search(self, value, type=SEARCH_GUESS, flags=RW, limit=10000, old_results=[]): + results = ffi.new("struct mCoreMemorySearchResults*") + lib.mCoreMemorySearchResultsInit(results, len(old_results)) + params = ffi.new("struct mCoreMemorySearchParams*") + params.memoryFlags = flags + params.type = type + if type == self.SEARCH_8: + params.value8 = int(value) + elif type == self.SEARCH_16: + params.value16 = int(value) + elif type == self.SEARCH_32: + params.value32 = int(value) + else: + params.valueStr = ffi.new("char[]", str(value).encode("ascii")) + + for result in old_results: + r = lib.mCoreMemorySearchResultsAppend(results) + r.address = result.address + r.segment = result.segment + r.guessDivisor = result.guessDivisor + r.type = result.type + if old_results: + lib.mCoreMemorySearchRepeat(self._core, params, results) + else: + lib.mCoreMemorySearch(self._core, params, results, limit) + new_results = [MemorySearchResult(self, lib.mCoreMemorySearchResultsGetPointer(results, i)) for i in range(lib.mCoreMemorySearchResultsSize(results))] + lib.mCoreMemorySearchResultsDeinit(results) + return new_results