Core: Add basic scripting bridge

This commit is contained in:
Vicki Pfau 2017-07-07 14:09:32 -07:00
parent dce49ea990
commit 1a7a544ba7
7 changed files with 68 additions and 0 deletions

View File

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

View File

@ -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*);

View File

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

View File

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

View File

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

View File

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

View File

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