diff --git a/src/platform/python/CMakeLists.txt b/src/platform/python/CMakeLists.txt index 7b7605e7d..ad0d7536a 100644 --- a/src/platform/python/CMakeLists.txt +++ b/src/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} diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index 8820a8c08..9721e14b6 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -28,6 +28,7 @@ void free(void*); #include "flags.h" #include +#include #include #define PYEXPORT extern "Python+C" diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index ccf35a880..8c8a3716c 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -21,6 +21,7 @@ ffi.set_source("mgba._pylib", """ #include #include #include +#include #include #include #include diff --git a/src/platform/python/mgba/memory.py b/src/platform/python/mgba/memory.py index a7f52e22e..c59f5a792 100644 --- a/src/platform/python/mgba/memory.py +++ b/src/platform/python/mgba/memory.py @@ -67,10 +67,53 @@ class MemoryView(object): 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 @@ class Memory(object): 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