summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-20 09:57:19 +0200
committerBad Diode <bd@badd10de.dev>2021-05-20 09:57:19 +0200
commitc118943822514fee30084958a24a7d45a9016f46 (patch)
tree72043a60f41b00eac8c17d92c22b7b51e2b1cf28
parentba0fca599c1a06a0fc0f1d7089a1532be7f6454a (diff)
downloadgba-dev-tools-c118943822514fee30084958a24a7d45a9016f46.tar.gz
gba-dev-tools-c118943822514fee30084958a24a7d45a9016f46.zip
Add bin2carr tool
-rw-r--r--.gitignore1
-rw-r--r--bin2carr/Makefile47
-rw-r--r--bin2carr/src/main.c223
-rw-r--r--bin2carr/src/shorthand.h (renamed from src/shorthand.h)0
-rw-r--r--sprite2gba/Makefile (renamed from Makefile)0
-rw-r--r--sprite2gba/src/main.c (renamed from src/main.c)0
-rw-r--r--sprite2gba/src/shorthand.h35
-rw-r--r--sprite2gba/src/stb_image.h (renamed from src/stb_image.h)0
8 files changed, 306 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 567609b..598f739 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
1build/ 1build/
2**/build/
diff --git a/bin2carr/Makefile b/bin2carr/Makefile
new file mode 100644
index 0000000..a9ff816
--- /dev/null
+++ b/bin2carr/Makefile
@@ -0,0 +1,47 @@
1.POSIX:
2.SUFFIXES:
3
4# Source code location and files to watch for changes.
5SRC_DIR := src
6SRC_MAIN := $(SRC_DIR)/main.c
7WATCH_SRC := $(wildcard $(SRC_DIR)/*.c)
8WATCH_SRC += $(wildcard $(SRC_DIR)/*.h)
9
10# Output library names and executables.
11BIN_NAME := bin2carr
12BUILD_DIR := build
13BIN := $(BUILD_DIR)/$(BIN_NAME)
14
15# Compiler and linker configuration.
16CC := gcc
17CFLAGS := -Wall -Wextra -pedantic -std=c99 -DBIN_NAME=\"$(BIN_NAME)\"
18LDFLAGS := -lm
19LDLIBS :=
20RELEASE_CFLAGS := -DNDEBUG -O2
21DEBUG_CFLAGS := -DDEBUG -g
22
23.PHONY: static clean run
24
25# Setup debug/release builds.
26# make clean && make <target> DEBUG=0
27# make clean && make <target> DEBUG=1
28DEBUG ?= 0
29ifeq ($(DEBUG), 1)
30 CFLAGS += $(DEBUG_CFLAGS)
31else
32 CFLAGS += $(RELEASE_CFLAGS)
33endif
34
35static: $(BUILD_DIR) $(BIN)
36
37$(BIN): $(SRC_MAIN) $(WATCH_SRC)
38 $(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $(SRC_MAIN) $(LDLIBS)
39
40$(BUILD_DIR):
41 mkdir -p $(BUILD_DIR)
42
43run: $(BIN)
44 exec $(BIN)
45
46clean:
47 rm -r $(BUILD_DIR)
diff --git a/bin2carr/src/main.c b/bin2carr/src/main.c
new file mode 100644
index 0000000..f2d0569
--- /dev/null
+++ b/bin2carr/src/main.c
@@ -0,0 +1,223 @@
1#include <getopt.h>
2#include <stdio.h>
3#include <stdlib.h>
4
5#include "shorthand.h"
6
7typedef enum {
8 ELEM_U8, ELEM_S8, ELEM_U16, ELEM_S16,
9 ELEM_U32, ELEM_S32, ELEM_U64, ELEM_S64,
10} ElemSize;
11
12void
13write_array(FILE *file_in, FILE *file_out, char *arr_name, ElemSize elem_size) {
14 char *arr_type;
15 size_t n_elem = 0;
16 switch (elem_size) {
17 case ELEM_U8:
18 arr_type = "u8";
19 n_elem = 8;
20 break;
21 case ELEM_S8:
22 arr_type = "s8";
23 n_elem = 8;
24 break;
25 case ELEM_U16:
26 arr_type = "u16";
27 n_elem = 8;
28 break;
29 case ELEM_S16:
30 arr_type = "s16";
31 n_elem = 8;
32 break;
33 case ELEM_U32:
34 arr_type = "u32";
35 n_elem = 4;
36 break;
37 case ELEM_S32:
38 arr_type = "s32";
39 n_elem = 4;
40 break;
41 case ELEM_U64:
42 arr_type = "u64";
43 n_elem = 4;
44 break;
45 case ELEM_S64:
46 arr_type = "s64";
47 n_elem = 4;
48 break;
49 }
50 fprintf(file_out, "%s %s[] = {\n", arr_type, arr_name);
51 size_t n_read = 0;
52 size_t counter = 0;
53 do {
54 if (counter == 0) {
55 fprintf(file_out, " ");
56 }
57 switch (elem_size) {
58 case ELEM_U8:
59 case ELEM_S8: {
60 u8 elem;
61 n_read = fread(&elem, sizeof(u8), 1, file_in);
62 fprintf(file_out, "0x%02x,", elem);
63 break;
64 }
65 case ELEM_U16:
66 case ELEM_S16: {
67 u16 elem;
68 n_read = fread(&elem, sizeof(u16), 1, file_in);
69 fprintf(file_out, "0x%04x,", elem);
70 break;
71 }
72 case ELEM_U32:
73 case ELEM_S32: {
74 u32 elem;
75 n_read = fread(&elem, sizeof(u32), 1, file_in);
76 fprintf(file_out, "0x%08x,", elem);
77 break;
78 }
79 case ELEM_U64:
80 case ELEM_S64: {
81 u64 elem;
82 n_read = fread(&elem, sizeof(u64), 1, file_in);
83 fprintf(file_out, "0x%016lx,", elem);
84 break;
85 }
86 }
87
88 if (counter == n_elem - 1) {
89 fprintf(file_out, "\n");
90 counter = 0;
91 } else {
92 fprintf(file_out, " ");
93 counter++;
94 }
95 } while(n_read != 0);
96 fprintf(file_out, "};\n");
97}
98
99void
100print_usage(void) {
101 printf("Usage: %s [options] <filename>\n", BIN_NAME);
102 printf("\n");
103 printf("\t-e <u16>\tSize of array elements.\n");
104 printf("\t-n <arr_name>\tName of the output array.\n");
105 printf("\t-o <out_file.c>\tPath to the output file. If blank, stdout will be used.\n");
106 printf("\n");
107}
108
109int
110main(int argc, char *argv[]) {
111 // Initialize default parameters.
112 char *in_file_path = NULL;
113 char *out_file_path = NULL;
114 char arr_name[256] = {0};
115 ElemSize elem_size = ELEM_U8;
116
117 // Process options.
118 int option;
119 while ((option = getopt(argc, argv, "e:n:o:")) != -1) {
120 switch (option) {
121 case 'e': {
122 // Element size.
123 char *size = optarg;
124 if (strcmp(size, "u8") == 0) {
125 elem_size = ELEM_U8;
126 } else if (strcmp(size, "s8") == 0) {
127 elem_size = ELEM_S8;
128 } else if (strcmp(size, "u16") == 0) {
129 elem_size = ELEM_U16;
130 } else if (strcmp(size, "s16") == 0) {
131 elem_size = ELEM_S16;
132 } else if (strcmp(size, "u32") == 0) {
133 elem_size = ELEM_U32;
134 } else if (strcmp(size, "s32") == 0) {
135 elem_size = ELEM_S32;
136 } else if (strcmp(size, "u64") == 0) {
137 elem_size = ELEM_U64;
138 } else if (strcmp(size, "s64") == 0) {
139 elem_size = ELEM_S64;
140 }
141 } break;
142 case 'n': {
143 // Array name.
144 char *ptr = optarg;
145 size_t k = 0;
146 while(*ptr) {
147 switch (*ptr) {
148 case '.':
149 case '/':
150 case '-':
151 case '\\':
152 ptr++;
153 break;
154 default: {
155 arr_name[k++] = *ptr++;
156 } break;
157 }
158 }
159 } break;
160 case 'o': {
161 // Output file.
162 out_file_path = optarg;
163 } break;
164 default: {
165 print_usage();
166 return EXIT_FAILURE;
167 } break;
168 }
169 }
170
171 // Get the path to the file to be exported.
172 if (optind != argc - 1) {
173 fprintf(stderr, "%s: No input file given.\n", BIN_NAME);
174 print_usage();
175 return EXIT_FAILURE;
176 }
177 in_file_path = argv[optind];
178
179 // Check if there is a default array name.
180 if (arr_name[0] == '\0') {
181 char *ptr = in_file_path;
182 size_t k = 0;
183 while(*ptr) {
184 switch (*ptr) {
185 case '.':
186 case '/':
187 case '-':
188 case '\\':
189 ptr++;
190 break;
191 default: {
192 arr_name[k++] = *ptr++;
193 } break;
194 }
195 }
196 }
197
198 // Try to open input file.
199 FILE *file_in = fopen(in_file_path, "r");
200 if (file_in == NULL) {
201 fprintf(stderr, "%s: can't open input file: %s\n", BIN_NAME,
202 in_file_path);
203 return EXIT_FAILURE;
204 }
205
206 // Write output to file.
207 if (out_file_path == NULL) {
208 write_array(file_in, stdout, arr_name, elem_size);
209 } else {
210 FILE *file_out = fopen(out_file_path, "w");
211 if (!file_out) {
212 fprintf(stderr, "%s: can't open output file: %s\n", BIN_NAME, out_file_path);
213 fclose(file_in);
214 return EXIT_FAILURE;
215 }
216 write_array(file_in, file_out, arr_name, elem_size);
217 fclose(file_out);
218 }
219
220 // Cleanup.
221 fclose(file_in);
222 return EXIT_SUCCESS;
223}
diff --git a/src/shorthand.h b/bin2carr/src/shorthand.h
index 9c2e2f0..9c2e2f0 100644
--- a/src/shorthand.h
+++ b/bin2carr/src/shorthand.h
diff --git a/Makefile b/sprite2gba/Makefile
index 0d6dc07..0d6dc07 100644
--- a/Makefile
+++ b/sprite2gba/Makefile
diff --git a/src/main.c b/sprite2gba/src/main.c
index f91ecd0..f91ecd0 100644
--- a/src/main.c
+++ b/sprite2gba/src/main.c
diff --git a/sprite2gba/src/shorthand.h b/sprite2gba/src/shorthand.h
new file mode 100644
index 0000000..9c2e2f0
--- /dev/null
+++ b/sprite2gba/src/shorthand.h
@@ -0,0 +1,35 @@
1#ifndef MIC_SHORTHAND_H
2#define MIC_SHORTHAND_H
3
4#include <assert.h>
5#include <stdbool.h>
6#include <stddef.h>
7#include <stdint.h>
8
9//
10// This simple header just typedefs the basic C define types to a shorter name,
11// loads the quality of life bool macro for _Bool and defines shorthand macros
12// for byte sizes. We need that the targeted architecture uses the floating
13// point representation as described on the IEEE-754 standard.
14//
15
16_Static_assert(sizeof(double) == 8, "no support for IEEE-754");
17_Static_assert(sizeof(float) == 4, "no support for IEEE-754");
18
19typedef uint8_t u8;
20typedef uint16_t u16;
21typedef uint32_t u32;
22typedef uint64_t u64;
23typedef int8_t s8;
24typedef int16_t s16;
25typedef int32_t s32;
26typedef int64_t s64;
27typedef float f32;
28typedef double f64;
29
30#define KB(N) ((u64)(N) * 1024)
31#define MB(N) ((u64)KB(N) * 1024)
32#define GB(N) ((u64)MB(N) * 1024)
33#define TB(N) ((u64)GB(N) * 1024)
34
35#endif // MIC_SHORTHAND_H
diff --git a/src/stb_image.h b/sprite2gba/src/stb_image.h
index accef48..accef48 100644
--- a/src/stb_image.h
+++ b/sprite2gba/src/stb_image.h