Commit Diff


commit - /dev/null
commit + 3557439489e45dc65b16d38d7824899f996087da
blob - /dev/null
blob + 0d6b9930861bc435e82ffee20ba4dcd095c0d866 (mode 644)
--- /dev/null
+++ .gitignore
@@ -0,0 +1,6 @@
+cmake*
+.cache
+build
+compile_commands.json
+test
+.idea
\ No newline at end of file
blob - /dev/null
blob + 95726308eca49b759a0374eb54c13b66f0d7ce7c (mode 644)
--- /dev/null
+++ .gitlab-ci.yml
@@ -0,0 +1,8 @@
+test:
+  image: danger89/cmake:latest
+  script:
+    - mkdir build
+    - cd build
+    - cmake ..
+    - make
+    - ./test
blob - /dev/null
blob + 1a58f66277d6bc869dfeb701591bd39f25eaacd0 (mode 644)
Binary files /dev/null and DOOM1.WAD differ
blob - /dev/null
blob + 9ab0ced9ac03fcce95af58cb1eae389cacb70547 (mode 644)
--- /dev/null
+++ README.md
@@ -0,0 +1,5 @@
+# spitWAD
+
+`spitWAD` is a simple DOOM WAD management library
+
+`DOOM1.WAD` contained in this repo is the shareware version of DOOM and is used for tests
blob - /dev/null
blob + 0193223d3fd55a028cd6d07ebb9b32824fc768f8 (mode 644)
--- /dev/null
+++ spitwad.c
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "spitwad.h"
+
+static int fail(const char* msg) {
+    fprintf(stderr, "%s\n", msg);
+    return 1;
+}
+
+static uint32_t getlong(const unsigned char* data, size_t offset) {
+    return data[offset] | data[offset + 1] << 8 | data[offset + 2] << 16 | data[offset + 3] << 24;
+}
+
+static uint16_t getshort(const unsigned char* data, size_t offset) {
+    return data[offset] | data[offset + 1] << 8;
+}
+
+static char* getstring(const unsigned char* data, size_t offset) {
+    char* s = malloc(sizeof(char) * 9);
+    strncpy(s, data + offset, 8);
+    s[8] = '\0';
+    return s;
+}
+
+int new_WAD(struct WAD* wad, const unsigned char* data, size_t data_sz) {
+    if (wad == NULL) {
+        return fail("Supplied wad to new_WAD was NULL");
+    }
+
+    wad->data = malloc(sizeof(unsigned char) * data_sz);
+    if (wad->data == NULL) {
+        destroy_WAD(wad);
+        return fail("Allocation failure for wad->data");
+    }
+    memcpy(wad->data, data, data_sz);
+    wad->data_sz = data_sz;
+
+    char name[5];
+    memcpy(name, data, 4);
+    name[4] = '\0';
+    if (strcmp(name, "IWAD") == 0) {
+        wad->type = IWAD;
+    } else if (strcmp(name, "PWAD") == 0) {
+        wad->type = PWAD;
+    } else {
+        destroy_WAD(wad);
+        return fail("WAD Type was not IWAD or PWAD");
+    }
+
+    wad->dir_sz = getlong(data, 4);
+    wad->dir_offset = getlong(data, 8);
+
+    wad->directory = malloc(sizeof(struct DirEntry) * wad->dir_sz);
+    if (wad->directory == NULL) {
+        destroy_WAD(wad);
+        return fail("Allocation failure for wad->directory");
+    }
+
+    for (size_t i = wad->dir_offset, j = 0; i < data_sz; i += 16, ++j) {
+        wad->directory[j].offset = getlong(data, i);
+        wad->directory[j].length = getlong(data, i + 4);
+
+        char *s = getstring(data, i + 8);
+        strcpy(wad->directory[j].name, s);
+        free(s);
+    }
+
+    return 0;
+}
+
+int new_WAD_from_file(struct WAD* wad, const char* path) {
+    if (wad == NULL) {
+        fprintf(stderr, "Supplied wad to new_WAD_from_file was NULL\n");
+        return 0;
+    }
+
+   FILE *fp = NULL;
+   fp = fopen(path, "r");
+   if (fp == NULL) {
+       destroy_WAD(wad);
+       fprintf(stderr, "Failed to open %s. Returning NULL\n", path);
+       return 1;
+   }
+
+   fseek(fp, 0, SEEK_END);
+   size_t fsz = ftell(fp);
+   rewind(fp);
+
+   unsigned char *buf = NULL;
+   buf = (unsigned char*)malloc(sizeof(unsigned char) * fsz);
+   if (buf == NULL) {
+       destroy_WAD(wad);
+       fclose(fp);
+       return fail("Failed to allocate buf in new_WAD_from_file");
+   }
+
+   fread(buf, 1, fsz, fp);
+   fclose(fp);
+
+   new_WAD(wad, buf, fsz);
+   free(buf);
+   return 0;
+}
+
+void destroy_WAD(struct WAD* wad) {
+    free(wad->data);
+    free(wad->directory);
+    free(wad);
+    wad = NULL;
+}
+
+int write_to_file(struct WAD* wad, const char* path) {
+
+}
blob - /dev/null
blob + f8c126d3463dec98a4e19c992cec4a115a6968f4 (mode 644)
--- /dev/null
+++ spitwad.h
@@ -0,0 +1,32 @@
+#ifndef SPITWAD_SPITWAD_H
+#define SPITWAD_SPITWAD_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+enum WAD_Type {
+    IWAD,
+    PWAD
+};
+
+struct DirEntry {
+    uint32_t offset;
+    uint32_t length;
+    char name[9];
+};
+
+struct WAD {
+    enum WAD_Type type;
+    uint32_t dir_sz;
+    uint32_t dir_offset;
+    unsigned char *data;
+    size_t data_sz;
+    struct DirEntry *directory;
+};
+
+int new_WAD(struct WAD* wad, const unsigned char* data, size_t data_sz);
+int new_WAD_from_file(struct WAD* wad, const char* path);
+void destroy_WAD(struct WAD* wad);
+int write_to_file(struct WAD* wad, const char* path);
+
+#endif //SPITWAD_SPITWAD_H
blob - /dev/null
blob + 53accdcca7dd11c8a981c9209a35865ccab0d733 (mode 644)
--- /dev/null
+++ test.c
@@ -0,0 +1,18 @@
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "spitwad.h"
+
+int main() {
+    struct WAD *wad = malloc(sizeof(struct WAD));
+    assert(new_WAD_from_file(wad, "DOOM1.WAD") == 0);
+
+    // Values from manually inspecting DOOM1.WAD with a third-party tool
+    assert(wad->type == IWAD);
+    assert(wad->dir_sz == 1264);
+    assert(wad->dir_offset == 4175796);
+    assert(wad->directory[0].offset == 12);
+    assert(wad->directory[0].length == 10752);
+    assert(strcmp(wad->directory[0].name, "PLAYPAL") == 0);
+}
\ No newline at end of file