diff options
author | Jari Vetoniemi <mailroxas@gmail.com> | 2017-04-20 16:49:35 +0300 |
---|---|---|
committer | Jari Vetoniemi <mailroxas@gmail.com> | 2017-05-01 22:58:22 +0300 |
commit | 29086b1d12a2c28cffdbfbf0b3990a7bd75506b9 (patch) | |
tree | 8acd48bc30932812744c0adb102d7a7add494357 /src/xi | |
parent | 76b8c9e03c97b16d9ff97f3b79c0ecbff0f5e7f2 (diff) |
work in progress
Diffstat (limited to 'src/xi')
-rw-r--r-- | src/xi/xi2path.c | 16 | ||||
-rw-r--r-- | src/xi/xi2path.h | 35 | ||||
-rw-r--r-- | src/xi/xidec.c | 136 | ||||
-rw-r--r-- | src/xi/xifile.c | 169 | ||||
-rw-r--r-- | src/xi/xils.c | 94 |
5 files changed, 0 insertions, 450 deletions
diff --git a/src/xi/xi2path.c b/src/xi/xi2path.c deleted file mode 100644 index bd9c702..0000000 --- a/src/xi/xi2path.c +++ /dev/null @@ -1,16 +0,0 @@ -#include <stdlib.h> -#include <err.h> - -#include "xi2path.h" - -int -main(int argc, char *argv[]) -{ - if (argc < 2) - errx(EXIT_FAILURE, "usage: %s id\n", argv[0]); - - char path[12]; - xi2path(path, strtol(argv[1], NULL, 10)); - printf("%s\n", path); - return EXIT_SUCCESS; -} diff --git a/src/xi/xi2path.h b/src/xi/xi2path.h deleted file mode 100644 index 954c554..0000000 --- a/src/xi/xi2path.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <stdio.h> -#include <assert.h> -#include <stdint.h> - -static inline void -xi2path(char out[12], const uint16_t id) -{ - // Forms path like: section/id.DAT, from 16bit id. - // First 7 bits are used for DAT and rest of the bits for ROM section. - // - // e.g. ID of 1000 would look like 11101000 00000011 in binary. - // RDDDDDDD RRRRRRRR - // - // In the above graph, 'R' bits form the ROM section (7) and 'D' bits form the DAT (104). - // Thus maximum DAT and ROM section IDs are 127 and 511 respectively (65535 as decimal). - - snprintf(out, 12, "%u/%u.DAT", id >> 7, id & 0x7F); -} - -static inline void -xi2rompath(char out[18], const uint8_t rom, const uint16_t id) -{ - assert(rom <= 9); - - char path[12]; - xi2path(path, id); - - if (rom > 1) { - snprintf(out, 18, "ROM%u/%s", rom, path); - } else { - snprintf(out, 18, "ROM/%s", path); - } -} diff --git a/src/xi/xidec.c b/src/xi/xidec.c deleted file mode 100644 index 3df917f..0000000 --- a/src/xi/xidec.c +++ /dev/null @@ -1,136 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> -#include <string.h> -#include <assert.h> -#include <err.h> - -static uint8_t -rotate_right(uint8_t b, const uint8_t count) -{ - for (size_t i = 0; i < count; ++i) { - const bool drop = ((b & 0x01) == 0x01); - b = (b >> 1) | (drop ? 0x80 : 0); - } - return b; -} - -static void -decode(uint8_t *data, const size_t size, const uint8_t count) -{ - assert(data); - - for (size_t i = 0; i < size; ++i) - data[i] = rotate_right(data[i], count); -} - -static size_t -count_bits(const uint8_t byte) -{ - static const uint8_t lut[16] = { - 0, 1, 1, 2, 1, 2, 2, 3, - 1, 2, 2, 3, 2, 3, 3, 4 - }; - - return lut[byte & 0x0F] + lut[byte >> 4]; -} - -static uint8_t -text_rotation(const uint8_t *data, const size_t size) -{ - assert(data); - - if (size < 2 || (data[0] == 0 && data[1] == 0)) - return 0; - - const int seed = count_bits(data[1]) - count_bits(data[0]); - switch (abs(seed) % 5) { - case 0: return 1; - case 1: return 7; - case 2: return 2; - case 3: return 6; - case 4: return 3; - default:break; - } - - assert(0 && "failed to detect rotation"); - return 0; -} - -static uint8_t -other_rotation(const uint8_t *data, const size_t size) -{ - assert(data); - - if (size < 13) - return 0; - - const int seed = count_bits(data[2]) - count_bits(data[11]) + count_bits(data[12]); - switch (abs(seed) % 5) { - case 0: return 7; - case 1: return 1; - case 2: return 6; - case 3: return 2; - case 4: return 5; - default:break; - } - - assert(0 && "failed to detect rotation"); - return 0; -} - -static uint8_t -item_rotation(const uint8_t *data, const size_t size) -{ - assert(data); - (void)data, (void)size; - return 5; -} - -int -main(int argc, char *argv[]) -{ - if (argc < 2) - errx(EXIT_FAILURE, "usage: %s (name | ability | spell | item | text) < data\n", argv[0]); - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - - const struct info { - const char *name; - size_t chunk; - uint8_t (*rotation)(const uint8_t *data, const size_t size); - } map[] = { - { .name = "name", .chunk = 32 }, - { .name = "ability", .chunk = 1024, .rotation = other_rotation }, - { .name = "spell", .chunk = 1024, .rotation = other_rotation }, - { .name = "item", .chunk = 3072, .rotation = item_rotation }, - { .name = "text", .chunk = 255, .rotation = text_rotation }, - }; - - const struct info *info = NULL; - for (size_t i = 0; i < ARRAY_SIZE(map); ++i) { - if (strcmp(map[i].name, argv[1])) - continue; - - info = &map[i]; - break; - } - - if (!info) - errx(EXIT_FAILURE, "unknown file type '%s'", argv[1]); - - uint8_t buf[4096]; - assert(sizeof(buf) >= info->chunk); - - size_t bytes; - while ((bytes = fread(buf, 1, info->chunk, stdin)) > 0) { - if (info->rotation) - decode(buf, bytes, info->rotation(buf, bytes)); - - fwrite(buf, 1, bytes, stdout); - } - - return EXIT_SUCCESS; -} diff --git a/src/xi/xifile.c b/src/xi/xifile.c deleted file mode 100644 index f1b2111..0000000 --- a/src/xi/xifile.c +++ /dev/null @@ -1,169 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <ctype.h> -#include <assert.h> -#include <err.h> - -static const char *stdin_name = "/dev/stdin"; - -static FILE* -fopen_or_die(const char *path, const char *mode) -{ - assert(path && mode); - - FILE *f; - if (!(f = fopen(path, mode))) - err(EXIT_FAILURE, "fopen(%s, %s)", path, mode); - - return f; -} - -static void -detect(const char *path) -{ - assert(path); - - uint8_t buf[32] = {0}; - const char *name = (!strcmp(path, "-") ? stdin_name : path); - FILE *f = (name == stdin_name ? stdin : fopen_or_die(name, "rb")); - fread(buf, 1, sizeof(buf), f); - - const struct info { - const char *name; - const uint8_t *header; - size_t chunk; - } map[] = { -#define HDR(...) .header = (const uint8_t[]){__VA_ARGS__}, .chunk = sizeof((const uint8_t[]){__VA_ARGS__}) - { - .name = "BGMStream", - HDR('B', 'G', 'M', 'S', 't', 'r', 'e', 'a', 'm') - }, { - .name = "SeWave", - HDR('S', 'e', 'W', 'a', 'v', 'e') - }, { - .name = "PMUS", - HDR('P', 'M', 'U', 'S') - }, { - .name = "RIFF/WAVE", - HDR('R', 'I', 'F', 'F', 0x24, 0xB3, 0xCF, 0x04, 'W', 'A', 'V', 'E', 'f', 'm', 't') - }, { - .name = "RIFF/ACON", - HDR('R', 'I', 'F', 'F', 0x58, 0x23, 0, 0, 'A', 'C', 'O', 'N', 'a', 'n', 'i', 'h') - }, { - .name = "name", - HDR('n', 'o', 'n', 'e', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - }, { - .name = "syst", - HDR('s', 'y', 's', 't') - }, { - .name = "menu", - HDR('m', 'e', 'n', 'u') - }, { - .name = "lobb", - HDR('l', 'o', 'b', 'b') - }, { - .name = "wave", - HDR('w', 'a', 'v', 'e') - }, { - .name = "ability", - HDR(0, 0, 0, 0x17, 0, 0, 0, 0, 0x80) - }, { - .name = "spell", - HDR(0, 0, 0, 0, 0x03, 0, 0x9F, 0, 0x10) - }, { - .name = "mgc_", - HDR('m', 'g', 'c', '_') - }, { - .name = "win0", - HDR('w', 'i', 'n', '0') - }, { - .name = "titl", - HDR('t', 'i', 't', 'l') - }, { - .name = "sel_", - HDR('s', 'e', 'l', '_') - }, { - .name = "damv", - HDR('d', 'a', 'm', 'v') - }, { - .name = "XISTRING", - HDR('X', 'I', 'S', 'T', 'R', 'I', 'N', 'G') - }, { - .name = "prvd", - HDR('p', 'r', 'v', 'd') - }, { - .name = "selp", - HDR('s', 'e', 'l', 'p') - }, { - .name = "dun", - HDR('d', 'u', 'n') - }, { - .name = "town", - HDR('t', 'o', 'w', 'n') - }, { - .name = "dese", - HDR('d', 'e', 's', 'e') - }, { - .name = "fore", - HDR('f', 'o', 'r', 'e') - }, { - .name = "tree", - HDR('t', 'r', 'e', 'e') - }, { - .name = "unka", - HDR('u', 'n', 'k', 'a') - }, { - .name = "moun", - HDR('m', 'o', 'u', 'n') - }, { - .name = "cast", - HDR('c', 'a', 's', 't') - }, { - .name = "fuji", - HDR('f', 'u', 'j', 'i') - }, { - .name = "view", - HDR('v', 'i', 'e', 'w') - } -#undef HDR - }; - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - - const struct info *info = NULL; - for (size_t i = 0; i < ARRAY_SIZE(map); ++i) { - assert(map[i].chunk <= sizeof(buf)); - if (memcmp(buf, map[i].header, map[i].chunk)) - continue; - - info = &map[i]; - break; - } - - if (info) { - printf("%s: %s\n", name, info->name); - } else { - int i; - for (i = 0; i < 32 && isprint(buf[i]); ++i); - if (i > 0) { - printf("%s: unknown (%.*s)\n", name, i, buf); - } else { - printf("%s: unknown\n", name); - } - } - fclose(f); -} - -int -main(int argc, char *argv[]) -{ - if (argc < 2) - errx(EXIT_FAILURE, "usage: %s file\n", argv[0]); - - for (int i = 1; i < argc; ++i) - detect(argv[i]); - - return EXIT_SUCCESS; -} diff --git a/src/xi/xils.c b/src/xi/xils.c deleted file mode 100644 index 9c9a75e..0000000 --- a/src/xi/xils.c +++ /dev/null @@ -1,94 +0,0 @@ -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <assert.h> -#include <err.h> - -#include "xi2path.h" - -static FILE* -fopen_or_die(const char *gamedir, const char *file, const char *mode) -{ - assert(gamedir && file && mode); - - char path[4096]; - snprintf(path, sizeof(path), "%s/%s", gamedir, file); - - FILE *f; - if (!(f = fopen(path, mode))) - err(EXIT_FAILURE, "fopen(%s, %s)", path, mode); - - return f; -} - -static void -dump_tables(const char *dir, const char *names[2], const uint8_t rom, const bool print_all, const bool verbose) -{ - assert(dir && names); - - // FTABLE.DAT contains list of IDs. - // VTABLE.DAT contains number of ROM for each entry or 0 if the entry is not used. - FILE *f = fopen_or_die(dir, names[0], "rb"); - FILE *v = fopen_or_die(dir, names[1], "rb"); - -#define ELEM_SIZE(x) (sizeof(x[0])) -#define ARRAY_SIZE(x) (sizeof(x) / ELEM_SIZE(x)) - - { - size_t read[2]; - uint16_t id[255]; - uint8_t exist[255]; - while ((read[0] = fread(id, ELEM_SIZE(id), ARRAY_SIZE(id), f)) > 0 && - (read[1] = fread(exist, ELEM_SIZE(exist), ARRAY_SIZE(exist), v)) > 0) { - assert(read[0] == read[1]); - - for (size_t i = 0; i < read[0]; ++i) { - if (!print_all && !exist[i]) - continue; - - if (verbose) - printf("%u: ", exist[i]); - - char path[18]; - xi2rompath(path, rom, id[i]); - printf("%s\n", path); - } - } - } - - fclose(v); - fclose(f); -} - -int -main(int argc, char *argv[]) -{ - bool verbose = false; - bool print_all = false; - const char *gamedir = NULL; - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "-a")) { - print_all = true; - } else if (!strcmp(argv[i], "-v")) { - verbose = true; - } else { - gamedir = argv[i]; - break; - } - } - - if (!gamedir) - errx(EXIT_FAILURE, "usage: %s [-a|-v] gamedir\n", argv[0]); - - dump_tables(gamedir, (const char*[]){ "FTABLE.DAT", "VTABLE.DAT" }, 1, print_all, verbose); - - for (uint8_t i = 2; i <= 9; ++i) { - char dir[4096], f[12], v[12]; - snprintf(dir, sizeof(dir), "%s/ROM%u", gamedir, i); - snprintf(f, sizeof(f), "FTABLE%u.DAT", i); - snprintf(v, sizeof(v), "VTABLE%u.DAT", i); - dump_tables(dir, (const char*[]){ f, v }, i, print_all, verbose); - } - - return EXIT_SUCCESS; -} |