diff options
Diffstat (limited to 'ines2.c')
| -rw-r--r-- | ines2.c | 163 |
1 files changed, 0 insertions, 163 deletions
diff --git a/ines2.c b/ines2.c deleted file mode 100644 index db28090..0000000 --- a/ines2.c +++ /dev/null @@ -1,163 +0,0 @@ - -#include <archive.h> -#include <archive_entry.h> - -// iNES header fields -#define INES_HEADER_SIZE 16 -#define INES_PRG_SIZE_LSB 4 -#define INES_CHR_SIZE_LSB 5 -#define INES_FLAGS6 6 -#define INES_FLAGS7 7 -#define INES_PRG_CHR_MSB 9 -#define INES_CHR_EXP 8 -#define INES_PRG_EXP 9 - -// Size units -#define PRG_ROM_UNIT 16384 -#define CHR_ROM_UNIT 8192 -#define TRAINER_SIZE 512 - -// Flag masks -#define FLAG6_TRAINER 0x04 -#define FLAG6_FOUR_SCREEN 0x08 -#define FLAG6_VERTICAL_MIRROR 0x01 - -// Mirroring modes -#define MIRROR_HORIZONTAL 0 -#define MIRROR_VERTICAL 1 -#define MIRROR_FOUR_SCREEN 2 - - -static uint8_t *ines2_read_entire_file(const char *path, size_t *out_size) { - FILE *f = fopen(path, "rb"); - if(!f) return 0; - - fseek(f, 0, SEEK_END); - size_t size = ftell(f); - fseek(f, 0, SEEK_SET); - - uint8_t *buffer = (uint8_t *)malloc(size); - size_t read_size = fread(buffer, 1, size, f); - fclose(f); - - if(read_size != size) { - free(buffer); - return 0; - } - - *out_size = size; - return buffer; -} - -uint8_t *ines2_unzip_file_to_memory(const char *zip_path, size_t *out_size) { - struct archive *a = archive_read_new(); - struct archive_entry *entry; - uint8_t *buffer = 0; - size_t size = 0; - - archive_read_support_format_zip(a); - - if(archive_read_open_filename(a, zip_path, 10240) != ARCHIVE_OK) { - fprintf(stderr, "libarchive: failed to open zip: %s\n", archive_error_string(a)); - archive_read_free(a); - return 0; - } - - if(archive_read_next_header(a, &entry) != ARCHIVE_OK) { - fprintf(stderr, "libarchive: no valid file found in zip\n"); - archive_read_free(a); - return 0; - } - - const char *name = archive_entry_pathname(entry); - - size = archive_entry_size(entry); - buffer = (uint8_t*)malloc(size); - if(!buffer) { - fprintf(stderr, "libarchive: malloc failed\n"); - archive_read_free(a); - return 0; - } - - ssize_t read_size = archive_read_data(a, buffer, size); - if(read_size != (ssize_t)size) { - fprintf(stderr, "libarchive: failed to read full file\n"); - free(buffer); - buffer = 0; - } - - - archive_read_free(a); - - if(buffer && out_size) { - *out_size = size; - } - return buffer; -} - -static int ines2_load(struct nes_state *state, const char *path) { - uint8_t *data = 0; - size_t size = 0; - - if(strstr(path, ".zip")) { - data = ines2_unzip_file_to_memory(path, &size); - } else { - data = ines2_read_entire_file(path, &size); - } - - if(!data || size < INES_HEADER_SIZE) { - free(data); - return -1; - } - - uint8_t *ptr = data; - uint8_t *header = ptr; ptr += INES_HEADER_SIZE; - - uint8_t prg_lsb = header[INES_PRG_SIZE_LSB]; - uint8_t chr_lsb = header[INES_CHR_SIZE_LSB]; - uint8_t prg_msb = header[INES_PRG_CHR_MSB] & 0x0f; - uint8_t chr_msb = (header[INES_PRG_CHR_MSB] & 0xf0) >> 4; - - uint32_t prg_size = (prg_msb << 8 | prg_lsb) * PRG_ROM_UNIT; - uint32_t chr_size = (chr_msb << 8 | chr_lsb) * CHR_ROM_UNIT; - - if(prg_lsb == 0x0f) prg_size = 1 << header[INES_PRG_EXP]; - if(chr_lsb == 0x0f) chr_size = 1 << header[INES_CHR_EXP]; - - uint8_t mapper_low = (header[INES_FLAGS6] >> 4); - uint8_t mapper_high = (header[INES_FLAGS7] & 0xf0); - uint8_t mapper_ext = (header[INES_PRG_CHR_MSB] & 0x0f); - uint8_t mapper_upper = header[8] & 0x0f; - uint8_t submapper = (header[8] >> 4); - - state->ines.mapper = mapper_low | mapper_high | (mapper_upper << 8); - state->ines.submapper = submapper; - - if(header[INES_FLAGS6] & FLAG6_FOUR_SCREEN) { - state->ines.mirroring = MIRROR_FOUR_SCREEN; - } else if(header[INES_FLAGS6] & FLAG6_VERTICAL_MIRROR) { - state->ines.mirroring = MIRROR_VERTICAL; - } else { - state->ines.mirroring = MIRROR_HORIZONTAL; - } - - state->ines.prg_size = prg_size; - state->ines.chr_size = chr_size; - - if(header[INES_FLAGS6] & FLAG6_TRAINER) { - ptr += TRAINER_SIZE; - } - - memcpy(state->prg_rom, ptr, prg_size); - ptr += prg_size; - - if(chr_size > 0) { - memcpy(state->chr_rom, ptr, chr_size); - } - - free(data); - return 0; -} - - - |
