mirror of https://github.com/mgba-emu/mgba.git
Core: Add basic scripting bridge
This commit is contained in:
parent
dce49ea990
commit
1a7a544ba7
|
@ -19,6 +19,7 @@ set(USE_SQLITE3 ON CACHE BOOL "Whether or not to enable SQLite3 support")
|
||||||
set(M_CORE_GBA ON CACHE BOOL "Build Game Boy Advance core")
|
set(M_CORE_GBA ON CACHE BOOL "Build Game Boy Advance core")
|
||||||
set(M_CORE_GB ON CACHE BOOL "Build Game Boy core")
|
set(M_CORE_GB ON CACHE BOOL "Build Game Boy core")
|
||||||
set(USE_LZMA ON CACHE BOOL "Whether or not to enable 7-Zip support")
|
set(USE_LZMA ON CACHE BOOL "Whether or not to enable 7-Zip support")
|
||||||
|
set(ENABLE_SCRIPTING ON CACHE BOOL "Whether or not to enable scripting support")
|
||||||
set(BUILD_QT ON CACHE BOOL "Build Qt frontend")
|
set(BUILD_QT ON CACHE BOOL "Build Qt frontend")
|
||||||
set(BUILD_SDL ON CACHE BOOL "Build SDL frontend")
|
set(BUILD_SDL ON CACHE BOOL "Build SDL frontend")
|
||||||
set(BUILD_LIBRETRO OFF CACHE BOOL "Build libretro core")
|
set(BUILD_LIBRETRO OFF CACHE BOOL "Build libretro core")
|
||||||
|
@ -353,6 +354,7 @@ endif()
|
||||||
# Feature dependencies
|
# Feature dependencies
|
||||||
set(FEATURE_DEFINES)
|
set(FEATURE_DEFINES)
|
||||||
set(FEATURES)
|
set(FEATURES)
|
||||||
|
set(ENABLES)
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES .*BSD)
|
if(CMAKE_SYSTEM_NAME MATCHES .*BSD)
|
||||||
set(LIBEDIT_LIBRARIES -ledit)
|
set(LIBEDIT_LIBRARIES -ledit)
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
|
if (CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
|
||||||
|
@ -599,6 +601,10 @@ if(USE_SQLITE3)
|
||||||
list(APPEND FEATURE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/feature/sqlite3/no-intro.c")
|
list(APPEND FEATURE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/feature/sqlite3/no-intro.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_SCRIPTING)
|
||||||
|
list(APPEND ENABLES SCRIPTING)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(TEST_SRC ${CORE_TEST_SRC})
|
set(TEST_SRC ${CORE_TEST_SRC})
|
||||||
if(M_CORE_GB)
|
if(M_CORE_GB)
|
||||||
add_definitions(-DM_CORE_GB)
|
add_definitions(-DM_CORE_GB)
|
||||||
|
@ -646,6 +652,10 @@ foreach(FEATURE IN LISTS FEATURES)
|
||||||
list(APPEND FEATURE_DEFINES "USE_${FEATURE}")
|
list(APPEND FEATURE_DEFINES "USE_${FEATURE}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
foreach(ENABLE IN LISTS ENABLES)
|
||||||
|
list(APPEND FEATURE_DEFINES "ENABLE_${ENABLE}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
source_group("Virtual files" FILES ${CORE_VFS_SRC} ${VFS_SRC})
|
source_group("Virtual files" FILES ${CORE_VFS_SRC} ${VFS_SRC})
|
||||||
source_group("Extra features" FILES ${FEATURE_SRC})
|
source_group("Extra features" FILES ${FEATURE_SRC})
|
||||||
source_group("Third-party code" FILES ${THIRD_PARTY_SRC})
|
source_group("Third-party code" FILES ${THIRD_PARTY_SRC})
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum mDebuggerState {
|
||||||
DEBUGGER_PAUSED,
|
DEBUGGER_PAUSED,
|
||||||
DEBUGGER_RUNNING,
|
DEBUGGER_RUNNING,
|
||||||
DEBUGGER_CUSTOM,
|
DEBUGGER_CUSTOM,
|
||||||
|
DEBUGGER_SCRIPT,
|
||||||
DEBUGGER_SHUTDOWN
|
DEBUGGER_SHUTDOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,6 +93,7 @@ struct mDebugger {
|
||||||
struct mDebuggerPlatform* platform;
|
struct mDebuggerPlatform* platform;
|
||||||
enum mDebuggerState state;
|
enum mDebuggerState state;
|
||||||
struct mCore* core;
|
struct mCore* core;
|
||||||
|
struct mScriptBridge* bridge;
|
||||||
|
|
||||||
void (*init)(struct mDebugger*);
|
void (*init)(struct mDebugger*);
|
||||||
void (*deinit)(struct mDebugger*);
|
void (*deinit)(struct mDebugger*);
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
#include <mgba/internal/debugger/parser.h>
|
#include <mgba/internal/debugger/parser.h>
|
||||||
#include <mgba-util/string.h>
|
#include <mgba-util/string.h>
|
||||||
|
|
||||||
|
#if ENABLE_SCRIPTING
|
||||||
|
#include <mgba/core/scripting.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(NDEBUG) && !defined(_WIN32)
|
#if !defined(NDEBUG) && !defined(_WIN32)
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,6 +55,9 @@ static void _writeWord(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _dumpByte(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _dumpByte(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _dumpHalfword(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _dumpHalfword(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _dumpWord(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _dumpWord(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
static void _source(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct CLIDebuggerCommandSummary _debuggerCommands[] = {
|
static struct CLIDebuggerCommandSummary _debuggerCommands[] = {
|
||||||
{ "b", _setBreakpoint, CLIDVParse, "Set a breakpoint" },
|
{ "b", _setBreakpoint, CLIDVParse, "Set a breakpoint" },
|
||||||
|
@ -92,6 +99,9 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = {
|
||||||
{ "x/1", _dumpByte, CLIDVParse, "Examine bytes at a specified offset" },
|
{ "x/1", _dumpByte, CLIDVParse, "Examine bytes at a specified offset" },
|
||||||
{ "x/2", _dumpHalfword, CLIDVParse, "Examine halfwords at a specified offset" },
|
{ "x/2", _dumpHalfword, CLIDVParse, "Examine halfwords at a specified offset" },
|
||||||
{ "x/4", _dumpWord, CLIDVParse, "Examine words at a specified offset" },
|
{ "x/4", _dumpWord, CLIDVParse, "Examine words at a specified offset" },
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
{ "source", _source, CLIDVStringParse, "Load a script" },
|
||||||
|
#endif
|
||||||
#if !defined(NDEBUG) && !defined(_WIN32)
|
#if !defined(NDEBUG) && !defined(_WIN32)
|
||||||
{ "!", _breakInto, 0, "Break into attached debugger (for developers)" },
|
{ "!", _breakInto, 0, "Break into attached debugger (for developers)" },
|
||||||
#endif
|
#endif
|
||||||
|
@ -411,6 +421,20 @@ static void _dumpWord(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
static void _source(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
|
if (!dv) {
|
||||||
|
debugger->backend->printf(debugger->backend, "Needs a filename\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (debugger->d.bridge && mScriptBridgeLoadScript(debugger->d.bridge, dv->charValue)) {
|
||||||
|
debugger->d.state = DEBUGGER_SCRIPT;
|
||||||
|
} else {
|
||||||
|
debugger->backend->printf(debugger->backend, "Failed to load script\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void _setBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
static void _setBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
||||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
#include <mgba/internal/debugger/gdb-stub.h>
|
#include <mgba/internal/debugger/gdb-stub.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_SCRIPTING
|
||||||
|
#include <mgba/core/scripting.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
const uint32_t DEBUGGER_ID = 0xDEADBEEF;
|
const uint32_t DEBUGGER_ID = 0xDEADBEEF;
|
||||||
|
|
||||||
mLOG_DEFINE_CATEGORY(DEBUGGER, "Debugger", "core.debugger");
|
mLOG_DEFINE_CATEGORY(DEBUGGER, "Debugger", "core.debugger");
|
||||||
|
@ -34,6 +38,7 @@ struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore* core) {
|
||||||
};
|
};
|
||||||
|
|
||||||
union DebugUnion* debugger = malloc(sizeof(union DebugUnion));
|
union DebugUnion* debugger = malloc(sizeof(union DebugUnion));
|
||||||
|
memset(debugger, 0, sizeof(*debugger));
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DEBUGGER_CLI:
|
case DEBUGGER_CLI:
|
||||||
|
@ -92,6 +97,14 @@ void mDebuggerRun(struct mDebugger* debugger) {
|
||||||
debugger->state = DEBUGGER_RUNNING;
|
debugger->state = DEBUGGER_RUNNING;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DEBUGGER_SCRIPT:
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
mScriptBridgeRun(debugger->bridge);
|
||||||
|
#endif
|
||||||
|
if (debugger->state == DEBUGGER_SCRIPT) {
|
||||||
|
debugger->state = DEBUGGER_RUNNING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DEBUGGER_SHUTDOWN:
|
case DEBUGGER_SHUTDOWN:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,3 +55,6 @@ void free(void*);
|
||||||
#include <mgba/internal/gba/input.h>
|
#include <mgba/internal/gba/input.h>
|
||||||
#include <mgba/internal/gb/renderers/tile-cache.h>
|
#include <mgba/internal/gb/renderers/tile-cache.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_DEBUGGERS
|
||||||
|
#include <mgba/debugger/debugger.h>
|
||||||
|
#endif
|
||||||
|
|
|
@ -26,6 +26,7 @@ ffi.set_source("mgba._pylib", """
|
||||||
#include <mgba/core/thread.h>
|
#include <mgba/core/thread.h>
|
||||||
#include <mgba/core/tile-cache.h>
|
#include <mgba/core/tile-cache.h>
|
||||||
#include <mgba/core/version.h>
|
#include <mgba/core/version.h>
|
||||||
|
#include <mgba/debugger/debugger.h>
|
||||||
#include <mgba/internal/arm/arm.h>
|
#include <mgba/internal/arm/arm.h>
|
||||||
#include <mgba/internal/gba/gba.h>
|
#include <mgba/internal/gba/gba.h>
|
||||||
#include <mgba/internal/gba/input.h>
|
#include <mgba/internal/gba/input.h>
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
#ifdef USE_EDITLINE
|
#ifdef USE_EDITLINE
|
||||||
#include "feature/editline/cli-el-backend.h"
|
#include "feature/editline/cli-el-backend.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
#include <mgba/core/scripting.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
#include <mgba/core/config.h>
|
#include <mgba/core/config.h>
|
||||||
|
@ -159,6 +162,10 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
mCoreAutoloadSave(renderer->core);
|
mCoreAutoloadSave(renderer->core);
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
struct mScriptBridge* bridge = mScriptBridgeCreate();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DEBUGGERS
|
#ifdef USE_DEBUGGERS
|
||||||
struct mDebugger* debugger = mDebuggerCreate(args->debuggerType, renderer->core);
|
struct mDebugger* debugger = mDebuggerCreate(args->debuggerType, renderer->core);
|
||||||
if (debugger) {
|
if (debugger) {
|
||||||
|
@ -171,6 +178,9 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) {
|
||||||
mDebuggerAttach(debugger, renderer->core);
|
mDebuggerAttach(debugger, renderer->core);
|
||||||
mDebuggerEnter(debugger, DEBUGGER_ENTER_MANUAL, NULL);
|
mDebuggerEnter(debugger, DEBUGGER_ENTER_MANUAL, NULL);
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
mScriptBridgeSetDebugger(bridge, debugger);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (args->patch) {
|
if (args->patch) {
|
||||||
|
@ -212,6 +222,11 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) {
|
||||||
printf("Could not run game. Are you sure the file exists and is a compatible game?\n");
|
printf("Could not run game. Are you sure the file exists and is a compatible game?\n");
|
||||||
}
|
}
|
||||||
renderer->core->unloadROM(renderer->core);
|
renderer->core->unloadROM(renderer->core);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
mScriptBridgeDestroy(bridge);
|
||||||
|
#endif
|
||||||
|
|
||||||
return didFail;
|
return didFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue