From 97d1c4246e167ab493175d890409c4154628760c Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 22 May 2021 23:17:50 +0200 Subject: Include bin2carr on the tools directory --- Makefile | 7 +- src/common.h | 1 - tools/bin2carr/Makefile | 47 +++++++++ tools/bin2carr/src/main.c | 232 +++++++++++++++++++++++++++++++++++++++++ tools/bin2carr/src/shorthand.h | 35 +++++++ 5 files changed, 319 insertions(+), 3 deletions(-) create mode 100644 tools/bin2carr/Makefile create mode 100644 tools/bin2carr/src/main.c create mode 100644 tools/bin2carr/src/shorthand.h diff --git a/Makefile b/Makefile index 89f64a2..d91466d 100644 --- a/Makefile +++ b/Makefile @@ -52,10 +52,10 @@ else CFLAGS += $(RELEASE_CFLAGS) endif -main: $(BUILD_DIR) $(ROM) $(BIN) +main: tools $(BUILD_DIR) $(ROM) $(BIN) $(ROM): - ../tools/bin2carr/build/bin2carr $(ROM_SRC) \ + ./tools/bin2carr/build/bin2carr $(ROM_SRC) \ -n uxn_rom \ -e u16 \ -o $(ROM) @@ -81,3 +81,6 @@ run: main clean: rm $(ROM) rm -r $(BUILD_DIR) + +tools: + make -C tools/bin2carr diff --git a/src/common.h b/src/common.h index 08736ea..5d3f497 100644 --- a/src/common.h +++ b/src/common.h @@ -653,7 +653,6 @@ sound_volume(SoundChannel channels, u8 volume) { typedef u8 WaveBank[32]; -// typedef u32 WaveBank[4]; #define SOUND_WAVE_RAM ((WaveBank*)(MEM_IO + 0x90)) typedef enum { diff --git a/tools/bin2carr/Makefile b/tools/bin2carr/Makefile new file mode 100644 index 0000000..a9ff816 --- /dev/null +++ b/tools/bin2carr/Makefile @@ -0,0 +1,47 @@ +.POSIX: +.SUFFIXES: + +# Source code location and files to watch for changes. +SRC_DIR := src +SRC_MAIN := $(SRC_DIR)/main.c +WATCH_SRC := $(wildcard $(SRC_DIR)/*.c) +WATCH_SRC += $(wildcard $(SRC_DIR)/*.h) + +# Output library names and executables. +BIN_NAME := bin2carr +BUILD_DIR := build +BIN := $(BUILD_DIR)/$(BIN_NAME) + +# Compiler and linker configuration. +CC := gcc +CFLAGS := -Wall -Wextra -pedantic -std=c99 -DBIN_NAME=\"$(BIN_NAME)\" +LDFLAGS := -lm +LDLIBS := +RELEASE_CFLAGS := -DNDEBUG -O2 +DEBUG_CFLAGS := -DDEBUG -g + +.PHONY: static clean run + +# Setup debug/release builds. +# make clean && make DEBUG=0 +# make clean && make DEBUG=1 +DEBUG ?= 0 +ifeq ($(DEBUG), 1) + CFLAGS += $(DEBUG_CFLAGS) +else + CFLAGS += $(RELEASE_CFLAGS) +endif + +static: $(BUILD_DIR) $(BIN) + +$(BIN): $(SRC_MAIN) $(WATCH_SRC) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $(SRC_MAIN) $(LDLIBS) + +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + +run: $(BIN) + exec $(BIN) + +clean: + rm -r $(BUILD_DIR) diff --git a/tools/bin2carr/src/main.c b/tools/bin2carr/src/main.c new file mode 100644 index 0000000..699db61 --- /dev/null +++ b/tools/bin2carr/src/main.c @@ -0,0 +1,232 @@ +#include +#include +#include +#include + +#include "shorthand.h" + +typedef enum { + ELEM_U8, ELEM_S8, ELEM_U16, ELEM_S16, + ELEM_U32, ELEM_S32, ELEM_U64, ELEM_S64, +} ElemSize; + +void +write_array(FILE *file_in, FILE *file_out, char *arr_name, ElemSize elem_size) { + char *arr_type; + size_t n_elem = 0; + switch (elem_size) { + case ELEM_U8: + arr_type = "u8"; + n_elem = 8; + break; + case ELEM_S8: + arr_type = "s8"; + n_elem = 8; + break; + case ELEM_U16: + arr_type = "u16"; + n_elem = 8; + break; + case ELEM_S16: + arr_type = "s16"; + n_elem = 8; + break; + case ELEM_U32: + arr_type = "u32"; + n_elem = 4; + break; + case ELEM_S32: + arr_type = "s32"; + n_elem = 4; + break; + case ELEM_U64: + arr_type = "u64"; + n_elem = 4; + break; + case ELEM_S64: + arr_type = "s64"; + n_elem = 4; + break; + default: + arr_type = "u8"; + n_elem = 8; + break; + } + fprintf(file_out, "const %s %s[] = {\n", arr_type, arr_name); + size_t n_read = 0; + size_t counter = 0; + do { + if (counter == 0) { + fprintf(file_out, " "); + } + switch (elem_size) { + case ELEM_U8: + case ELEM_S8: { + u8 elem; + n_read = fread(&elem, sizeof(u8), 1, file_in); + fprintf(file_out, "0x%02x,", elem); + break; + } + case ELEM_U16: + case ELEM_S16: { + u16 elem; + n_read = fread(&elem, sizeof(u16), 1, file_in); + fprintf(file_out, "0x%04x,", elem); + break; + } + case ELEM_U32: + case ELEM_S32: { + u32 elem; + n_read = fread(&elem, sizeof(u32), 1, file_in); + fprintf(file_out, "0x%08x,", elem); + break; + } + case ELEM_U64: + case ELEM_S64: { + u64 elem; + n_read = fread(&elem, sizeof(u64), 1, file_in); + fprintf(file_out, "0x%016lx,", elem); + break; + } + } + + if (counter == n_elem - 1) { + fprintf(file_out, "\n"); + counter = 0; + } else { + fprintf(file_out, " "); + counter++; + } + } while(n_read != 0); + if (counter != 0) { + fseek(file_out, -1, SEEK_CUR); + fprintf(file_out, "\n"); + } + fprintf(file_out, "};\n"); +} + +void +print_usage(void) { + printf("Usage: %s [options] \n", BIN_NAME); + printf("\n"); + printf("\t-e \tSize of array elements.\n"); + printf("\t-n \tName of the output array.\n"); + printf("\t-o \tPath to the output file. If blank, stdout will be used.\n"); + printf("\n"); +} + +int +main(int argc, char *argv[]) { + // Initialize default parameters. + char *in_file_path = NULL; + char *out_file_path = NULL; + char arr_name[256] = {0}; + ElemSize elem_size = ELEM_U8; + + // Process options. + int option; + while ((option = getopt(argc, argv, "e:n:o:")) != -1) { + switch (option) { + case 'e': { + // Element size. + char *size = optarg; + if (strcmp(size, "u8") == 0) { + elem_size = ELEM_U8; + } else if (strcmp(size, "s8") == 0) { + elem_size = ELEM_S8; + } else if (strcmp(size, "u16") == 0) { + elem_size = ELEM_U16; + } else if (strcmp(size, "s16") == 0) { + elem_size = ELEM_S16; + } else if (strcmp(size, "u32") == 0) { + elem_size = ELEM_U32; + } else if (strcmp(size, "s32") == 0) { + elem_size = ELEM_S32; + } else if (strcmp(size, "u64") == 0) { + elem_size = ELEM_U64; + } else if (strcmp(size, "s64") == 0) { + elem_size = ELEM_S64; + } + } break; + case 'n': { + // Array name. + char *ptr = optarg; + size_t k = 0; + while(*ptr) { + switch (*ptr) { + case '.': + case '/': + case '-': + case '\\': + ptr++; + break; + default: { + arr_name[k++] = *ptr++; + } break; + } + } + } break; + case 'o': { + // Output file. + out_file_path = optarg; + } break; + default: { + print_usage(); + return EXIT_FAILURE; + } break; + } + } + + // Get the path to the file to be exported. + if (optind != argc - 1) { + fprintf(stderr, "%s: No input file given.\n", BIN_NAME); + print_usage(); + return EXIT_FAILURE; + } + in_file_path = argv[optind]; + + // Check if there is a default array name. + if (arr_name[0] == '\0') { + char *ptr = in_file_path; + size_t k = 0; + while(*ptr) { + switch (*ptr) { + case '.': + case '/': + case '-': + case '\\': + ptr++; + break; + default: { + arr_name[k++] = *ptr++; + } break; + } + } + } + + // Try to open input file. + FILE *file_in = fopen(in_file_path, "r"); + if (file_in == NULL) { + fprintf(stderr, "%s: can't open input file: %s\n", BIN_NAME, + in_file_path); + return EXIT_FAILURE; + } + + // Write output to file. + if (out_file_path == NULL) { + write_array(file_in, stdout, arr_name, elem_size); + } else { + FILE *file_out = fopen(out_file_path, "w"); + if (!file_out) { + fprintf(stderr, "%s: can't open output file: %s\n", BIN_NAME, out_file_path); + fclose(file_in); + return EXIT_FAILURE; + } + write_array(file_in, file_out, arr_name, elem_size); + fclose(file_out); + } + + // Cleanup. + fclose(file_in); + return EXIT_SUCCESS; +} diff --git a/tools/bin2carr/src/shorthand.h b/tools/bin2carr/src/shorthand.h new file mode 100644 index 0000000..9c2e2f0 --- /dev/null +++ b/tools/bin2carr/src/shorthand.h @@ -0,0 +1,35 @@ +#ifndef MIC_SHORTHAND_H +#define MIC_SHORTHAND_H + +#include +#include +#include +#include + +// +// This simple header just typedefs the basic C define types to a shorter name, +// loads the quality of life bool macro for _Bool and defines shorthand macros +// for byte sizes. We need that the targeted architecture uses the floating +// point representation as described on the IEEE-754 standard. +// + +_Static_assert(sizeof(double) == 8, "no support for IEEE-754"); +_Static_assert(sizeof(float) == 4, "no support for IEEE-754"); + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; +typedef float f32; +typedef double f64; + +#define KB(N) ((u64)(N) * 1024) +#define MB(N) ((u64)KB(N) * 1024) +#define GB(N) ((u64)MB(N) * 1024) +#define TB(N) ((u64)GB(N) * 1024) + +#endif // MIC_SHORTHAND_H -- cgit v1.2.1