Start moving command line parsing into a separate file

This commit is contained in:
Jeffrey Pfau 2014-04-20 04:06:44 -07:00
parent e739e4000b
commit 89ccb41b03
6 changed files with 163 additions and 26 deletions

View File

@ -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 @@ endif()
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()

View File

@ -164,6 +164,15 @@ static THREAD_ENTRY _GBAThreadRun(void* context) {
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;

View File

@ -6,6 +6,7 @@
#include "gba.h"
#include "util/threading.h"
#include "platform/commandline.h"
struct GBAThread;
typedef void (*ThreadCallback)(struct GBAThread* threadContext);
@ -72,6 +73,8 @@ struct GBAThread {
int rewindBufferWriteOffset;
};
void GBAMapOptionsToContext(struct StartupOptions*, struct GBAThread*);
int GBAThreadStart(struct GBAThread* threadContext);
int GBAThreadHasStarted(struct GBAThread* threadContext);
void GBAThreadEnd(struct GBAThread* threadContext);

View File

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

View File

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

View File

@ -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 @@
#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 @@ static const GLint _glTexCoords[] = {
};
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,
.sync.videoFrameWait = 0,
.sync.audioWait = 1,
.startCallback = _GBASDLStart,
.cleanCallback = _GBASDLClean,
.userData = &renderer,
.rewindBufferCapacity = 10,
.rewindBufferInterval = 30
.sync.videoFrameWait = 0,
.sync.audioWait = 1,
.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 @@ static int _GBASDLInit(struct GLSoftwareRenderer* renderer) {
#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;