Start moving command line parsing into a separate file
Jeffrey Pfau jeffrey@endrift.com
Sun, 20 Apr 2014 04:06:44 -0700
6 files changed,
163 insertions(+),
26 deletions(-)
M
CMakeLists.txt
→
CMakeLists.txt
@@ -11,6 +11,7 @@ file(GLOB ARM_SRC ${CMAKE_SOURCE_DIR}/src/arm/*.c)
file(GLOB GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c) file(GLOB UTIL_SRC ${CMAKE_SOURCE_DIR}/src/util/*.[cS]) file(GLOB RENDERER_SRC ${CMAKE_SOURCE_DIR}/src/gba/renderers/video-software.c) +set(UTIL_SRC ${UTIL_SRC};${CMAKE_SOURCE_DIR}/src/platform/commandline.c) source_group("ARM core" FILES ${ARM_SRC}) source_group("GBA board" FILES ${GBA_SRC} ${RENDERER_SRC}) source_group("Utilities" FILES ${UTIL_SRC})@@ -39,6 +40,7 @@
set(DEBUGGER_SRC "${CMAKE_SOURCE_DIR}/src/debugger/debugger.c;${CMAKE_SOURCE_DIR}/src/debugger/memory-debugger.c") if(USE_CLI_DEBUGGER) + add_definitions(-DUSE_CLI_DEBUGGER) set(DEBUGGER_SRC "${DEBUGGER_SRC};${CMAKE_SOURCE_DIR}/src/debugger/cli-debugger.c") set(DEBUGGER_LIB "edit") else()
M
src/gba/gba-thread.c
→
src/gba/gba-thread.c
@@ -164,6 +164,15 @@
return 0; } +void GBAMapOptionsToContext(struct StartupOptions* opts, struct GBAThread* threadContext) { + threadContext->fd = opts->fd; + threadContext->fname = opts->fname; + threadContext->biosFd = opts->biosFd; + threadContext->frameskip = opts->frameskip; + threadContext->rewindBufferCapacity = opts->rewindBufferCapacity; + threadContext->rewindBufferInterval = opts->rewindBufferInterval; +} + int GBAThreadStart(struct GBAThread* threadContext) { // TODO: error check threadContext->activeKeys = 0;
M
src/gba/gba-thread.h
→
src/gba/gba-thread.h
@@ -6,6 +6,7 @@
#include "gba.h" #include "util/threading.h" +#include "platform/commandline.h" struct GBAThread; typedef void (*ThreadCallback)(struct GBAThread* threadContext);@@ -71,6 +72,8 @@ int rewindBufferNext;
struct GBASerializedState** rewindBuffer; int rewindBufferWriteOffset; }; + +void GBAMapOptionsToContext(struct StartupOptions*, struct GBAThread*); int GBAThreadStart(struct GBAThread* threadContext); int GBAThreadHasStarted(struct GBAThread* threadContext);
A
src/platform/commandline.c
@@ -0,0 +1,56 @@
+#include "commandline.h" + +#include <fcntl.h> +#include <getopt.h> + +static const char* _defaultFilename = "test.rom"; + +static const struct option _options[] = { + { "bios", 1, 0, 'b' }, + { "gdb", 1, 0, 'g' }, + { 0, 0, 0, 0 } +}; + +int parseCommandArgs(struct StartupOptions* opts, int argc, char* const* argv) { + memset(opts, 0, sizeof(*opts)); + opts->fd = -1; + opts->biosFd = -1; + opts->width = 240; + opts->height = 160; + opts->fullscreen = 0; + + int ch; + while ((ch = getopt_long(argc, argv, "b:dfg", _options, 0)) != -1) { + switch (ch) { + case 'b': + opts->biosFd = open(optarg, O_RDONLY); + break; +#ifdef USE_CLI_DEBUGGER + case 'd': + opts->debuggerType = DEBUGGER_CLI; + break; +#endif + case 'f': + opts->fullscreen = 1; + break; +#ifdef USE_GDB_STUB + case 'g': + opts->debuggerType = DEBUGGER_GDB; + break; +#endif + } + } + argc -= optind; + argv += optind; + if (argc) { + opts->fname = argv[0]; + } else { + opts->fname = _defaultFilename; + } + opts->fd = open(opts->fname, O_RDONLY); + return 1; +} + +void usage(const char* arg0) { + printf("%s: bad arguments\n", arg0); +}
A
src/platform/commandline.h
@@ -0,0 +1,36 @@
+#ifndef COMMAND_LINE_H +#define COMMAND_LINE_H + +#include "common.h" + +enum DebuggerType { + DEBUGGER_NONE = 0, +#ifdef USE_CLI_DEBUGGER + DEBUGGER_CLI, +#endif +#ifdef USE_GDB_STUB + DEBUGGER_GDB, +#endif + DEBUGGER_MAX +}; + +struct StartupOptions { + int fd; + const char* fname; + int biosFd; + int frameskip; + int rewindBufferCapacity; + int rewindBufferInterval; + + int width; + int height; + int fullscreen; + + enum DebuggerType debuggerType; + int debugAtStart; +}; + +int parseCommandArgs(struct StartupOptions* opts, int argc, char* const* argv); +void usage(const char* arg0); + +#endif
M
src/platform/sdl/gl-main.c
→
src/platform/sdl/gl-main.c
@@ -1,9 +1,17 @@
+#ifdef USE_CLI_DEBUGGER #include "debugger/cli-debugger.h" +#endif + +#ifdef USE_GDB_STUB +#include "debugger/gdb-stub.h" +#endif + #include "gba-thread.h" #include "gba.h" #include "sdl-audio.h" #include "sdl-events.h" #include "renderers/video-software.h" +#include "platform/commandline.h" #include <SDL.h> #ifdef __APPLE__@@ -12,11 +20,9 @@ #else
#include <GL/gl.h> #endif -#include <fcntl.h> #include <errno.h> #include <signal.h> #include <sys/time.h> -#include <unistd.h> struct GLSoftwareRenderer { struct GBAVideoSoftwareRenderer d;@@ -52,48 +58,73 @@ 0, 1
}; int main(int argc, char** argv) { - const char* fname = "test.rom"; - if (argc > 1) { - fname = argv[1]; - } - int fd = open(fname, O_RDONLY); - if (fd < 0) { - return 1; - } - struct GLSoftwareRenderer renderer; GBAVideoSoftwareRendererCreate(&renderer.d); - renderer.viewportWidth = 240; - renderer.viewportHeight = 160; + struct StartupOptions opts; + if (!parseCommandArgs(&opts, argc, argv)) { + usage(argv[0]); + return 1; + } + + renderer.viewportWidth = opts.width; + renderer.viewportHeight = opts.height; +#if SDL_VERSION_ATLEAST(2, 0, 0) + renderer.events.fullscreen = opts.fullscreen; +#endif if (!_GBASDLInit(&renderer)) { return 1; } - struct CLIDebugger debugger; - CLIDebuggerCreate(&debugger); + union { + struct ARMDebugger d; +#ifdef USE_CLI_DEBUGGER + struct CLIDebugger cli; +#endif +#ifdef USE_GDB_STUB + struct GDBStub gdb; +#endif + } debugger; + struct GBAThread context = { - .fd = fd, - .biosFd = -1, - .fname = fname, .debugger = &debugger.d, .renderer = &renderer.d.d, - .frameskip = 0, + .startCallback = _GBASDLStart, + .cleanCallback = _GBASDLClean, .sync.videoFrameWait = 0, .sync.audioWait = 1, - .startCallback = _GBASDLStart, - .cleanCallback = _GBASDLClean, - .userData = &renderer, - .rewindBufferCapacity = 10, - .rewindBufferInterval = 30 + .userData = &renderer }; + + switch (opts.debuggerType) { +#ifdef USE_CLI_DEBUGGER + case DEBUGGER_CLI: + CLIDebuggerCreate(&debugger.cli); + break; +#endif +#ifdef USE_GDB_STUB + case DEBUGGER_GDB: + GDBStubCreate(&debugger.gdb); + break; +#endif + case DEBUGGER_NONE: + case DEBUGGER_MAX: + context.debugger = 0; + break; + } + + GBAMapOptionsToContext(&opts, &context); + GBAThreadStart(&context); _GBASDLRunloop(&context, &renderer); GBAThreadJoin(&context); - close(fd); + close(opts.fd); + if (opts.biosFd >= 0) { + close(opts.biosFd); + } _GBASDLDeinit(&renderer);@@ -129,7 +160,7 @@ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
#endif #if SDL_VERSION_ATLEAST(2, 0, 0) - renderer->window = SDL_CreateWindow("GBAc", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL); + renderer->window = SDL_CreateWindow("GBAc", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->events.fullscreen)); SDL_GL_CreateContext(renderer->window); SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); renderer->events.window = renderer->window;