summaryrefslogtreecommitdiff
path: root/ines2.c
diff options
context:
space:
mode:
authorPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
committerPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
commit030724a9aea346e4a9843d5842fb28c6d6c4cf1a (patch)
treef06fb84aaef64b2f4e2d81b3d2d3eef71bad83ec /ines2.c
parent412b2ef851516c1de8ba5006ddd284192cbcaf9b (diff)
Rearrangement and refactoring and optimizations and more accuracy
Diffstat (limited to 'ines2.c')
-rw-r--r--ines2.c163
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;
-}
-
-
-