commit 832771c343663cb1fc025c5ae6879b9cbe3e9d1b
parent 1a90e43cf4c4a6578c2888a7a023d88ce82261a6
Author: MikoĊaj Lenczewski <mblenczewski@gmail.com>
Date: Sun, 12 Feb 2023 17:40:18 +0000
Add initial dump functionality for testing brzeszczot
Diffstat:
2 files changed, 189 insertions(+), 4 deletions(-)
diff --git a/brzeszczot/include/brzeszczot.h b/brzeszczot/include/brzeszczot.h
@@ -4,5 +4,9 @@
#include "common.h"
#include "libriot.h"
+#include "libriot/wad.h"
+#include "libriot/inibin.h"
+
+#include <unistd.h>
#endif /* BRZESZCZOT_H */
diff --git a/brzeszczot/src/brzeszczot.c b/brzeszczot/src/brzeszczot.c
@@ -1,11 +1,192 @@
#include "brzeszczot.h"
+#include "brzeszczot/argparse.h"
+
+static inline u64
+read_file(char const *fp, u8 **out) {
+ FILE *f = fopen(fp, "rb");
+ if (!f) return 0;
+
+ u64 len;
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ u8 *buf = malloc(len);
+ if (!buf) { fclose(f); return 0; }
+
+ int fd = fileno(f);
+
+ u64 total_read = 0;
+ do {
+ u64 curr = read(fd, buf + total_read, len - total_read);
+ if (!curr) { free(buf); fclose(f); return 0; }
+
+ total_read += curr;
+ } while (total_read < len);
+
+ fclose(f);
+
+ *out = buf;
+
+ return total_read;
+}
+
+static inline u64
+write_file(char const *fp, u64 len, u8 *buf) {
+ FILE *f = fopen(fp, "wb");
+ if (!f) return 0;
+
+ int fd = fileno(f);
+
+ u64 total_written = 0;
+ do {
+ u64 curr = write(fd, buf + total_written, len - total_written);
+ if (!curr) { fclose(f); return total_written; }
+
+ total_written += curr;
+ } while (total_written < len);
+
+ fclose(f);
+
+ return total_written;
+}
+
+static s32
+wad_dump(struct opts *opts) {
+ assert(opts);
+
+ u8 *filebuf;
+ u64 filelen = read_file(opts->src, &filebuf);
+ if (!filelen) {
+ errlog("Failed to read source file: %s", opts->src);
+ return 1;
+ }
+
+ struct mem_stream in = {
+ .ptr = filebuf,
+ .len = filelen,
+ .cur = 0,
+ };
+
+ struct riot_wad_ctx wadctx;
+ if (!riot_wad_ctx_init(&wadctx)) {
+ errlog("Failed to initialise WAD context");
+ free(filebuf);
+ return 1;
+ }
+
+ if (!riot_wad_read(&wadctx, in)) {
+ errlog("Failed to read WAD file");
+ riot_wad_ctx_free(&wadctx);
+ free(filebuf);
+ return 1;
+ }
+
+ riot_wad_print(&wadctx, stdout);
+
+ struct mem_stream out = {
+ .ptr = filebuf,
+ .len = filelen,
+ .cur = 0,
+ };
+
+ if (!riot_wad_write(&wadctx, out)) {
+ errlog("Failed to write WAD file");
+ riot_wad_ctx_free(&wadctx);
+ free(filebuf);
+ return 1;
+ }
+
+ riot_wad_ctx_free(&wadctx);
+
+ u64 written = write_file(opts->dst, filelen, filebuf);
+ if (!written || written < filelen) {
+ errlog("Failed to write destination file: %s", opts->dst);
+ free(filebuf);
+ return 1;
+ }
+
+ free(filebuf);
+
+ return 0;
+}
+
+static s32
+inibin_dump(struct opts *opts) {
+ assert(opts);
+
+ u8 *filebuf;
+ u64 filelen = read_file(opts->src, &filebuf);
+ if (!filelen) {
+ errlog("Failed to read source file: %s", opts->src);
+ return 1;
+ }
+
+ struct mem_stream in = {
+ .ptr = filebuf,
+ .len = filelen,
+ .cur = 0,
+ };
+
+ struct riot_inibin_ctx inibinctx;
+ if (!riot_inibin_ctx_init(&inibinctx)) {
+ errlog("Failed to initialise INIBIN context");
+ free(filebuf);
+ return 1;
+ }
+
+ if (!riot_inibin_read(&inibinctx, in)) {
+ errlog("Failed to read INIBIN file");
+ riot_inibin_ctx_free(&inibinctx);
+ free(filebuf);
+ return 1;
+ }
+
+ riot_inibin_print(&inibinctx, stdout);
+
+ struct mem_stream out = {
+ .ptr = filebuf,
+ .len = filelen,
+ .cur = 0,
+ };
+
+ if (!riot_inibin_write(&inibinctx, out)) {
+ errlog("Failed to write INIBIN file");
+ riot_inibin_ctx_free(&inibinctx);
+ free(filebuf);
+ return 1;
+ }
+
+ riot_inibin_ctx_free(&inibinctx);
+
+ u64 written = write_file(opts->dst, filelen, filebuf);
+ if (!written || written < filelen) {
+ errlog("Failed to write destination file: %s", opts->dst);
+ free(filebuf);
+ return 1;
+ }
+
+ free(filebuf);
+
+ return 0;
+}
s32
main(s32 argc, char **argv) {
- (void) argc;
- (void) argv;
+ dbglog("Version: " BRZESZCZOT_VERSION);
- dbglog("Version: " BRZESZCZOT_VERSION "\n");
+ struct opts opts;
+ if (!argparse(argc, argv, &opts)) return 1;
- return 0;
+ switch (opts.mode) {
+ case WAD_DUMP:
+ return wad_dump(&opts);
+
+ case INIBIN_DUMP:
+ return inibin_dump(&opts);
+
+ default:
+ errlog("Unknown mode: %d", opts.mode);
+ return 1;
+ }
}