Python: Export memory search

This commit is contained in:
Vicki Pfau 2017-06-11 14:02:40 -07:00
parent eff48a77f1
commit 04ebc6a06e
4 changed files with 76 additions and 2 deletions

View File

@ -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}

View File

@ -28,6 +28,7 @@ void free(void*);
#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"

View File

@ -21,6 +21,7 @@ ffi.set_source("mgba._pylib", """
#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>

View File

@ -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