Browse Source

Implement most forward-facing CLI stuff.

master
Ben Kurtovic 9 years ago
parent
commit
881226da70
8 changed files with 226 additions and 7 deletions
  1. +15
    -2
      README.md
  2. +153
    -3
      crater.c
  3. +13
    -0
      src/errors.c
  4. +6
    -0
      src/errors.h
  5. +22
    -0
      src/rom.c
  6. +9
    -0
      src/rom.h
  7. +6
    -0
      src/version.h
  8. +2
    -2
      src/z80.h

+ 15
- 2
README.md View File

@@ -25,6 +25,19 @@ Only OS X and Linux are tested. You'll need a decent compiler that supports C11
(gcc, clang) and SDL 2. Using Homebrew, you can `brew install sdl2`; using apt,
you can `apt-get install libsdl2-dev`.

Run `make` and then `./crater`. To build the development version with debug
symbols (they can exist simultaneously), run `make DEBUG=1` and then
Run `make` to create `./crater`. To build the development version with debug
symbols (they can exist simultaneously), run `make DEBUG=1`, which creates
`./crater-dev`.

Usage
-----

Running `./crater` without arguments will display a list of ROM images located
in the `roms/` directory, and then ask the user to pick one, or enter their own
ROM path. You can provide a path directly with `./crater path/to/rom`.

Add or symlink ROMs to `roms/` at your leisure. Note that they should end in
`.gg` or `.bin`.

`./crater -h` gives (fairly basic) command-line usage, and `./crater -v` gives
the current version.

+ 153
- 3
crater.c View File

@@ -1,10 +1,160 @@
/* Copyright (C) 2014 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <dirent.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <SDL.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

int main(int argc, char* argv[]) {
printf("Hello, world!\n");
#include "src/errors.h"
#include "src/rom.h"
#include "src/version.h"

#define ROMS_DIR "roms"

/* Print command-line help/usage. */
static void print_help(char *arg1)
{
printf("%s [--help|-h] [--version|-v] [rom_path]\n", arg1);
}

/* Print crater's version. */
static void print_version()
{
printf("crater %s\n", CRATER_VERSION);
}

/* Parse the command-line arguments for any special flags. */
static void parse_args(int argc, char *argv[])
{
char *arg;
int i;

for (i = 1; i < argc; i++) {
arg = argv[i];
if (arg[0] != '-')
continue;
do
arg++;
while (arg[0] == '-');

if (!strcmp(arg, "h") || !strcmp(arg, "help")) {
print_help(argv[0]);
exit(0);
} else if (!strcmp(arg, "v") || !strcmp(arg, "version")) {
print_version();
exit(0);
} else {
printf("Error: unknown argument: %s\n", argv[i]);
exit(1);
}
}
}

/* Return whether the given string ends with the given suffix. */
static bool ends_with(char *input, char *suffix)
{
size_t ilen = strlen(input), slen = strlen(suffix);

if (ilen < slen)
return false;
return strcmp(input + (ilen - slen), suffix) == 0;
}

/* Load all potential ROM files in roms/ into a data structure. */
static int load_rom_paths(char ***path_ptr)
{
DIR *dirp;
struct dirent *entry;
char **paths = NULL, *path;
int psize = 8, npaths = 0;

dirp = opendir(ROMS_DIR);
if (dirp) {
paths = malloc(sizeof(char*) * psize);
if (!paths)
out_of_memory();
while ((entry = readdir(dirp))) {
path = entry->d_name;
if (ends_with(path, ".gg") || ends_with(path, ".bin")) {
if (npaths >= psize) {
paths = realloc(paths, sizeof(char*) * (psize *= 2));
if (!paths)
out_of_memory();
}
paths[npaths] = malloc(sizeof(char*) *
(strlen(path) + strlen(ROMS_DIR) + 1));
if (!paths[npaths])
out_of_memory();
strcpy(paths[npaths], ROMS_DIR "/");
strcat(paths[npaths], path);
npaths++;
}
}
closedir(dirp);
} else {
if (errno == ENOENT)
printf("Warning: couldn't find roms/ directory.\n");
else
perror("Warning: couldn't open roms/ directory");
}
*path_ptr = paths;
return npaths;
}

/* Find all potential ROM files in the roms/ directory, then ask the user which
* one they want to run.
*/
static char* get_rom_path_from_user()
{
char **paths, *path, *input = NULL;
int npaths, i;
long int index;
size_t size = 0;
ssize_t len;

npaths = load_rom_paths(&paths);
for (i = 0; i < npaths; i++)
printf("[%2d] %s\n", i + 1, paths[i]);
if (npaths)
printf("Enter a ROM number from above, or the path to a ROM image: ");
else
printf("Enter the path to a ROM image: ");

len = getline(&input, &size, stdin);
if (!input)
out_of_memory();
if (len > 0 && input[len - 1] == '\n')
input[len - 1] = '\0';
index = strtol(input, NULL, 10);
if (index < 1 || index > npaths)
path = input;
else
path = paths[index - 1];

for (i = 0; i < npaths; i++) {
if (paths[i] != path)
free(paths[i]);
}
if (paths)
free(paths);
return path;
}

int main(int argc, char *argv[])
{
char *rom_path;

parse_args(argc, argv);
rom_path = argc > 1 ? argv[1] : get_rom_path_from_user();

// TODO: main logic hook here
printf("Loading ROM: %s\n", rom_path);

if (argc <= 1)
free(rom_path);
return 0;
}

+ 13
- 0
src/errors.c View File

@@ -0,0 +1,13 @@
/* Copyright (C) 2014 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <stdio.h>
#include <stdlib.h>

#include "errors.h"

/* Called after an out-of-memory error. Prints a message and dies. */
void out_of_memory() {
printf("Error: couldn't allocate memory.\n");
exit(1);
}

+ 6
- 0
src/errors.h View File

@@ -0,0 +1,6 @@
/* Copyright (C) 2014 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#pragma once

void out_of_memory();

+ 22
- 0
src/rom.c View File

@@ -0,0 +1,22 @@
/* Copyright (C) 2014 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <stdlib.h>

#include "rom.h"
#include "errors.h"

rom_type* load_rom(char *path)
{
rom_type *rom;

rom = malloc(sizeof(rom_type));
if (!rom)
out_of_memory();
return rom;
}

void unload_rom(rom_type *rom)
{
free(rom);
}

+ 9
- 0
src/rom.h View File

@@ -0,0 +1,9 @@
/* Copyright (C) 2014 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#pragma once

typedef struct {
char* name;
char* data;
} rom_type;

+ 6
- 0
src/version.h View File

@@ -0,0 +1,6 @@
/* Copyright (C) 2014 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#pragma once

#define CRATER_VERSION "0.1.dev"

+ 2
- 2
src/z80.h View File

@@ -3,6 +3,6 @@

#pragma once

struct register_t {
typedef struct {
int pc;
};
} register_type;

Loading…
Cancel
Save