Browse Source

Improve ROM loading.

master
Ben Kurtovic 9 years ago
parent
commit
afe764d034
4 changed files with 80 additions and 31 deletions
  1. +9
    -10
      crater.c
  2. +4
    -1
      makefile
  3. +58
    -19
      src/rom.c
  4. +9
    -1
      src/rom.h

+ 9
- 10
crater.c View File

@@ -37,19 +37,18 @@ int main(int argc, char *argv[])
retval = retval ? EXIT_SUCCESS : EXIT_FAILURE;
} else {
ROM *rom;
const char* errmsg;

printf("crater: a Sega Game Gear emulator\n\n");
if (!(rom = rom_open(config->rom_path))) {
if (errno == ENOMEM)
OUT_OF_MEMORY()
else
FATAL_ERRNO("couldn't load ROM image '%s'", config->rom_path)
}
printf("Loaded ROM image: %s\n", rom->name);
if ((errmsg = rom_open(&rom, config->rom_path))) {
ERROR("couldn't load ROM image '%s': %s", config->rom_path, errmsg)
retval = EXIT_FAILURE;
} else {
printf("crater: emulating: %s\n", rom->name);

// TODO: emulate game here...
// TODO: emulate game here...

rom_close(rom);
rom_close(rom);
}
}

config_destroy(config);


+ 4
- 1
makefile View File

@@ -26,13 +26,16 @@ ifdef DEBUG
MODE = debug
endif

.PHONY: all clean
.PHONY: all clean test

all: $(BNRY)

clean:
$(RM) $(BUILD) $(PROGRAM) $(PROGRAM)$(DEVEXT)

test:
@echo "not implemented yet"

$(DIRS):
$(MKDIR) $@



+ 58
- 19
src/rom.c View File

@@ -2,51 +2,86 @@
Released under the terms of the MIT License. See LICENSE for details. */

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#include "rom.h"
#include "logging.h"

/*
Create and return a ROM object located at the given path. Return NULL if
there was an error; errno will be set appropriately.
Return whether or not the given ROM image size is valid.
*/
ROM* rom_open(const char *path)
static bool validate_size(off_t size)
{
off_t kbytes = size >> 10;
if (kbytes << 10 != size)
return false;
if (kbytes < 8 || kbytes > 1024)
return false;
return !(kbytes & (kbytes - 1));
}

/*
Create and load a ROM image located at the given path.

rom_ptr will point to the new object if created successfully, and NULL will
be returned. Otherwise, rom_ptr will not be modified and an error string
will be returned. The error string should not be freed.
*/
const char* rom_open(ROM **rom_ptr, const char *path)
{
ROM *rom;
FILE* fp;
struct stat s;
struct stat st;

if (!(fp = fopen(path, "r")))
return NULL;
return strerror(errno);

if (fstat(fileno(fp), &s)) {
if (fstat(fileno(fp), &st)) {
fclose(fp);
return NULL;
return strerror(errno);
}
if (!(s.st_mode & S_IFREG)) {
errno = (s.st_mode & S_IFDIR) ? EISDIR : ENOENT;
if (!(st.st_mode & S_IFREG)) {
fclose(fp);
return NULL;
return (st.st_mode & S_IFDIR) ? rom_err_isdir : rom_err_notfile;
}

if (!(rom = malloc(sizeof(ROM)))) {
if (!(rom = malloc(sizeof(ROM))))
OUT_OF_MEMORY()

// Set defaults:
rom->name = NULL;
rom->data = NULL;
rom->size = 0;

// Set rom->name:
if (!(rom->name = malloc(sizeof(char) * (strlen(path) + 1))))
OUT_OF_MEMORY()
strcpy(rom->name, path);

// Set rom->size:
if (!validate_size(st.st_size)) {
rom_close(rom);
fclose(fp);
return NULL;
return rom_err_badsize;
}
rom->name = malloc(sizeof(char) * (strlen(path) + 1));
if (!rom->name) {
rom->size = st.st_size;

// Set rom->data:
if (!(rom->data = malloc(sizeof(char) * st.st_size)))
OUT_OF_MEMORY()
if (!(fread(rom->data, st.st_size, 1, fp))) {
rom_close(rom);
fclose(fp);
return NULL;
return rom_err_badread;
}
strcpy(rom->name, path);

// TODO: load data from file into a buffer

fclose(fp);
return rom;
*rom_ptr = rom;
return NULL;
}

/*
@@ -54,5 +89,9 @@ ROM* rom_open(const char *path)
*/
void rom_close(ROM *rom)
{
if (rom->name)
free(rom->name);
if (rom->data)
free(rom->data);
free(rom);
}

+ 9
- 1
src/rom.h View File

@@ -3,14 +3,22 @@

#pragma once

/* Error strings */

static const char* rom_err_isdir = "Is a directory";
static const char* rom_err_notfile = "Is not a regular file";
static const char* rom_err_badsize = "Invalid size";
static const char* rom_err_badread = "Couldn't read the entire file";

/* Structs */

typedef struct {
char* name;
char* data;
unsigned size;
} ROM;

/* Functions */

ROM* rom_open(const char*);
const char* rom_open(ROM**, const char*);
void rom_close(ROM*);

Loading…
Cancel
Save