diff --git a/gui.pnproj b/gui.pnproj
index 2fdea4f9..0c7ca049 100644
--- a/gui.pnproj
+++ b/gui.pnproj
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/source/banner/brlan.c b/source/banner/brlan.c
new file mode 100644
index 00000000..0342dff1
--- /dev/null
+++ b/source/banner/brlan.c
@@ -0,0 +1,214 @@
+/*
+ * brlan.c
+ * BannerPlayer
+ *
+ * Created by Alex Marshall on 09/03/16.
+ * Copyright 2009 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include
+#include
+#include
+
+#include "brlan.h"
+//#include "endian.h"
+
+char* BRLAN_rootpath = NULL;
+u8* BRLAN_file = NULL;
+u32 BRLAN_filesize = 0;
+u8* BRLAN_startfile = NULL;
+u32 BRLAN_startfilesize = 0;
+int BRLAN_looping = 0;
+
+void BRLAN_Initialize(char rootpath[])
+{
+ char brlanpath[256];
+ sprintf(brlanpath, "%s/arc/anim/banner.brlan", rootpath);
+ FILE* fp = fopen(brlanpath, "rb");
+ if(fp == NULL) {
+ fprintf(stderr, "Couldn't find banner.brlan. Let's assume it's a looping banner then.\n");
+ BRLAN_looping = 1;
+ sprintf(brlanpath, "%s/arc/anim/banner_start.brlan", rootpath);
+ fp = fopen(brlanpath, "rb");
+ if(fp == NULL) {
+ fprintf(stderr, "No BRLAN file found. Quitting.\n");
+ exit(1);
+ }
+ fseek(fp, 0, SEEK_END);
+ BRLAN_startfilesize = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ fread(BRLAN_startfile, BRLAN_startfilesize, 1, fp);
+ fclose(fp);
+ sprintf(brlanpath, "%s/arc/anim/banner_loop.brlan", rootpath);
+ fp = fopen(brlanpath, "rb");
+ if(fp == NULL) {
+ fprintf(stderr, "No BRLAN file found. Quitting.\n");
+ exit(1);
+ }
+ }else
+ BRLAN_looping = 0;
+ fseek(fp, 0, SEEK_END);
+ BRLAN_filesize = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ fread(BRLAN_file, BRLAN_filesize, 1, fp);
+ fclose(fp);
+}
+
+#define MAXIMUM_TAGS_SIZE (0x1000)
+
+fourcc tag_FourCCs[] = { "RLPA", "RLTS", "RLVI", "RLVC", "RLMC", "RLTP" };
+
+static size_t BRLAN_fileoffset = 0;
+
+static void BRLAN_ReadDataFromMemoryX(void* destination, void* input, size_t size)
+{
+ u8* out = (u8*)destination;
+ u8* in = ((u8*)input) + BRLAN_fileoffset;
+ memcpy(out, in, size);
+}
+
+static void BRLAN_ReadDataFromMemory(void* destination, void* input, size_t size)
+{
+ BRLAN_ReadDataFromMemoryX(destination, input, size);
+ BRLAN_fileoffset += size;
+}
+
+static void CreateGlobal_pai1(brlan_pai1_header_type2 *pai1_header, brlan_pai1_header_type1 pai1_header1,
+ brlan_pai1_header_type2 pai1_header2, int pai1_header_type)
+{
+ if(pai1_header_type == 1) {
+ pai1_header->magic[0] = pai1_header1.magic[0];
+ pai1_header->magic[1] = pai1_header1.magic[1];
+ pai1_header->magic[2] = pai1_header1.magic[2];
+ pai1_header->magic[3] = pai1_header1.magic[3];
+ pai1_header->size = pai1_header1.size;
+ pai1_header->framesize = pai1_header1.framesize;
+ pai1_header->flags = pai1_header1.flags;
+ pai1_header->unk1 = pai1_header1.unk1;
+ pai1_header->num_timgs = pai1_header1.num_timgs;
+ pai1_header->num_entries = pai1_header1.num_entries;
+ pai1_header->unk2 = 0;
+ pai1_header->entry_offset = pai1_header1.entry_offset;
+ }else
+ memcpy(pai1_header, &pai1_header2, sizeof(brlan_pai1_header_type2));
+}
+
+static int FourCCsMatch(fourcc cc1, fourcc cc2)
+{
+ if((cc1[0] == cc2[0]) && (cc1[1] == cc2[1]) && (cc1[2] == cc2[2]) && (cc1[3] == cc2[3]))
+ return 1;
+ else
+ return 0;
+}
+
+static int FourCCInList(fourcc cc)
+{
+ int i;
+ for(i = 0; i < 6; i++)
+ if(FourCCsMatch(cc, tag_FourCCs[i])) return 1;
+ return 0;
+}
+
+static void ReadTagFromBRLAN(BRLAN_animation **anims, int idx)
+{
+ int taghead_location = BRLAN_fileoffset;
+ tag_header head;
+ tag_entry* entries;
+ tag_entryinfo* entryinfo;
+ BRLAN_ReadDataFromMemory(&head, BRLAN_file, sizeof(tag_header));
+ memcpy(anims[idx]->type, head.magic, 4);
+ anims[idx]->entrycount = head.entry_count;
+ int i, z;
+ entries = (tag_entry*)calloc(anims[idx]->entrycount, sizeof(tag_entry));
+ entryinfo = (tag_entryinfo*)calloc(anims[idx]->entrycount, sizeof(tag_entryinfo));
+ for(i = 0; i < anims[idx]->entrycount; i++) {
+ BRLAN_ReadDataFromMemory(&entries[i], BRLAN_file, sizeof(tag_entry));
+ }
+ for(i = 0; i < anims[idx]->entrycount; i++) {
+ BRLAN_fileoffset = be32(entries[i].offset) + taghead_location;
+ BRLAN_ReadDataFromMemory(&entryinfo[i], BRLAN_file, sizeof(tag_entryinfo));
+ anims[idx]->entries[i].animtype = be16(entryinfo[i].type);
+ anims[idx]->entries[i].tripletcount = be16(entryinfo[i].coord_count);
+ for(z = 0; z < be16(entryinfo[i].coord_count); z++) {
+ BRLAN_ReadDataFromMemory(&anims[idx]->entries[i].triplets[z], BRLAN_file, sizeof(f32) * 3);
+ anims[idx]->entries[i].triplets[z].frame = le32(anims[idx]->entries[i].triplets[z].frame);
+ anims[idx]->entries[i].triplets[z].value = le32(anims[idx]->entries[i].triplets[z].value);
+ anims[idx]->entries[i].triplets[z].blend = le32(anims[idx]->entries[i].triplets[z].blend);
+ }
+ }
+ free(entries);
+ free(entryinfo);
+}
+
+u16 BRLAN_ReadAnimations(BRLAN_animation **anims)
+{
+ BRLAN_fileoffset = 0;
+ brlan_header header;
+ BRLAN_ReadDataFromMemoryX(&header, BRLAN_file, sizeof(brlan_header));
+ BRLAN_fileoffset = be16(header.pai1_offset);
+ brlan_pai1_universal universal;
+ BRLAN_ReadDataFromMemoryX(&universal, BRLAN_file, sizeof(brlan_pai1_universal));
+
+ int pai1_header_type;
+ brlan_pai1_header_type1 pai1_header1;
+ brlan_pai1_header_type2 pai1_header2;
+ brlan_pai1_header_type2 pai1_header;
+
+ if((be32(universal.flags) & (1 << 25)) >= 1) {
+ pai1_header_type = 2;
+ BRLAN_ReadDataFromMemory(&pai1_header2, BRLAN_file, sizeof(brlan_pai1_header_type2));
+ } else {
+ pai1_header_type = 1;
+ BRLAN_ReadDataFromMemory(&pai1_header1, BRLAN_file, sizeof(brlan_pai1_header_type1));
+ }
+
+ CreateGlobal_pai1(&pai1_header, pai1_header1, pai1_header2, pai1_header_type);
+
+ int tagcount = be16(pai1_header.num_entries);
+ u32 *taglocations = (u32*)calloc(tagcount, sizeof(u32));
+ *anims = (BRLAN_animation*)calloc(tagcount, sizeof(BRLAN_animation));
+ fourcc CCs[256];
+ memset(CCs, 0, 256*4);
+ BRLAN_fileoffset = be32(pai1_header.entry_offset) + be16(header.pai1_offset);
+ BRLAN_ReadDataFromMemory(taglocations, BRLAN_file, tagcount * sizeof(u32));
+ int animcnt = 1;
+ int i;
+ for(i = 0; i < tagcount; i++) {
+ BRLAN_fileoffset = be32(taglocations[i]) + be16(header.pai1_offset);
+ brlan_entry tmpentry;
+ BRLAN_ReadDataFromMemory(&tmpentry, BRLAN_file, sizeof(brlan_entry));
+ if((be32(tmpentry.flags) & (1 << 25)) >= 1)
+ BRLAN_fileoffset += sizeof(u32);
+ memcpy(anims[animcnt]->name, tmpentry.name, 20);
+ fourcc magick;
+ BRLAN_ReadDataFromMemoryX(magick, BRLAN_file, 4);
+ memcpy(CCs[i], magick, 4);
+ if(FourCCInList(CCs[i]) == 1) {
+ anims[animcnt]->offset = BRLAN_fileoffset;
+ ReadTagFromBRLAN(anims, animcnt);
+ animcnt++;
+ }
+ }
+ return tagcount;
+}
+
+void BRLAN_Finish()
+{
+ if(BRLAN_file != NULL)
+ free(BRLAN_file);
+ if(BRLAN_startfile != NULL)
+ free(BRLAN_startfile);
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/banner/brlan.h b/source/banner/brlan.h
new file mode 100644
index 00000000..74fb4e7e
--- /dev/null
+++ b/source/banner/brlan.h
@@ -0,0 +1,146 @@
+/*
+ * brlan.h
+ * BannerPlayer
+ *
+ * Created by Alex Marshall on 09/03/16.
+ * Copyright 2009 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef _BRLAN_H_
+#define _BRLAN_H_
+
+#include
+
+
+typedef char fourcc[4];
+
+#define le16 be16
+#define le32 be32
+#define le64 be64
+
+u16 be16(u16 x);
+u32 be32(u32 x);
+u64 be64(u64 x);
+
+typedef enum
+{
+ RLPA_ENTRY = 0,
+ RLTS_ENTRY = 1,
+ RLVI_ENTRY = 2,
+ RLVC_ENTRY = 3,
+ RLMC_ENTRY = 4,
+ RLTP_ENTRY = 5
+} brlan_entry_type;
+
+typedef struct
+{
+ fourcc magic; // "pai1" in ASCII.
+ u32 size; // Size of section, which is rest of the file. (header.file_size - header.offset_pai1)
+ u16 framesize; // Framesize
+ u8 flags; // Flags
+ u8 unk1; // Unknown
+ u16 num_timgs; // Number of timgs?
+ u16 num_entries; // Number of tags in the brlan.
+ u32 unk2; // Only if bit 25 of flags is set.
+ u32 entry_offset; // Offset to entries. (Relative to start of pai1 header.)
+} brlan_pai1_header_type2;
+
+typedef struct
+{
+ fourcc magic; // "RLAN" in ASCII.
+ u32 unk1; // Always 0xFEFF 0x0008. Possibly a versioning string.
+ u32 file_size; // Size of whole file, including the header.
+ u16 pai1_offset; // The offset to the pai1 header from the start of file.
+ u16 pai1_count; // How many pai1 sections there are (duh, only 1... wtf?)
+} brlan_header;
+
+typedef struct
+{
+ fourcc magic; // "pai1" in ASCII.
+ u32 size; // Size of section, which is rest of the file. (header.file_size - header.offset_pai1)
+ u16 framesize; // Framesize
+ u8 flags; // Flags
+ u8 unk1; // Unknown
+ u16 num_timgs; // Number of timgs?
+ u16 num_entries; // Number of tags in the brlan.
+} brlan_pai1_universal;
+
+typedef struct
+{
+ fourcc magic; // "pai1" in ASCII.
+ u32 size; // Size of section, which is rest of the file. (header.file_size - header.offset_pai1)
+ u16 framesize; // Framesize
+ u8 flags; // Flags
+ u8 unk1; // Unknown
+ u16 num_timgs; // Number of timgs?
+ u16 num_entries; // Number of tags in the brlan.
+ u32 entry_offset; // Offset to entries. (Relative to start of pai1 header.)
+} brlan_pai1_header_type1;
+
+typedef struct
+{
+ char name[20]; // Name of the BRLAN entry. (Must be defined in the BRLYT)
+ u32 flags; // Flags? (If bit 25 is set, we have another u32 after the entry. It's use is unknown.)
+ u32 anim_header_len; // Length of the animation header which is directly after this entry.
+} brlan_entry;
+
+typedef struct
+{
+ fourcc magic;
+ u8 entry_count; // How many entries in this chunk.
+ u8 pad1; // All cases I've seen is zero.
+ u8 pad2; // All cases I've seen is zero.
+ u8 pad3; // All cases I've seen is zero.
+} tag_header;
+
+typedef struct
+{
+ u32 offset; // Offset to the data pointed to by this entry.
+ // Relative to the start of the RLPA header.
+} tag_entry;
+
+typedef struct
+{
+ u16 type; // Type (look at animtypes)
+ u16 unk1; // ??? Every case has been 0x0200
+ u16 coord_count; // How many coordinates.
+ u16 pad1; // All cases I've seen is zero.
+ u32 unk2; // ??? In every case I've seen, it is 0x0000000C.
+} tag_entryinfo;
+
+typedef struct
+{ // Bits not listed here are currently unknown.
+ u32 part1; // If Bit 9 is set in flags, this is an f32, with a coordinate. (Bit 17 seems to act the same)
+ u32 part2; // If Bit 16 is set in flags, this is an f32, with another coordinate. (Bit 17 seems to act the same)
+ u32 part3; // With Bit 16 set in flags, this seems to be yet another coordinate. (Bit 17 seems to act the same)
+} tag_data;
+
+typedef struct BRLAN_trip
+{
+ f32 frame; // Frame number.
+ f32 value; // Value at the frame.
+ f32 blend; // Interpolation value.
+} BRLAN_triplets;
+
+typedef struct BRLAN_entr
+{
+ u16 animtype; // What subtype of animation.
+ u16 tripletcount; // Number of triplets.
+ BRLAN_triplets triplets[20]; // Shouldn't ever be more than 20.
+} BRLAN_entries;
+
+typedef struct BRLAN_anims
+{
+ char type[4]; // The type of animation (FourCC from BRLAN file)
+ char name[20]; // Name.
+ u32 offset; // Offset into the BRLAN file to find this animation.
+ u16 entrycount; // How many entries.
+ BRLAN_entries entries[20]; // The entries. Shouldn't ever be more than 20.
+} BRLAN_animation;
+
+void BRLAN_Initialize(char rootpath[]);
+u16 BRLAN_ReadAnimations(BRLAN_animation **anims);
+void BRLAN_Finish();
+
+#endif //_BRLAN_H_
diff --git a/source/banner/brlyt.c b/source/banner/brlyt.c
new file mode 100644
index 00000000..258348ce
--- /dev/null
+++ b/source/banner/brlyt.c
@@ -0,0 +1,29 @@
+/*
+ * brlyt.c
+ * BannerPlayer
+ *
+ * Created by Alex Marshall on 09/03/16.
+ * Copyright 2009 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include
+#include
+#include
+
+#include "brlyt.h"
+
+void BRLYT_Initialize(char rootpath[])
+{
+
+}
+
+int BRLYT_ReadObjects(BRLYT_object** objs)
+{
+ return 0;
+}
+
+void BRLYT_Finish()
+{
+
+}
diff --git a/source/banner/brlyt.h b/source/banner/brlyt.h
new file mode 100644
index 00000000..2792819a
--- /dev/null
+++ b/source/banner/brlyt.h
@@ -0,0 +1,25 @@
+/*
+ * brlyt.h
+ * BannerPlayer
+ *
+ * Created by Alex Marshall on 09/03/16.
+ * Copyright 2009 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef _BRLYT_H_
+#define _BRLYT_H_
+
+#include
+
+typedef struct BRLYT_objs
+{
+ char type[4]; // The type of object (FourCC from BRLYT file)
+ u32 offset; // Offset into the BRLYT file to find this object.
+} BRLYT_object;
+
+void BRLYT_Initialize(char rootpath[]);
+int BRLYT_ReadObjects(BRLYT_object** objs);
+void BRLYT_Finish();
+
+#endif //_BRLYT_H_
diff --git a/source/getrev.c b/source/getrev.c
deleted file mode 100644
index 3c461f77..00000000
--- a/source/getrev.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "svnrev.h"
-
-char *GetRev() {
-
- return SVN_REV;
-
-}
diff --git a/source/getrev.h b/source/getrev.h
deleted file mode 100644
index 6138424b..00000000
--- a/source/getrev.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef GETREV_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-char *GetRev();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/source/network/networkops.cpp b/source/network/networkops.cpp
index b89b8beb..38e0b9f4 100644
--- a/source/network/networkops.cpp
+++ b/source/network/networkops.cpp
@@ -16,7 +16,7 @@
#include "settings/cfg.h"
#include "main.h"
#include "http.h"
-#include "getrev.h"
+#include "svnrev.h"
#define PORT 4299
diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp
index 35adff89..85f5c229 100644
--- a/source/prompts/PromptWindows.cpp
+++ b/source/prompts/PromptWindows.cpp
@@ -28,7 +28,7 @@
#include "wad/wad.h"
#include "unzip/unzip.h"
#include "zlib.h"
-#include "getrev.h"
+#include "svnrev.h"
/*** Variables that are also used extern ***/
diff --git a/source/svnrev.c b/source/svnrev.c
new file mode 100644
index 00000000..d3ea8328
--- /dev/null
+++ b/source/svnrev.c
@@ -0,0 +1,7 @@
+#define SVN_REV "644M"
+
+const char *GetRev()
+{
+ return SVN_REV;
+}
+
diff --git a/source/svnrev.h b/source/svnrev.h
index d4ddf560..f2880050 100644
--- a/source/svnrev.h
+++ b/source/svnrev.h
@@ -1,4 +1,14 @@
-#ifndef SVNREV_H
- #define SVNREV_H
- #define SVN_REV "643M"
+#ifndef SVNREV_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+char *GetRev();
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* SVNREV_H */
diff --git a/svnrev.sh b/svnrev.sh
index 2e869d3b..8d0b0142 100644
--- a/svnrev.sh
+++ b/svnrev.sh
@@ -3,15 +3,18 @@
a=$(svnversion -n ..)
[ -n "$a" ] || a=$(SubWCRev .. | tr -d '\n' | sed 's/[^0-9]*\([0-9]*\).*/\1/')
-[ -f ../source/svnrev.h ] || touch ../source/svnrev.h
+[ -f ../source/svnrev.c ] || touch ../source/svnrev.c
-b=$(cat ../source/svnrev.h | tr -d '\n' | sed 's/[^0-9]*\([0-9]*\).*/\1/')
+b=$(cat ../source/svnrev.c | tr -d '\n' | sed 's/[^0-9]*\([0-9]*\).*/\1/')
if [ "$a" != "$b" ]; then
- echo '#ifndef SVNREV_H' > ../source/svnrev.h
- echo ' #define SVNREV_H' >> ../source/svnrev.h
- echo ' #define SVN_REV "'$a'"' >> ../source/svnrev.h
- echo '#endif /* SVNREV_H */' >> ../source/svnrev.h
- echo 'svnrev.h changed' >&2
+ echo '#define SVN_REV "'$a'"' > ../source/svnrev.c
+ echo '' >> ../source/svnrev.c
+ echo 'const char *GetRev()' >> ../source/svnrev.c
+ echo '{ ' >> ../source/svnrev.c
+ echo ' return SVN_REV;' >> ../source/svnrev.c
+ echo '}' >> ../source/svnrev.c
+ echo '' >> ../source/svnrev.c
+ echo 'svnrev changed' >&2
fi
echo $a