aboutsummaryrefslogtreecommitdiff
path: root/laichzeit
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--laichzeit/Progress.pngbin0 -> 40007 bytes
-rw-r--r--laichzeit/banner.c252
-rw-r--r--laichzeit/banner.h73
-rw-r--r--laichzeit/brlan.c106
-rw-r--r--laichzeit/brlan.h91
-rw-r--r--laichzeit/brlyt.c448
-rw-r--r--laichzeit/brlyt.h345
-rw-r--r--laichzeit/c_oop.c32
-rw-r--r--laichzeit/c_oop.h20
-rw-r--r--laichzeit/soundbin.c15
-rw-r--r--laichzeit/soundbin.h17
-rw-r--r--laichzeit/tpl.c515
-rw-r--r--laichzeit/tpl.h85
-rwxr-xr-xlaichzeit/types.h87
14 files changed, 2086 insertions, 0 deletions
diff --git a/laichzeit/Progress.png b/laichzeit/Progress.png
new file mode 100644
index 0000000..65406a5
--- /dev/null
+++ b/laichzeit/Progress.png
Binary files differ
diff --git a/laichzeit/banner.c b/laichzeit/banner.c
new file mode 100644
index 0000000..28ec988
--- /dev/null
+++ b/laichzeit/banner.c
@@ -0,0 +1,252 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* banner.c */
+/* The code for all the final banner stuff. Compile this! */
+/* ------------------------------------------------------------------------- */
+/* Compilation code contributed by: */
+/* icefire */
+/* Intermediation code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/md5.h>
+
+#include "types.h"
+#include "banner.h"
+#include "c_oop.h"
+
+#define inlinepad(x, y) ((x) + ((y) - ((x) % (y))))
+
+typedef struct
+{
+ u16 type; // This is 0x0000 for files, 0x0100 for folders
+ u16 string_offset; // Offset into the string table,
+ // from the start of the string table.
+ u32 data_offset; // Absolute offset from U.8- header for files.
+ // Recursion for directories.
+ u32 size; // Size of file for files.
+ // Last file entry number for directories.
+} u8node;
+
+typedef struct
+{
+ u32 tag; // 0x55AA382D "U.8-"
+ u32 root_offset; // Offset to root_node, always 0x20.
+ u32 header_size; // Size of header from root_node to
+ // end of string table.
+ u32 data_offset; // Offset to data
+ // root_offset + header_size, aligned to 0x40.
+ u8 zeroes[16]; // Padding
+} u8header;
+
+typedef struct
+{
+ u8header header;
+ u8node rootnode;
+ u32 numnodes;
+ u8node* nodes;
+ u32 stringsz;
+ u8* string_table;
+ u32 datasz;
+ u8* data;
+} u8archive;
+
+static void AddFileToDir(U8Dir* arc, U8File file)
+{
+ AddObjectToList((u8**)&arc->files, \
+ (u32*)&arc->filecnt, \
+ (u8*)&file, sizeof(U8File));
+}
+
+static U8Dir* AddDirToDir(U8Dir* arc, U8Dir dir)
+{
+ return &arc->dirs[AddObjectToList((u8**)&arc->dirs, \
+ (u32*)&arc->dircnt, \
+ (u8*)&dir, sizeof(U8Dir))];
+}
+
+
+
+IMET* LaichMeta_IMET(char** names, \
+ u32 iconsize, u32 bannersize, u32 soundsize)
+{
+ IMET* header = malloc(sizeof(IMET));
+ memset(header, 0, sizeof(IMET));
+ header->imet[0] = 'I';
+ header->imet[1] = 'M';
+ header->imet[2] = 'E';
+ header->imet[3] = 'T';
+ header->unk = htobll(0x0000060000000003);
+ header->sizes[0] = htobl(iconsize);
+ header->sizes[1] = htobl(bannersize);
+ header->sizes[2] = htobl(soundsize);
+ header->flag1 = 0x00;
+
+ int i;
+ for(i = 0; i < 8; i++)
+ memcpy(header->names[i], names[i], 2 * 42);
+
+ MD5(((u8*)header) + 0x40, 0x600, (u8*)header->crypto);
+ return header;
+}
+
+IMD5* LaichMeta_IMD5(u8* file, u32 size)
+{
+ IMD5* header = malloc(sizeof(IMD5));
+ memset(header, 0, sizeof(IMD5));
+ header->imd5[0] = 'I';
+ header->imd5[1] = 'M';
+ header->imd5[2] = 'D';
+ header->imd5[3] = '5';
+ header->filesize = htobl(size);
+ MD5(file, size, header->crypto);
+ return header;
+}
+
+U8* LaichMeta_StartU8(U8Dir* root)
+{
+ U8* arc = malloc(sizeof(U8));
+ arc->rootdir.filecnt = 0;
+ arc->rootdir.files = NULL;
+ arc->rootdir.dircnt = 0;
+ arc->rootdir.dirs = NULL;
+ memset(arc->rootdir.name, 0, 256);
+ *root = arc->rootdir;
+ return arc;
+}
+
+U8Dir* LaichMeta_CreateDirInDirU8(U8Dir* arc, char* name)
+{
+ U8Dir dir;
+ dir.filecnt = 0;
+ dir.files = NULL;
+ dir.dircnt = 0;
+ dir.dirs = NULL;
+ memset(dir.name, 0, 256);
+ strncpy(dir.name, name, 256);
+ return AddDirToDir(arc, dir);
+}
+
+void LaichMeta_CreateFileInDirU8(U8Dir* arc, char* src, char* dst)
+{
+ U8File file;
+ memset(file.src, 0, 256);
+ strncpy(file.src, src, 256);
+ memset(file.dst, 0, 256);
+ strncpy(file.dst, dst, 256);
+ AddFileToDir(arc, file);
+}
+
+static void U8_packdir(u8archive * arc, U8Dir dir, u32 recursion)
+{
+ u32 i, oldnumnodes;
+ U8File curfile;
+ U8Dir curdir;
+ u8node curnode;
+
+ oldnumnodes = arc->numnodes;
+
+ arc->nodes = realloc(arc->nodes, arc->numnodes * sizeof(u8node));
+ curnode = arc->nodes[arc->numnodes];
+
+ curnode.type = 0x0001; // Is a folder.
+
+ curnode.string_offset = htobl(arc->stringsz);
+ arc->string_table = realloc(arc->string_table, strlen(curdir.name) \
+ + 1);
+ memcpy(arc->string_table, curdir.name, strlen(curdir.name) + 1);
+ arc->stringsz += strlen(curdir.name) + 1;
+ arc->numnodes++;
+
+ for(i = 0; i < dir.filecnt; i++) { // Handle files.
+ curfile = dir.files[i];
+
+ arc->nodes = realloc(arc->nodes, \
+ arc->numnodes * sizeof(u8node));
+ curnode = arc->nodes[arc->numnodes];
+
+ curnode.type = 0; //file
+ curnode.size = htobl(curfile.size);
+
+ curnode.string_offset = htobl(arc->stringsz);
+ arc->string_table = realloc(arc->string_table, \
+ strlen(curfile.dst) + 1);
+ memcpy(arc->string_table, curfile.dst, \
+ strlen(curfile.dst) + 1);
+ arc->stringsz += strlen(curfile.dst) + 1;
+
+ curnode.data_offset = htobl(arc->datasz);
+ arc->data = realloc(arc->data, inlinepad(curfile.size, 32));
+ memcpy(arc->data, curfile.data, curfile.size);
+ arc->datasz += inlinepad(curfile.size, 32);
+
+ arc->numnodes++;
+ }
+
+ for(i = 0; i < dir.dircnt; i++) { // Handle folders.
+ curdir = dir.dirs[i];
+ U8_packdir(arc, curdir, ++recursion);
+ }
+
+ // add one for root node
+ arc->nodes[oldnumnodes].size = htobl(arc->numnodes + 1);
+}
+
+u8* LaichMeta_CompileU8(U8* input, u32* size)
+{
+ u8archive arc;
+ u32 offset = 0, data_offset, i;
+ u8* outbuf;
+
+ arc.string_table = calloc(1, 1); //Initial NULL
+ arc.stringsz = 1; //Initial NULL
+ arc.data = NULL;
+ arc.nodes = NULL;
+
+ U8_packdir(&arc, input->rootdir, 0);
+
+ arc.rootnode.type = htobs(0x0100);
+ arc.rootnode.string_offset = 0;
+ arc.rootnode.data_offset = 0;
+ arc.rootnode.size = htobl(arc.numnodes);
+
+ arc.header.tag = htobl(0x55AA382D);
+ arc.header.root_offset = htobl(0x20);
+ arc.header.header_size = htobl( \
+ (sizeof(u8node) * arc.numnodes) + \
+ arc.stringsz);
+ data_offset = inlinepad(0x20 + \
+ (sizeof(u8node) * arc.numnodes) + \
+ arc.stringsz, 0x40);
+ arc.header.data_offset = htobl(data_offset);
+ memset(arc.header.zeroes, 0, 16);
+
+ for(i = 0; i < arc.numnodes; i++) // fix the data offset
+ if (htobs(arc.nodes[i].type) == 0) // Checking if it is a file
+ arc.nodes[i].data_offset = htobl(\
+ btohl(arc.nodes[i].data_offset) + \
+ data_offset);
+
+ outbuf = calloc(1, sizeof(u8header) + sizeof(u8node) + \
+ (sizeof(u8node) * arc.numnodes) + arc.stringsz + \
+ arc.datasz);
+
+ memcpy(outbuf + offset, &arc.header, sizeof(u8header));
+ offset += sizeof(u8header);
+ memcpy(outbuf + offset, &arc.rootnode, sizeof(u8node));
+ offset += sizeof(u8node);
+ memcpy(outbuf + offset, arc.nodes, sizeof(u8node) * arc.numnodes);
+ offset += sizeof(u8node) * arc.numnodes;
+ memcpy(outbuf + offset, arc.string_table, arc.stringsz);
+ offset += arc.stringsz;
+ memcpy(outbuf + offset, arc.data, arc.datasz);
+ offset += arc.datasz;
+
+ *size = offset;
+ return outbuf;
+}
diff --git a/laichzeit/banner.h b/laichzeit/banner.h
new file mode 100644
index 0000000..b60b24d
--- /dev/null
+++ b/laichzeit/banner.h
@@ -0,0 +1,73 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* banner.h */
+/* The header file for all the final banner stuff. Include this! */
+/* ------------------------------------------------------------------------- */
+/* Compilation code contributed by: */
+/* icefire */
+/* Intermediation code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#ifndef BANNER_H
+#define BANNER_H
+
+#include "types.h"
+
+#define USE_BANNER
+
+typedef struct
+{
+ u8 zeroes[128]; // padding
+ char imet[4]; // `IMET'
+ u64 unk; // 0x0000060000000003 fixed, unknown purpose
+ u32 sizes[3]; // icon.bin, banner.bin, sound.bin
+ u32 flag1; // ???
+ u16 names[7][42]; // JP, EN, DE, FR, ES, IT, NL
+ u8 zeroes_2[840]; // Padding
+ u8 crypto[16]; // MD5 of 0x40 to 0x640 in header.
+ // Should be all 0's when calculating MD5.
+} IMET;
+
+typedef struct
+{
+ char imd5[4]; // `IMD5'
+ u32 filesize; // Size of rest of file
+ u8 zeroes[8]; // Padding
+ u8 crypto[16]; // MD5 of rest of file
+} IMD5;
+
+typedef struct
+{
+ char src[256]; // Filename.
+ char dst[256]; // Filename.
+ u32 size; // Size of the data.
+ u8* data; // The data.
+} U8File;
+
+typedef struct ud
+{
+ char name[256]; // Name.
+ int filecnt; // How many files.
+ U8File* files; // The files.
+ int dircnt; // How many subdirs.
+ struct ud* dirs; // The dirs.
+} U8Dir;
+
+typedef struct
+{
+ U8Dir rootdir; // The root dir.
+} U8;
+
+IMET* LaichMeta_IMET(char** names, \
+ u32 iconsize, u32 bannersize, u32 soundsize);
+IMD5* LaichMeta_IMD5(u8* file, u32 size);
+U8* LaichMeta_StartU8(U8Dir* root);
+U8Dir* LaichMeta_CreateDirInDirU8(U8Dir* arc, char* name);
+void LaichMeta_CreateFileInDirU8(U8Dir* arc, char* src, char* dst);
+u8* LaichMeta_CompileU8(U8* input, u32* size);
+
+#endif //BANNER_H
diff --git a/laichzeit/brlan.c b/laichzeit/brlan.c
new file mode 100644
index 0000000..2d121cd
--- /dev/null
+++ b/laichzeit/brlan.c
@@ -0,0 +1,106 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* brlan.c */
+/* The code for all the BRLAN stuff. Compile this! */
+/* ------------------------------------------------------------------------- */
+/* Most code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "brlan.h"
+#include "c_oop.h"
+
+static void AddTripletToAnimOnTagOnBRLAN(BRLAN* brlan, int tag, int anim, \
+ LANTriplet triplet)
+{
+ AddObjectToList((u8**)&brlan->tags[tag].anims[anim].triplets, \
+ (u32*)&brlan->tags[tag].anims[anim].tripletcnt, \
+ (u8*)&triplet, sizeof(LANTriplet));
+}
+
+static int AddAnimToTagOnBRLAN(BRLAN* brlan, int tag, LANAnim anim)
+{
+ return AddObjectToList((u8**)&brlan->tags[tag].anims, \
+ (u32*)&brlan->tags[tag].animcnt, \
+ (u8*)&anim, sizeof(LANAnim));
+}
+
+static int AddTagToBRLAN(BRLAN* brlan, LANTag tag)
+{
+ return AddObjectToList((u8**)&brlan->tags, \
+ (u32*)&brlan->tagcnt, \
+ (u8*)&tag, sizeof(LANTag));
+}
+
+static void AddTextureToBRLAN(BRLAN* brlan, LANTex tex)
+{
+ AddObjectToList((u8**)&brlan->texs, \
+ (u32*)&brlan->texcnt, \
+ (u8*)&tex, sizeof(LANTex));
+}
+
+BRLAN* LaichAnim_Start()
+{
+ BRLAN* brlan = malloc(sizeof(BRLAN));
+ brlan->framesize = 0;
+ brlan->tagcnt = 0;
+ brlan->texcnt = 0;
+ brlan->tags = NULL;
+ brlan->texs = NULL;
+ return brlan;
+}
+
+void LaichAnim_AddTexture(BRLAN* brlan, char* name)
+{
+ LANTex tex;
+ memset(tex.name, 0, 256);
+ strncpy(tex.name, name, 256);
+ AddTextureToBRLAN(brlan, tex);
+}
+
+int LaichAnim_StartTag(BRLAN* brlan, char* name, LANTagType type)
+{
+ LANTag tag;
+ memset(tag.name, 0, 20);
+ strncpy(tag.name, name, 20);
+ tag.type = type;
+ tag.animcnt = 0;
+ tag.anims = NULL;
+ return AddTagToBRLAN(brlan, tag);
+}
+
+int LaichAnim_StartAnim(BRLAN* brlan, int tag, LANAnimType type)
+{
+ LANAnim anim;
+ anim.type = type;
+ anim.tripletcnt = 0;
+ anim.triplets = NULL;
+ return AddAnimToTagOnBRLAN(brlan, tag, anim);
+}
+
+void LaichAnim_AddTriplet(BRLAN* brlan, int tag, int anim, \
+ f32 frame, f32 value, f32 interpolation)
+{
+ LANTriplet triplet;
+ triplet.frame = frame;
+ triplet.value = value;
+ triplet.interpolation = interpolation;
+ AddTripletToAnimOnTagOnBRLAN(brlan, tag, anim, triplet);
+}
+
+void LaichAnim_EndAnim(BRLAN* brlan, int tag, int anim)
+{
+ brlan->tags[tag].anims[anim].done = 1;
+}
+
+void LaichAnim_EndTag(BRLAN* brlan, int tag)
+{
+ brlan->tags[tag].done = 1;
+}
diff --git a/laichzeit/brlan.h b/laichzeit/brlan.h
new file mode 100644
index 0000000..30fe311
--- /dev/null
+++ b/laichzeit/brlan.h
@@ -0,0 +1,91 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* brlan.h */
+/* The header file for all the BRLAN stuff. Include this! */
+/* ------------------------------------------------------------------------- */
+/* Most code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#ifndef BRLAN_H
+#define BRLAN_H
+
+#include "types.h"
+
+#define USE_BRLAN
+
+typedef enum {
+ BRLAN_TAG_RLPA = 0, // Pane Animation (All the transforms)
+ BRLAN_TAG_RLVC = 1, // Vertex Color (Changes colors)
+ BRLAN_TAG_RLTP = 2, // Texture Picture (Changes TPL frame)
+ BRLAN_TAG_RLMC = 3, // Material Color
+ BRLAN_TAG_RLTS = 4, // Texture Shader (Defines RLTPs)
+ BRLAN_TAG_RLVI = 5 // Vertex (I?)
+ // TODO: Figure out the rest of the names.
+} LANTagType;
+
+typedef enum {
+ BRLAN_RLPA_X_TRANSLATION = 0,
+ BRLAN_RLPA_Y_TRANSLATION = 1,
+ BRLAN_RLPA_Z_TRANSLATION = 2,
+ BRLAN_RLPA_ROTATE = 3,
+ BRLAN_RLPA_X_ZOOM = 4,
+ BRLAN_RLPA_Y_ZOOM = 5,
+ BRLAN_RLPA_WIDTH = 6,
+ BRLAN_RLPA_HEIGHT = 7,
+ BRLAN_RLVC_ALPHA = 8,
+ BRLAN_RLTS_RANGE = 9,
+ BRLAN_RLTP_CHANGE_FRAME = 10
+ // TODO: Add moar.
+} LANAnimType;
+
+typedef struct {
+ f32 frame; // The frame.
+ f32 value; // The value.
+ f32 interpolation; // The interpolation.
+} LANTriplet;
+
+typedef struct {
+ LANAnimType type; // Type of animation.
+ int tripletcnt; // How many triplets.
+ LANTriplet* triplets; // The triplets.
+ int done; // Did we end it? (Security measure)
+} LANAnim;
+
+typedef struct {
+ char name[20]; // Name of tag.
+ u32 flags; // Flags.
+ LANTagType type; // Type of tag.
+ int animcnt; // How many animations.
+ LANAnim* anims; // The animations.
+ int done; // Did we end it? (Security measure)
+} LANTag;
+
+typedef struct {
+ char name[256]; // Name of texture. Using 256 because
+ // the actual size is arbitrary.
+} LANTex;
+
+typedef struct {
+ int framesize; // How many frames to be displayed.
+ int tagcnt; // How many tags there are.
+ int texcnt; // How many textures there are.
+ LANTag* tags; // The tags.
+ LANTex* texs; // The textures.
+ int done; // Did we end it? (Security measure)
+} BRLAN;
+
+BRLAN* LaichAnim_Start();
+void LaichAnim_AddTexture(BRLAN* brlan, char* name);
+int LaichAnim_StartTag(BRLAN* brlan, char* name, LANTagType type);
+int LaichAnim_StartAnim(BRLAN* brlan, int tag, LANAnimType type);
+void LaichAnim_AddTriplet(BRLAN* brlan, int tag, int anim, \
+ f32 frame, f32 value, f32 interpolation);
+void LaichAnim_EndAnim(BRLAN* brlan, int tag, int anim);
+void LaichAnim_EndTag(BRLAN* brlan, int tag);
+u8* LaichAnim_Compile(BRLAN* brlan);
+
+#endif //BRLAN_H
diff --git a/laichzeit/brlyt.c b/laichzeit/brlyt.c
new file mode 100644
index 0000000..3c20589
--- /dev/null
+++ b/laichzeit/brlyt.c
@@ -0,0 +1,448 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* brlyt.c */
+/* The code for all the BRLYT stuff. Compile this! */
+/* ------------------------------------------------------------------------- */
+/* Compilation code contributed by: */
+/* megazig */
+/* Intermediation code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "brlyt.h"
+#include "c_oop.h"
+
+#define RGBA8(w, x, y, z)\
+( \
+ (((u32)(z & 0xFF)) << 24) | \
+ (((u32)(w & 0xFF)) << 16) | \
+ (((u32)(x & 0xFF)) << 8) | \
+ (((u32)(y & 0xFF)) << 0) \
+)
+
+#define RGB565(w, x, y, z)\
+( \
+ (((u16)((w & 0xFF) >> 3)) << 11) | \
+ (((u16)((x & 0xFF) >> 2)) << 6) | \
+ (((u16)((y & 0xFF) >> 3)) << 0) \
+)
+
+static int AddEntryToBRLYT(BRLYT* brlyt, LYTEntry entry)
+{
+ return AddObjectToList((u8**)&brlyt->entries, (u32*)&brlyt->entrycnt, \
+ (u8*)&entry, sizeof(LYTEntry));
+}
+
+static int AddTexCoordToPic(BRLYT* brlyt, int pic, LYTTexCoord coord)
+{
+ return AddObjectToList((u8**)&brlyt->entries[pic].tag.pic.texcoords, \
+ (u32*)&brlyt->entries[pic].tag.pic.texcoordcnt, \
+ (u8*)&coord, sizeof(LYTTexCoord));
+}
+
+static int AddSubToGroup(BRLYT* brlyt, int group, LYTSub sub)
+{
+ return AddObjectToList((u8**)&brlyt->entries[group].tag.grp.subs, \
+ (u32*)&brlyt->entries[group].tag.grp.subcnts, \
+ (u8*)&sub, sizeof(LYTSub));
+}
+
+BRLYT* LaichLyt_Start(float width, float height)
+{
+ BRLYT* brlyt = calloc(sizeof(BRLYT), 1);
+ brlyt->width = width;
+ brlyt->height = height;
+ brlyt->entrycnt = 0;
+ brlyt->entries = NULL;
+ return brlyt;
+}
+
+int LaichLyt_StartPane(BRLYT* brlyt, char* name)
+{
+ LYTEntry entry;
+ entry.type = LYT_TYPE_PANE;
+ entry.done = 0;
+ entry.tag.pane.alpha = 255;
+ entry.tag.pane.alpha2 = 0;
+ memset(entry.tag.pane.name, 0, 24);
+ strncpy(entry.tag.pane.name, name, 24);
+ entry.tag.pane.x = 0;
+ entry.tag.pane.y = 0;
+ entry.tag.pane.z = 0;
+ entry.tag.pane.rot_x = 0;
+ entry.tag.pane.rot_x = 0;
+ entry.tag.pane.angle = 0;
+ entry.tag.pane.xmag = 0;
+ entry.tag.pane.ymag = 0;
+ entry.tag.pane.width = 0;
+ entry.tag.pane.height = 0;
+ entry.tag.pane.done = 0;
+ return AddEntryToBRLYT(brlyt, entry);
+}
+
+int LaichLyt_StartText(BRLYT* brlyt, char* name)
+{
+ LYTEntry entry;
+ entry.type = LYT_TYPE_TEXT;
+ entry.done = 0;
+ entry.tag.text.pane.alpha = 255;
+ entry.tag.text.pane.alpha2 = 0;
+ memset(entry.tag.text.pane.name, 0, 24);
+ strncpy(entry.tag.text.pane.name, name, 24);
+ entry.tag.text.pane.x = 0;
+ entry.tag.text.pane.y = 0;
+ entry.tag.text.pane.z = 0;
+ entry.tag.text.pane.rot_x = 0;
+ entry.tag.text.pane.rot_x = 0;
+ entry.tag.text.pane.angle = 0;
+ entry.tag.text.pane.xmag = 0;
+ entry.tag.text.pane.ymag = 0;
+ entry.tag.text.pane.width = 0;
+ entry.tag.text.pane.height = 0;
+ entry.tag.text.pane.done = 0;
+ entry.tag.text.font = LYT_FONT_DEFAULT;
+ entry.tag.text.stringlen = 0;
+ entry.tag.text.string = NULL;
+ entry.tag.text.color_fg = RGBA8(0, 0, 0, 255);
+ entry.tag.text.color_bg = RGBA8(0, 0, 0, 0);
+ entry.tag.text.done = 0;
+ return AddEntryToBRLYT(brlyt, entry);
+}
+
+int LaichLyt_StartPic(BRLYT* brlyt, char* name)
+{
+ LYTEntry entry;
+ entry.type = LYT_TYPE_PIC;
+ entry.done = 0;
+ entry.tag.pic.pane.alpha = 255;
+ entry.tag.pic.pane.alpha2 = 0;
+ memset(entry.tag.pic.pane.name, 0, 24);
+ strncpy(entry.tag.pic.pane.name, name, 24);
+ entry.tag.pic.pane.x = 0;
+ entry.tag.pic.pane.y = 0;
+ entry.tag.pic.pane.z = 0;
+ entry.tag.pic.pane.rot_x = 0;
+ entry.tag.pic.pane.rot_x = 0;
+ entry.tag.pic.pane.angle = 0;
+ entry.tag.pic.pane.xmag = 0;
+ entry.tag.pic.pane.ymag = 0;
+ entry.tag.pic.pane.width = 0;
+ entry.tag.pic.pane.height = 0;
+ entry.tag.pic.pane.done = 0;
+ entry.tag.pic.colors[0] = RGBA8(0, 0, 0, 255);
+ entry.tag.pic.colors[1] = RGBA8(0, 0, 0, 255);
+ entry.tag.pic.colors[2] = RGBA8(0, 0, 0, 255);
+ entry.tag.pic.colors[3] = RGBA8(0, 0, 0, 255);
+ entry.tag.pic.texcoordcnt = 0;
+ entry.tag.pic.texcoords = NULL;
+ entry.tag.pic.done = 0;
+ return AddEntryToBRLYT(brlyt, entry);
+}
+
+int LaichLyt_StartMat(BRLYT* brlyt)
+{
+ LYTEntry entry;
+ entry.type = LYT_TYPE_MAT;
+ entry.done = 0;
+ entry.tag.mat.done = 0;
+ entry.tag.mat.tev_colors[0] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.tev_colors[1] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.tev_colors[2] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.tev_colors[3] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors[0] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors[1] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors[2] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors[3] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors2[0] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors2[1] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors2[2] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.unk_colors2[3] = RGB565(0, 0, 0, 255);
+ entry.tag.mat.tev_kcolor[0] = RGBA8(0, 0, 0, 255);
+ entry.tag.mat.tev_kcolor[1] = RGBA8(0, 0, 0, 255);
+ entry.tag.mat.tev_kcolor[2] = RGBA8(0, 0, 0, 255);
+ entry.tag.mat.tev_kcolor[3] = RGBA8(0, 0, 0, 255);
+ entry.tag.mat.refcnt = 0;
+ entry.tag.mat.refs = NULL;
+ entry.tag.mat.stage1cnt = 0;
+ entry.tag.mat.stage1s = NULL;
+ entry.tag.mat.stage2cnt = 0;
+ entry.tag.mat.stage2s = NULL;
+ entry.tag.mat.stage3cnt = 0;
+ entry.tag.mat.stage3s = NULL;
+ entry.tag.mat.stage4cnt = 0;
+ entry.tag.mat.stage4s = NULL;
+ entry.tag.mat.stage5cnt = 0;
+ entry.tag.mat.stage5s = NULL;
+ entry.tag.mat.stage6cnt = 0;
+ entry.tag.mat.stage6s = NULL;
+ entry.tag.mat.stage7cnt = 0;
+ entry.tag.mat.stage7s = NULL;
+ entry.tag.mat.stage8cnt = 0;
+ entry.tag.mat.stage8s = NULL;
+ entry.tag.mat.stage9cnt = 0;
+ entry.tag.mat.stage9s = NULL;
+ entry.tag.mat.stage10cnt = 0;
+ entry.tag.mat.stage10s = NULL;
+ return AddEntryToBRLYT(brlyt, entry);
+}
+
+int LaichLyt_StartGroup(BRLYT* brlyt, char* name)
+{
+ LYTEntry entry;
+ entry.type = LYT_TYPE_GROUP;
+ entry.done = 0;
+ memset(entry.tag.grp.name, 0, 16);
+ strncpy(entry.tag.grp.name, name, 16);
+ entry.tag.grp.subcnts = 0;
+ entry.tag.grp.subs = NULL;
+ entry.tag.grp.done = 0;
+ return AddEntryToBRLYT(brlyt, entry);
+}
+
+static void LaichLyt_IntPaneCoords(LYTPane* pane, \
+ float x, float y, float z)
+{
+ pane->x = x;
+ pane->y = y;
+ pane->z = z;
+}
+
+static void LaichLyt_IntPaneRotation(LYTPane* pane, \
+ float rot_x, float rot_y, float angle)
+{
+ pane->rot_x = rot_x;
+ pane->rot_y = rot_y;
+ pane->angle = angle;
+}
+
+static void LaichLyt_IntPaneZoom(LYTPane* pane, \
+ float xmag, float ymag)
+{
+ pane->xmag = xmag;
+ pane->ymag = ymag;
+}
+
+static void LaichLyt_IntPaneSize(LYTPane* pane, \
+ float width, float height)
+{
+ pane->width = width;
+ pane->height = height;
+}
+
+static void LaichLyt_IntPaneAlpha(LYTPane* pane, \
+ u8 alpha, u8 alpha2)
+{
+ pane->alpha = alpha;
+ pane->alpha2 = alpha2;
+}
+
+void LaichLyt_PaneCoords(BRLYT* brlyt, int pane, \
+ float x, float y, float z)
+{
+ LaichLyt_IntPaneCoords(&(brlyt->entries[pane].tag.pane), \
+ x, y, z);
+}
+void LaichLyt_PaneRotation(BRLYT* brlyt, int pane, \
+ float rot_x, float rot_y, float angle)
+{
+ LaichLyt_IntPaneRotation(&(brlyt->entries[pane].tag.pane), \
+ rot_x, rot_y, angle);
+}
+void LaichLyt_PaneZoom(BRLYT* brlyt, int pane, \
+ float xmag, float ymag)
+{
+ LaichLyt_IntPaneZoom(&(brlyt->entries[pane].tag.pane), \
+ xmag, ymag);
+}
+void LaichLyt_PaneSize(BRLYT* brlyt, int pane, \
+ float width, float height)
+{
+ LaichLyt_IntPaneSize(&(brlyt->entries[pane].tag.pane), \
+ width, height);
+}
+void LaichLyt_PaneAlpha(BRLYT* brlyt, int pane, \
+ u8 alpha, u8 alpha2)
+{
+ LaichLyt_IntPaneAlpha(&(brlyt->entries[pane].tag.pane), \
+ alpha, alpha2);
+}
+
+void LaichLyt_TextCoords(BRLYT* brlyt, int text, \
+ float x, float y, float z)
+{
+ LaichLyt_IntPaneCoords(&(brlyt->entries[text].tag.text.pane), \
+ x, y, z);
+}
+void LaichLyt_TextRotation(BRLYT* brlyt, int text, \
+ float rot_x, float rot_y, float angle)
+{
+ LaichLyt_IntPaneRotation(&(brlyt->entries[text].tag.text.pane), \
+ rot_x, rot_y, angle);
+}
+void LaichLyt_TextZoom(BRLYT* brlyt, int text, \
+ float xmag, float ymag)
+{
+ LaichLyt_IntPaneZoom(&(brlyt->entries[text].tag.text.pane), \
+ xmag, ymag);
+}
+void LaichLyt_TextSize(BRLYT* brlyt, int text, \
+ float width, float height)
+{
+ LaichLyt_IntPaneSize(&(brlyt->entries[text].tag.text.pane), \
+ width, height);
+}
+void LaichLyt_TextAlpha(BRLYT* brlyt, int text, \
+ u8 alpha, u8 alpha2)
+{
+ LaichLyt_IntPaneAlpha(&(brlyt->entries[text].tag.text.pane), \
+ alpha, alpha2);
+}
+
+void LaichLyt_PicCoords(BRLYT* brlyt, int pic, \
+ float x, float y, float z)
+{
+ LaichLyt_IntPaneCoords(&(brlyt->entries[pic].tag.pic.pane), \
+ x, y, z);
+}
+void LaichLyt_PicRotation(BRLYT* brlyt, int pic, \
+ float rot_x, float rot_y, float angle)
+{
+ LaichLyt_IntPaneRotation(&(brlyt->entries[pic].tag.pic.pane), \
+ rot_x, rot_y, angle);
+}
+void LaichLyt_PicZoom(BRLYT* brlyt, int pic, \
+ float xmag, float ymag)
+{
+ LaichLyt_IntPaneZoom(&(brlyt->entries[pic].tag.pic.pane), \
+ xmag, ymag);
+}
+void LaichLyt_PicSize(BRLYT* brlyt, int pic, \
+ float width, float height)
+{
+ LaichLyt_IntPaneSize(&(brlyt->entries[pic].tag.pic.pane), \
+ width, height);
+}
+void LaichLyt_PicAlpha(BRLYT* brlyt, int pic, \
+ u8 alpha, u8 alpha2)
+{
+ LaichLyt_IntPaneAlpha(&(brlyt->entries[pic].tag.pic.pane), \
+ alpha, alpha2);
+}
+
+
+void LaichLyt_TextFont(BRLYT* brlyt, int text, \
+ LYTFont font)
+{
+ brlyt->entries[text].tag.text.font = font;
+}
+
+void LaichLyt_TextString(BRLYT* brlyt, int text, \
+ u16* string, int stringlen)
+{
+ brlyt->entries[text].tag.text.string = malloc(stringlen * 2);
+ memcpy(brlyt->entries[text].tag.text.string, string, stringlen * 2);
+ brlyt->entries[text].tag.text.stringlen = stringlen;
+}
+
+void LaichLyt_TextColors(BRLYT* brlyt, int text, \
+ u32 fg, u32 bg)
+{
+ brlyt->entries[text].tag.text.color_fg = fg;
+ brlyt->entries[text].tag.text.color_bg = bg;
+}
+
+
+void LaichLyt_PicColors(BRLYT* brlyt, int pic, \
+ u32 color1, u32 color2, u32 color3, u32 color4)
+{
+ brlyt->entries[pic].tag.pic.colors[0] = color1;
+ brlyt->entries[pic].tag.pic.colors[1] = color2;
+ brlyt->entries[pic].tag.pic.colors[2] = color3;
+ brlyt->entries[pic].tag.pic.colors[3] = color4;
+}
+
+void LaichLyt_PicAddTexCoord(BRLYT* brlyt, int pic, \
+ float coords[8])
+{
+ LYTTexCoord coord;
+ int i;
+ for(i = 0; i < 8; i++)
+ coord.coords[i] = coords[i];
+ AddTexCoordToPic(brlyt, pic, coord);
+}
+
+
+void LaichLyt_GroupAddSub(BRLYT* brlyt, int group, \
+ char* subname)
+{
+ LYTSub sub;
+ memset(sub.name, 0, 16);
+ strncpy(sub.name, subname, 16);
+ AddSubToGroup(brlyt, group, sub);
+}
+
+
+
+
+static void LaichLyt_EndEntry(BRLYT* brlyt, int tag)
+{
+ switch(brlyt->entries[tag].type) {
+ case LYT_TYPE_GROUP:
+ brlyt->entries[tag].tag.grp.done = 1;
+ break;
+
+ case LYT_TYPE_MAT:
+ brlyt->entries[tag].tag.mat.done = 1;
+ break;
+
+ case LYT_TYPE_PANE:
+ brlyt->entries[tag].tag.pane.done = 1;
+ break;
+
+ case LYT_TYPE_TEXT:
+ brlyt->entries[tag].tag.text.done = 1;
+ brlyt->entries[tag].tag.text.pane.done = 1;
+ break;
+
+ case LYT_TYPE_PIC:
+ brlyt->entries[tag].tag.pic.done = 1;
+ brlyt->entries[tag].tag.pic.pane.done = 1;
+ break;
+
+ default: // lolwut
+ return;
+ }
+ brlyt->entries[tag].done = 1;
+}
+
+void LaichLyt_EndGroup(BRLYT* brlyt, int group)
+{
+ LaichLyt_EndEntry(brlyt, group);
+}
+
+void LaichLyt_EndMat(BRLYT* brlyt, int mat)
+{
+ LaichLyt_EndEntry(brlyt, mat);
+}
+
+void LaichLyt_EndPic(BRLYT* brlyt, int pic)
+{
+ LaichLyt_EndEntry(brlyt, pic);
+}
+
+void LaichLyt_EndText(BRLYT* brlyt, int text)
+{
+ LaichLyt_EndEntry(brlyt, text);
+}
+
+void LaichLyt_EndPane(BRLYT* brlyt, int pane)
+{
+ LaichLyt_EndEntry(brlyt, pane);
+}
diff --git a/laichzeit/brlyt.h b/laichzeit/brlyt.h
new file mode 100644
index 0000000..2588d78
--- /dev/null
+++ b/laichzeit/brlyt.h
@@ -0,0 +1,345 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* brlyt.h */
+/* The header file for all the BRLYT stuff. Include this! */
+/* ------------------------------------------------------------------------- */
+/* Compilation code contributed by: */
+/* megazig */
+/* Intermediation code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#ifndef BRLYT_H
+#define BRLYT_H
+
+#include "types.h"
+
+#define USE_BRLYT
+
+typedef enum
+{
+ LYT_FONT_DEFAULT = 0 // Default.
+} LYTFont;
+
+typedef enum
+{
+ LYT_TYPE_PANE = 0, // Panes.
+ LYT_TYPE_TEXT = 1, // Text.
+ LYT_TYPE_PIC = 2, // Pictures.
+ LYT_TYPE_MAT = 3, // Materials.
+ LYT_TYPE_GROUP = 4 // Groups.
+} LYTType;
+
+typedef struct
+{
+ u8 alpha; // The alpha.
+ u8 alpha2; // Always 0. Seems to deal with alpha.
+ char name[24]; // Name of pane.
+ float x; // Starting X location.
+ float y; // Starting Y location.
+ float z; // Starting Z location.
+ float rot_x; // Starting X flip rotation.
+ float rot_y; // Starting Y flip rotation.
+ float angle; // Starting rotation.
+ float xmag; // Starting X zoom.
+ float ymag; // Starting Y zoom.
+ float width; // Starting width.
+ float height; // Starting height.
+ int done; // Is it done? (Safety measure)
+} LYTPane;
+
+typedef struct
+{
+ LYTPane pane; // The Pane.
+ LYTFont font; // Which font to use.
+ int stringlen; // How many [UTF16] letters in string.
+ u16* string; // The string (UTF16)
+ u32 color_fg; // Foreground color.
+ u32 color_bg; // Background color.
+ int done; // Is it done? (Safety measure)
+} LYTText;
+
+typedef struct
+{
+ float coords[8]; // The coordinates.
+} LYTTexCoord;
+
+typedef struct
+{
+ LYTPane pane; // The Pane.
+ u32 colors[4]; // Vertex Colors.
+ u8 texcoordcnt; // Number of Texture Coordinates.
+ LYTTexCoord* texcoords; // Texture coordinates.
+ int done; // Is it done? (Safety measure)
+} LYTPic;
+
+typedef struct
+{
+ char name[16]; // Name of the sub.
+} LYTSub;
+
+typedef struct
+{
+ char name[16]; // Name of the group.
+ int subcnts; // How many subs?
+ LYTSub* subs; // The subs.
+ int done; // Is it done? (Safety measure)
+} LYTGroup;
+
+typedef struct
+{
+ u32 wrap_s; // S wrapping.
+ u32 wrap_t; // T wrapping.
+} LYTTexRef;
+
+typedef struct
+{
+ float unk1; // Something.
+ float unk2; // Something.
+ float unk3; // Something.
+ float unk4; // Something.
+ float unk5; // Something.
+} LYTStage1;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+} LYTStage2;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+} LYTStage3;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+} LYTStage4;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+} LYTStage5;
+
+typedef struct
+{
+ u32 a; // Something.
+ u32 b; // Something.
+ u32 c; // Something.
+ u32 d; // Something.
+ u32 e; // Something.
+} LYTStage6;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+} LYTStage7;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+ u8 unk5; // Something.
+ u8 unk6; // Something.
+ u8 unk7; // Something.
+ u8 unk8; // Something.
+ u8 unk9; // Something.
+ u8 unk10; // Something.
+ u8 unk11; // Something.
+ u8 unk12; // Something.
+ u8 unk13; // Something.
+ u8 unk14; // Something.
+ u8 unk15; // Something.
+ u8 unk16; // Something.
+} LYTStage8;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+} LYTStage9;
+
+typedef struct
+{
+ u8 unk1; // Something.
+ u8 unk2; // Something.
+ u8 unk3; // Something.
+ u8 unk4; // Something.
+} LYTStage10;
+
+typedef struct
+{
+ u16 tev_colors[4]; // Colors.
+ u16 unk_colors[4]; // Colors.
+ u16 unk_colors2[4]; // Colors.
+ u32 tev_kcolor[4]; // Colors.
+ int refcnt; // Number of Texture references.
+ LYTTexRef* refs; // The Texture references.
+ int stage1cnt; // Number of Stage1s.
+ LYTStage1* stage1s; // The Stage1s.
+ int stage2cnt; // Number of Stage2s.
+ LYTStage2* stage2s; // The Stage2s.
+ int stage3cnt; // Number of Stage3s.
+ LYTStage3* stage3s; // The Stage3s.
+ int stage4cnt; // Number of Stage4s.
+ LYTStage4* stage4s; // The Stage4s.
+ int stage5cnt; // Number of Stage5s.
+ LYTStage5* stage5s; // The Stage5s.
+ int stage6cnt; // Number of Stage6s.
+ LYTStage6* stage6s; // The Stage6s.
+ int stage7cnt; // Number of Stage7s.
+ LYTStage7* stage7s; // The Stage7s.
+ int stage8cnt; // Number of Stage8s.
+ LYTStage8* stage8s; // The Stage8s.
+ int stage9cnt; // Number of Stage9s.
+ LYTStage9* stage9s; // The Stage9s.
+ int stage10cnt; // Number of Stage10s.
+ LYTStage10* stage10s; // The Stage10s.
+ int done; // Is it done? (Safety measure)
+} LYTMat;
+
+typedef union
+{
+ LYTPane pane; // Pane.
+ LYTText text; // Text.
+ LYTPic pic; // Picture.
+ LYTMat mat; // Material.
+ LYTGroup grp; // Group.
+} LYTTag;
+
+typedef struct
+{
+ LYTType type; // Kind of entry.
+ LYTTag tag; // The tag.
+ int done; // Is it done? (Safety measure)
+} LYTEntry;
+
+typedef struct
+{
+ float width; // Width of banner.
+ float height; // Height of banner.
+ int entrycnt; // How many entries.
+ LYTEntry* entries; // The entries.
+} BRLYT;
+
+BRLYT* LaichLyt_Start(float width, float height);
+int LaichLyt_StartPane (BRLYT* brlyt, char* name);
+int LaichLyt_StartText (BRLYT* brlyt, char* name);
+int LaichLyt_StartPic (BRLYT* brlyt, char* name);
+int LaichLyt_StartMat (BRLYT* brlyt);
+int LaichLyt_StartGroup(BRLYT* brlyt, char* name);
+
+/* Pane stuff */
+void LaichLyt_PaneCoords(BRLYT* brlyt, int pane, \
+ float x, float y, float z);
+void LaichLyt_PaneRotation(BRLYT* brlyt, int pane, \
+ float rot_x, float rot_y, float angle);
+void LaichLyt_PaneZoom(BRLYT* brlyt, int pane, \
+ float xmag, float ymag);
+void LaichLyt_PaneSize(BRLYT* brlyt, int pane, \
+ float width, float height);
+void LaichLyt_PaneAlpha(BRLYT* brlyt, int pane, \
+ u8 alpha, u8 alpha2);
+
+/* Panes exist in Text and Pic tags, so we gotta create those too!*/
+void LaichLyt_TextCoords(BRLYT* brlyt, int text, \
+ float x, float y, float z);
+void LaichLyt_TextRotation(BRLYT* brlyt, int text, \
+ float rot_x, float rot_y, float angle);
+void LaichLyt_TextZoom(BRLYT* brlyt, int text, \
+ float xmag, float ymag);
+void LaichLyt_TextSize(BRLYT* brlyt, int text, \
+ float width, float height);
+void LaichLyt_TextAlpha(BRLYT* brlyt, int text, \
+ u8 alpha, u8 alpha2);
+void LaichLyt_PicCoords(BRLYT* brlyt, int pic, \
+ float x, float y, float z);
+void LaichLyt_PicRotation(BRLYT* brlyt, int pic, \
+ float rot_x, float rot_y, float angle);
+void LaichLyt_PicZoom(BRLYT* brlyt, int pic, \
+ float xmag, float ymag);
+void LaichLyt_PicSize(BRLYT* brlyt, int pic, \
+ float width, float height);
+void LaichLyt_PicAlpha(BRLYT* brlyt, int pic, \
+ u8 alpha, u8 alpha2);
+
+/* Text stuff */
+void LaichLyt_TextFont(BRLYT* brlyt, int text, \
+ LYTFont font);
+void LaichLyt_TextString(BRLYT* brlyt, int text, \
+ u16* string, int stringlen);
+void LaichLyt_TextColors(BRLYT* brlyt, int text, \
+ u32 fg, u32 bg);
+
+/* Pic stuff */
+void LaichLyt_PicColors(BRLYT* brlyt, int pic, \
+ u32 color1, u32 color2, u32 color3, u32 color4);
+void LaichLyt_PicAddTexCoord(BRLYT* brlyt, int pic, \
+ float coords[8]);
+
+/* Group stuff */
+void LaichLyt_GroupAddSub(BRLYT* brlyt, int group, \
+ char* subname);
+
+/* Material stuff */
+void LaichLyt_MatColors(BRLYT* brlyt, int mat, \
+ u16 tev_colors[4], u16 unk_colors[4], \
+ u16 unk_colors2[4], u32 tev_kcolor[4]);
+void LaichLyt_MatAddTexRef(BRLYT* brlyt, int mat, \
+ u32 wrap_s, u32 wrap_t);
+void LaichLyt_MatAddStage1(BRLYT* brlyt, int mat, \
+ float unk1, float unk2, float unk3, \
+ float unk4, float unk5);
+void LaichLyt_MatAddStage2(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4);
+void LaichLyt_MatAddStage3(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4);
+void LaichLyt_MatAddStage4(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4);
+void LaichLyt_MatAddStage5(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4);
+void LaichLyt_MatAddStage6(BRLYT* brlyt, int mat, \
+ u32 a, u32 b, u32 c, u32 d, u32 e);
+void LaichLyt_MatAddStage7(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4);
+void LaichLyt_MatAddStage8(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4, \
+ u8 unk5, u8 unk6, u8 unk7, u8 unk8, \
+ u8 unk9, u8 unk10, u8 unk11, u8 unk12, \
+ u8 unk13, u8 unk14, u8 unk15, u8 unk16);
+void LaichLyt_MatAddStage9(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4);
+void LaichLyt_MatAddStage10(BRLYT* brlyt, int mat, \
+ u8 unk1, u8 unk2, u8 unk3, u8 unk4);
+
+void LaichLyt_EndGroup(BRLYT* brlyt, int group);
+void LaichLyt_EndMat (BRLYT* brlyt, int mat );
+void LaichLyt_EndPic (BRLYT* brlyt, int pic );
+void LaichLyt_EndText (BRLYT* brlyt, int text );
+void LaichLyt_EndPane (BRLYT* brlyt, int pane );
+u8* LaichLyt_Compile(BRLYT* brlyt);
+
+
+#endif //BRLYT_H
diff --git a/laichzeit/c_oop.c b/laichzeit/c_oop.c
new file mode 100644
index 0000000..95c1083
--- /dev/null
+++ b/laichzeit/c_oop.c
@@ -0,0 +1,32 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* c_oop.c */
+/* Object orientation shit for C. Compile this! */
+/* ------------------------------------------------------------------------- */
+/* Code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "c_oop.h"
+
+int AddObjectToList(u8** listv, u32* listcnt, u8* object, u32 size)
+{
+ *listcnt++;
+ u8* list = *(u8**)listv;
+ u8* entries = calloc(size, *listcnt);
+ if(list != NULL) {
+ memcpy(entries, list, size * (*listcnt - 1));
+ free(list);
+ }
+ memcpy(&entries[(*listcnt - 1) * size], object, size);
+ *(u8**)listv = entries;
+ return *listcnt - 1;
+}
+
diff --git a/laichzeit/c_oop.h b/laichzeit/c_oop.h
new file mode 100644
index 0000000..8864f0e
--- /dev/null
+++ b/laichzeit/c_oop.h
@@ -0,0 +1,20 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* c_oop.h */
+/* Object orientation shit for C. Include this! */
+/* ------------------------------------------------------------------------- */
+/* Code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#ifndef C_OOP_H
+#define C_OOP_H
+
+#include "types.h"
+
+int AddObjectToList(u8** listv, u32* listcnt, u8* object, u32 size);
+
+#endif //C_OOP_H
diff --git a/laichzeit/soundbin.c b/laichzeit/soundbin.c
new file mode 100644
index 0000000..4357822
--- /dev/null
+++ b/laichzeit/soundbin.c
@@ -0,0 +1,15 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* soundbin.c */
+/* The code for all the sound.bin stuff. Compile this! */
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "soundbin.h"
+
diff --git a/laichzeit/soundbin.h b/laichzeit/soundbin.h
new file mode 100644
index 0000000..9abac15
--- /dev/null
+++ b/laichzeit/soundbin.h
@@ -0,0 +1,17 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* soundbin.h */
+/* The header file for all the sound.bin stuff. Include this! */
+/*****************************************************************************/
+
+#ifndef SOUNDBIN_H
+#define SOUNDBIN_H
+
+#include "types.h"
+
+//#define USE_SOUNDBIN
+
+#endif //SOUNDBIN_H
diff --git a/laichzeit/tpl.c b/laichzeit/tpl.c
new file mode 100644
index 0000000..e2e62a3
--- /dev/null
+++ b/laichzeit/tpl.c
@@ -0,0 +1,515 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* tpl.c */
+/* The code for all the TPL stuff. Compile this! */
+/* ------------------------------------------------------------------------- */
+/* Most code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gd.h>
+
+#include "types.h"
+#include "tpl.h"
+#include "c_oop.h"
+
+static int AddImageToTPL(TPL* tpl, TPLImage img)
+{
+ return AddObjectToList((u8**)&tpl->imgs, (u32*)&tpl->imgcnt, \
+ (u8*)&img, sizeof(TPLImage));
+}
+
+TPL* LaichTPL_Start()
+{
+ TPL* tpl = malloc(sizeof(TPL));
+ tpl->imgcnt = 0;
+ tpl->imgs = NULL;
+ return tpl;
+}
+
+int LaichTPL_StartImage(TPL* tpl, char* file)
+{
+ TPLImage img;
+ img.done = 0;
+ img.header.height = 0;
+ img.header.width = 0;
+ img.header.format = TPL_FORMAT_RGBA8;
+ img.header.offs = 0;
+ img.header.wrap_s = 0;
+ img.header.wrap_t = 0;
+ img.header.min = 0;
+ img.header.mag = 0;
+ img.header.lod_bias = 0;
+ img.header.edge_lod = 0;
+ img.header.min_lod = 0;
+ img.header.max_lod = 0;
+ img.header.unpacked = 0;
+ memset(img.filename, 0, 256);
+ strncpy(img.filename, file, 256);
+ return AddImageToTPL(tpl, img);
+}
+
+void LaichTPL_SetImageFormat(TPL* tpl, int img, TPLFormat format)
+{
+ tpl->imgs[img].header.format = format;
+}
+
+void LaichTPL_SetImageWrap(TPL* tpl, int img, u32 s, u32 t)
+{
+ tpl->imgs[img].header.wrap_s = s;
+ tpl->imgs[img].header.wrap_t = t;
+}
+
+void LaichTPL_SetImageFilters(TPL* tpl, int img, u32 min, u32 mag)
+{
+ tpl->imgs[img].header.min = min;
+ tpl->imgs[img].header.mag = mag;
+}
+
+void LaichTPL_SetImageLOD(TPL* tpl, int img, \
+ f32 lod_bias, u8 edge_lod, u8 min_lod, u8 max_lod)
+{
+ tpl->imgs[img].header.lod_bias = lod_bias;
+ tpl->imgs[img].header.edge_lod = edge_lod;
+ tpl->imgs[img].header.min_lod = min_lod;
+ tpl->imgs[img].header.max_lod = max_lod;
+}
+
+void LaichTPL_EndImage(TPL* tpl, int img)
+{
+ tpl->imgs[img].done = 1;
+}
+
+static int TPL_ConvertBitMapToRGB565(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width, u32 height)
+{
+ s32 x, y;
+ s32 x1, y1;
+ u32 iv;
+ u8* subbitmapdata = bitmapdata;
+ if(subbitmapdata == NULL)
+ return -1;
+ *tplbuf = (u8*)calloc(align(width, 4) * align(height, 4), 2);
+ if(*tplbuf == NULL)
+ return -1;
+ u8* writebuf = *tplbuf;
+ u32 outsz = align(width, 4) * align(height, 4) * 2;
+ for(iv = 0, y1 = 0; y1 < height; y1 += 4) {
+ for(x1 = 0; x1 < width; x1 += 4) {
+ for(y = y1; y < (y1 + 4); y++) {
+ for(x = x1; x < (x1 + 4); x++) {
+ u16 newpixel = 0;
+ if((x >= width) || (y >= height))
+ newpixel = 0;
+ else {
+ u32 rgba = ((u32*)subbitmapdata)[x + (y * width)];
+ u8 r = (rgba >> 0) & 0xFF;
+ u8 g = (rgba >> 8) & 0xFF;
+ u8 b = (rgba >> 16) & 0xFF;
+ // u8 a = (rgba >> 24) & 0xFF;
+
+ newpixel = ((b >> 3) << 11) | ((g >> 2) << 5) | ((r >> 3) << 0);
+ }
+ ((u16*)writebuf)[iv++] = htons(newpixel);
+ }
+ }
+ }
+ }
+ printf("Converted to 0x%08x bytes of 0x%08x bytes.\n", iv * 2, outsz);
+ fflush(stdout);
+ return outsz;
+}
+
+static int TPL_ConvertBitMapToRGBA8(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width, u32 height)
+{
+ s32 x, y;
+ s32 x1, y1;
+ u32 iv;
+ u8* subbitmapdata = bitmapdata;
+ *tplbuf = (u8*)calloc(align(width, 4) * align(height, 4), 4);
+ if(*tplbuf == NULL)
+ return -1;
+ u32 i;
+ u8* writebuf = *tplbuf;
+ u32 outsz = align(width, 4) * align(height, 4) * 4;
+ i = 0;
+ int z = 0;
+ u32 rgba[32];
+ u32 la[32];
+ u32 lr[32];
+ u32 lg[32];
+ u32 lb[32];
+ for(iv = 0, y1 = 0; y1 < height; y1 += 4) {
+ for(x1 = 0; x1 < width; x1 += 4) {
+ for(y = y1; y < (y1 + 4); y++) {
+ for(x = x1; x < (x1 + 4); x++) {
+ if((x >= width) || (y >= height))
+ rgba[z] = 0;
+ else
+ rgba[z] = ((u32*)subbitmapdata)[x + (y * width)];
+ lr[z] = (rgba[z] >> 0) & 0xFF;
+ lg[z] = (rgba[z] >> 8) & 0xFF;
+ lb[z] = (rgba[z] >> 16) & 0xFF;
+ la[z] = (rgba[z] >> 24) & 0xFF;
+ z++;
+ }
+ }
+ if(z == 16) { // Dump time!
+ for(i = 0; i < 16; i++) {
+ writebuf[iv++] = lr[i];
+ writebuf[iv++] = la[i];
+ }
+ for(i = 0; i < 16; i++) {
+ writebuf[iv++] = lb[i];
+ writebuf[iv++] = lg[i];
+ }
+ z = 0;
+ }
+ }
+ }
+ printf("Converted to 0x%08x bytes of 0x%08x bytes.\n", iv, outsz);
+ fflush(stdout);
+ return outsz;
+}
+
+static int TPL_ConvertBitMapToRGB5A3(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width, u32 height)
+{
+ s32 x, y;
+ s32 x1, y1;
+ u32 iv;
+ u8* subbitmapdata = bitmapdata;
+ if(subbitmapdata == NULL)
+ return -1;
+ *tplbuf = (u8*)calloc(align(width, 4) * align(height, 4), 2);
+ if(*tplbuf == NULL)
+ return -1;
+ u8* writebuf = *tplbuf;
+ u32 outsz = align(width, 4) * align(height, 4) * 2;
+ for(iv = 0, y1 = 0; y1 < height; y1 += 4) {
+ for(x1 = 0; x1 < width; x1 += 4) {
+ for(y = y1; y < (y1 + 4); y++) {
+ for(x = x1; x < (x1 + 4); x++) {
+ u16 newpixel = 0;
+ if((x >= width) || (y >= height))
+ newpixel = 0;
+ else {
+ u32 rgba = ((u32*)subbitmapdata)[x + (y * width)];
+ u8 r = (rgba >> 0) & 0xFF;
+ u8 g = (rgba >> 8) & 0xFF;
+ u8 b = (rgba >> 16) & 0xFF;
+ u8 a = (rgba >> 24) & 0xFF;
+ if(a <= 0xDA) {
+ // We have enough Alpha to matter. Lets use RGB4A3!
+ newpixel |= (1 << 15);
+ r = ((r * 15) / 255) & 0xF;
+ g = ((g * 15) / 255) & 0xF;
+ b = ((b * 15) / 255) & 0xF;
+ a = ((a * 7) / 255) & 0x7;
+ newpixel |= r << 11;
+ newpixel |= g << 7;
+ newpixel |= b << 3;
+ newpixel |= a << 0;
+ }else{
+ // We don't have enough Alpha to matter. Use RGB5.
+ newpixel &= ~(1 << 15);
+ r = ((r * 31) / 255) & 0x1F;
+ g = ((g * 31) / 255) & 0x1F;
+ b = ((b * 31) / 255) & 0x1F;
+ newpixel |= r << 10;
+ newpixel |= g << 5;
+ newpixel |= b << 0;
+ }
+ }
+ ((u16*)writebuf)[iv++] = htobs(newpixel);
+ }
+ }
+ }
+ }
+ printf("Converted to 0x%08x bytes of 0x%08x bytes.\n", iv * 2, outsz);
+ fflush(stdout);
+ return outsz;
+}
+
+static int TPL_ConvertBitMapToI4(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width, u32 height)
+{
+ s32 x, y;
+ s32 x1, y1;
+ u32 iv;
+ u8* subbitmapdata = bitmapdata;
+ if(subbitmapdata == NULL)
+ return -1;
+ *tplbuf = (u8*)calloc(align(width, 4) * align(height, 4) / 2, 1);
+ if(*tplbuf == NULL)
+ return -1;
+ u8* writebuf = *tplbuf;
+ u32 outsz = align(width, 4) * align(height, 4) / 2;
+ for(iv = 0, y1 = 0; y1 < height; y1 += 8) {
+ for(x1 = 0; x1 < width; x1 += 8) {
+ for(y = y1; y < (y1 + 8); y++) {
+ for(x = x1; x < (x1 + 8); x += 2) {
+ u8 newpixel;
+ if((x >= width) || (y >= height))
+ newpixel = 0;
+ else {
+ u32 rgba = ((u32*)subbitmapdata)[x + (y * width)];
+ u8 i1 = (rgba >> 0) & 0xFF;
+ rgba = ((u32*)subbitmapdata)[x + 1 + (y * width)];
+ u8 i2 = (rgba >> 0) & 0xFF;
+
+ newpixel = (((i1 * 15) / 255) << 4);
+ newpixel |= (((i2 * 15) / 255) & 0xF);
+ }
+ ((u8*)writebuf)[iv++] = newpixel;
+ }
+ }
+ }
+ }
+ printf("Converted to 0x%08x bytes of 0x%08x bytes.\n", iv, outsz);
+ fflush(stdout);
+ return outsz;
+}
+
+static int TPL_ConvertBitMapToIA4(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width, u32 height)
+{
+ s32 x, y;
+ s32 x1, y1;
+ u32 iv;
+ u8* subbitmapdata = bitmapdata;
+ if(subbitmapdata == NULL)
+ return -1;
+ *tplbuf = (u8*)calloc(align(width, 4) * align(height, 4), 1);
+ if(*tplbuf == NULL)
+ return -1;
+ u8* writebuf = *tplbuf;
+ u32 outsz = align(width, 4) * align(height, 4);
+ for(iv = 0, y1 = 0; y1 < height; y1 += 4) {
+ for(x1 = 0; x1 < width; x1 += 8) {
+ for(y = y1; y < (y1 + 4); y++) {
+ for(x = x1; x < (x1 + 8); x++) {
+ u8 newpixel;
+ if((x >= width) || (y >= height))
+ newpixel = 0;
+ else {
+ u32 rgba = ((u32*)subbitmapdata)[x + (y * width)];
+ u8 i1 = (rgba >> 0) & 0xFF;
+ u8 a1 = (rgba >> 24) & 0xFF;
+
+ newpixel = (((i1 * 15) / 255) << 4);
+ newpixel |= (((a1 * 15) / 255) & 0xF);
+ }
+ ((u8*)writebuf)[iv++] = newpixel;
+ }
+ }
+ }
+ }
+ printf("Converted to 0x%08x bytes of 0x%08x bytes.\n", iv, outsz);
+ fflush(stdout);
+ return outsz;
+}
+
+static int TPL_ConvertBitMapToI8(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width, u32 height)
+{
+ s32 x, y;
+ s32 x1, y1;
+ u32 iv;
+ u8* subbitmapdata = bitmapdata;
+ if(subbitmapdata == NULL)
+ return -1;
+ *tplbuf = (u8*)calloc(align(width, 4) * align(height, 4), 1);
+ if(*tplbuf == NULL)
+ return -1;
+ u8* writebuf = *tplbuf;
+ u32 outsz = align(width, 4) * align(height, 4);
+ for(iv = 0, y1 = 0; y1 < height; y1 += 4) {
+ for(x1 = 0; x1 < width; x1 += 8) {
+ for(y = y1; y < (y1 + 4); y++) {
+ for(x = x1; x < (x1 + 8); x++) {
+ u32 rgba = ((u32*)subbitmapdata)[x + (y * width)];
+ u8 i1;
+ if((x >= width) || (y >= height))
+ i1 = 0;
+ else
+ i1 = (rgba >> 0) & 0xFF;
+
+ ((u8*)writebuf)[iv++] = i1;
+ }
+ }
+ }
+ }
+ printf("Converted to 0x%08x bytes of 0x%08x bytes.\n", iv, outsz);
+ fflush(stdout);
+ return outsz;
+}
+
+static int TPL_ConvertBitMapToIA8(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width, u32 height)
+{
+ s32 x, y;
+ s32 x1, y1;
+ u32 iv;
+ u8* subbitmapdata = bitmapdata;
+ if(subbitmapdata == NULL)
+ return -1;
+ *tplbuf = (u8*)calloc(align(width, 4) * align(height, 4), 2);
+ if(*tplbuf == NULL)
+ return -1;
+ u8* writebuf = *tplbuf;
+ u32 outsz = align(width, 4) * align(height, 4) * 2;
+ for(iv = 0, y1 = 0; y1 < height; y1 += 4) {
+ for(x1 = 0; x1 < width; x1 += 4) {
+ for(y = y1; y < (y1 + 4); y++) {
+ for(x = x1; x < (x1 + 4); x++) {
+ u16 newpixel;
+ if((x >= width) || (y >= height))
+ newpixel = 0;
+ else{
+ u32 rgba = ((u32*)subbitmapdata)[x + (y * width)];
+ u8 i1 = (rgba >> 0) & 0xFF;
+ u8 a1 = (rgba >> 24) & 0xFF;
+
+ newpixel = i1 << 8;
+ newpixel |= a1;
+ }
+ ((u16*)writebuf)[iv++] = newpixel;
+ }
+ }
+ }
+ }
+ printf("Converted to 0x%08x bytes of 0x%08x bytes.\n", iv * 2, outsz);
+ fflush(stdout);
+ return outsz;
+}
+
+u8* LaichTPL_CompileTPL(TPL* tpl, u32* fsize)
+{
+ FILE *out = fopen("tpl.tmp", "wb");
+ if(out == NULL)
+ return NULL;
+ fflush(stdout);
+ u32 magic = htobl(0x0020af30);
+ u32 header[] = { magic, htobl(tpl->imgcnt), htobl(0xc) };
+ fwrite(header, 4, 3, out);
+
+ int i;
+ for(i = 0; i < tpl->imgcnt; i++) {
+ u32 offsets[] = { htobl(12 + (8 * tpl->imgcnt) + (36 * i)), htobl(0) };
+ fwrite(offsets, 4, 2, out);
+ }
+ u8* imagedatas[256];
+ u32 imagesizes[256];
+ for(i = 0; i < tpl->imgcnt; i++) {
+ FILE* gdfp = fopen(tpl->imgs[i].filename, "rb");
+ gdImagePtr im = gdImageCreateFromPng(gdfp);
+ gdImageAlphaBlending(im, 0);
+ gdImageSaveAlpha(im, 1);
+ fclose(gdfp);
+ u32 width = tpl->imgs[i].header.width;
+ u32 height = tpl->imgs[i].header.height;
+ u32 bitmapsize = width * height * 4;
+ u8* bitmapdata = (u8*)malloc(width * height * 4);
+ memset(bitmapdata, 0, width * height * 4);
+ u8* tplbuf;
+ u32 x, y;
+ for(y = 0; y < height; y++) {
+ for(x = 0; x < width; x++) {
+ u32 p;
+ if(x >= width || y >= height)
+ p = 0;
+ else
+ p = gdImageGetPixel(im, x, y);
+ u8 a = 254 - 2*((u8)gdImageAlpha(im, p));
+ if(a == 254) a++;
+ u8 r = (u8)gdImageRed(im, p);
+ u8 g = (u8)gdImageGreen(im, p);
+ u8 b = (u8)gdImageBlue(im, p);
+ u32 rgba = (r << 8) | (g << 16) | (b << 24) | (a << 0);
+ rgba = htobl(rgba);
+ ((u32*)bitmapdata)[x + (y * width)] = rgba;
+ }
+ }
+ int ret;
+ switch(tpl->imgs[i].header.format) {
+ case TPL_FORMAT_RGB565:
+ ret = TPL_ConvertBitMapToRGB565(bitmapdata, bitmapsize, &tplbuf, width, height);
+ break;
+ case TPL_FORMAT_RGB5A3:
+ ret = TPL_ConvertBitMapToRGB5A3(bitmapdata, bitmapsize, &tplbuf, width, height);
+ break;
+ case TPL_FORMAT_RGBA8:
+ ret = TPL_ConvertBitMapToRGBA8(bitmapdata, bitmapsize, &tplbuf, width, height);
+ break;
+ case TPL_FORMAT_I4:
+ ret = TPL_ConvertBitMapToI4(bitmapdata, bitmapsize, &tplbuf, width, height);
+ break;
+ case TPL_FORMAT_I8:
+ ret = TPL_ConvertBitMapToI8(bitmapdata, bitmapsize, &tplbuf, width, height);
+ break;
+ case TPL_FORMAT_IA4:
+ ret = TPL_ConvertBitMapToIA4(bitmapdata, bitmapsize, &tplbuf, width, height);
+ break;
+ case TPL_FORMAT_IA8:
+ ret = TPL_ConvertBitMapToIA8(bitmapdata, bitmapsize, &tplbuf, width, height);
+ break;
+ case TPL_FORMAT_CMP:
+ ret = -1;
+ break;
+ default:
+ ret = -1;
+ }
+ if(ret == -1) {
+ return NULL;
+ }
+ imagedatas[i] = tplbuf;
+ imagesizes[i] = ret;
+ fflush(stdout);
+ tpl->imgs[i].header.format = htobl(tpl->imgs[i].header.format);
+ tpl->imgs[i].header.offs = htobl(12 + (8 * tpl->imgcnt) + (36 * tpl->imgcnt));
+ printf("Dimensions: %dx%d\n", width, height);
+ tpl->imgs[i].header.width = htobs(tpl->imgs[i].header.width);
+ tpl->imgs[i].header.height = htobs(tpl->imgs[i].header.height);
+ tpl->imgs[i].header.min = htobl(tpl->imgs[i].header.min);
+ tpl->imgs[i].header.mag = htobl(tpl->imgs[i].header.mag);
+ tpl->imgs[i].header.wrap_s = htobl(tpl->imgs[i].header.wrap_s);
+ tpl->imgs[i].header.wrap_t = htobl(tpl->imgs[i].header.wrap_t);
+ tpl->imgs[i].header.lod_bias = htobl(tpl->imgs[i].header.lod_bias);
+ fwrite(&tpl->imgs[i].header.height, 2, 1, out);
+ fwrite(&tpl->imgs[i].header.width, 2, 1, out);
+ fwrite(&tpl->imgs[i].header.format, 4, 1, out);
+ fwrite(&tpl->imgs[i].header.offs, 4, 1, out);
+ fwrite(&tpl->imgs[i].header.wrap_s, 4, 1, out);
+ fwrite(&tpl->imgs[i].header.wrap_t, 4, 1, out);
+ fwrite(&tpl->imgs[i].header.min, 4, 1, out);
+ fwrite(&tpl->imgs[i].header.mag, 4, 1, out);
+ fwrite(&tpl->imgs[i].header.lod_bias, 4, 1, out);
+ fwrite(&tpl->imgs[i].header.edge_lod, 1, 1, out);
+ fwrite(&tpl->imgs[i].header.min_lod, 1, 1, out);
+ fwrite(&tpl->imgs[i].header.max_lod, 1, 1, out);
+ fwrite(&tpl->imgs[i].header.unpacked, 1, 1, out);
+ fflush(out);
+ }
+ for(i = 0; i < tpl->imgcnt; i++) {
+ fwrite(imagedatas[i], imagesizes[i], 1, out);
+ fflush(out);
+ free(imagedatas[i]);
+ }
+ fclose(out);
+ out = fopen("tpl.tmp", "rb");
+ fseek(out, 0, SEEK_END);
+ u32 filesize = ftell(out);
+ u8* filedata = malloc(filesize);
+ fseek(out, 0, SEEK_SET);
+ fread(filedata, filesize, 1, out);
+ fflush(out);
+ fclose(out);
+ remove("tpl.tmp");
+ if(fsize != NULL)
+ *fsize = filesize;
+ return filedata;
+}
+
+
+
diff --git a/laichzeit/tpl.h b/laichzeit/tpl.h
new file mode 100644
index 0000000..443dc52
--- /dev/null
+++ b/laichzeit/tpl.h
@@ -0,0 +1,85 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* tpl.h */
+/* The header file for all the TPL stuff. Include this! */
+/* ------------------------------------------------------------------------- */
+/* Most code contributed by: */
+/* SquidMan */
+/*****************************************************************************/
+
+#ifndef TPL_H
+#define TPL_H
+
+#include "types.h"
+
+#define USE_TPL
+
+typedef enum {
+ // I4 (4 bit intensity, 8x8 tiles)
+ TPL_FORMAT_I4 = 0,
+ // I8 (8 bit intensity, 8x4 tiles)
+ TPL_FORMAT_I8 = 1,
+ // IA4 (4 bit intensity with 4 bit alpha, 8x4 tiles)
+ TPL_FORMAT_IA4 = 2,
+ // IA8 (8 bit intensity with 8 bit alpha, 4x4 tiles)
+ TPL_FORMAT_IA8 = 3,
+
+ // RGB565 (4x4 tiles)
+ TPL_FORMAT_RGB565 = 4,
+ // RGB5A3 (*) (4x4 tiles)
+ TPL_FORMAT_RGB5A3 = 5,
+ // RGBA8 (4x4 tiles in two cache lines - first is AR and second is GB)
+ TPL_FORMAT_RGBA8 = 6,
+
+ // CI4 (4 bit color index, 8x8 tiles)
+ TPL_FORMAT_CI4 = 8,
+ // CI8 (8 bit color index, 8x4 tiles)
+ TPL_FORMAT_CI8 = 9,
+ // CI14X2 (14 bit color index, 4x4 tiles)
+ TPL_FORMAT_CI14X2 = 10,
+
+ // CMP (S3TC compressed, 2x2 blocks of 4x4 tiles)
+ TPL_FORMAT_CMP = 14
+} TPLFormat;
+
+typedef struct {
+ u16 height; // Height of the TPL image.
+ u16 width; // Width of the TPL image.
+ TPLFormat format; // Format of the TPL image.
+ u32 offs; // Offset to actual image data.
+ u32 wrap_s; // Wrap S.
+ u32 wrap_t; // Wrap T.
+ u32 min; // Min filter.
+ u32 mag; // Mag filter.
+ f32 lod_bias; // LOD Bias?
+ u8 edge_lod; // Edge LOD?
+ u8 min_lod; // Minimum LOD?
+ u8 max_lod; // Maximum LOD?
+ u8 unpacked; // Unpacked?
+} TPLHeader;
+
+typedef struct {
+ char filename[256]; // Filename.
+ TPLHeader header; // Header.
+ int done; // Is it done?
+} TPLImage;
+
+typedef struct {
+ int imgcnt; // How many TPLs
+ TPLImage* imgs; // The TPLs
+} TPL;
+
+TPL* LaichTPL_Start();
+int LaichTPL_StartImage(TPL* tpl, char* file);
+void LaichTPL_SetImageFormat(TPL* tpl, int img, TPLFormat format);
+void LaichTPL_SetImageWrap(TPL* tpl, int img, u32 s, u32 t);
+void LaichTPL_SetImageFilters(TPL* tpl, int img, u32 min, u32 mag);
+void LaichTPL_SetImageLOD(TPL* tpl, int img, \
+ f32 lod_bias, u8 edge_lod, u8 min_lod, u8 max_lod);
+void LaichTPL_EndImage(TPL* tpl, int img);
+u8* LaichTPL_CompileTPL(TPL* tpl, u32* fsize);
+
+#endif //TPL_H
diff --git a/laichzeit/types.h b/laichzeit/types.h
new file mode 100755
index 0000000..01fc038
--- /dev/null
+++ b/laichzeit/types.h
@@ -0,0 +1,87 @@
+/*****************************************************************************/
+/* Laichzeit */
+/* Part of the Benzin Project */
+/* Copyright (c)2009 HACKERCHANNEL. Protected under the GNU GPLv2. */
+/* ------------------------------------------------------------------------- */
+/* types.h */
+/* Typedefs for stuff. Keep this! */
+/*****************************************************************************/
+
+#ifndef TYPEDEFS_H
+#define TYPEDEFS_H
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+typedef unsigned long long u64;
+
+typedef signed char s8;
+typedef signed short s16;
+typedef signed long s32;
+typedef signed long long s64;
+
+typedef float f32;
+typedef double f64;
+
+
+typedef volatile unsigned char vu8;
+typedef volatile unsigned short vu16;
+typedef volatile unsigned long vu32;
+typedef volatile unsigned long long vu64;
+
+typedef volatile signed char vs8;
+typedef volatile signed short vs16;
+typedef volatile signed long vs32;
+typedef volatile signed long long vs64;
+
+typedef volatile float vf32;
+typedef volatile double vf64;
+
+
+// Switch these if you're on a big endian machine.
+#define LENDIAN
+//#define BENDIAN
+
+#define be16(x) ((u16)( \
+ ((((u16)(x)) >> 8) & 0x00FF) | \
+ ((((u16)(x)) << 8) & 0xFF00) \
+ ))
+
+#define be32(x) ((u32)( \
+ ((((u32)(x)) << 24) & 0xFF000000) | \
+ ((((u32)(x)) << 8) & 0x00FF0000) | \
+ ((((u32)(x)) >> 8) & 0x0000FF00) | \
+ ((((u32)(x)) >> 24) & 0x000000FF) \
+ ))
+
+#define be64(x) ((u64)( \
+ ((((u64)(x)) << 56) & 0xFF00000000000000LL) | \
+ ((((u64)(x)) << 40) & 0x00FF000000000000LL) | \
+ ((((u64)(x)) << 24) & 0x0000FF0000000000LL) | \
+ ((((u64)(x)) << 8) & 0x000000FF00000000LL) | \
+ ((((u64)(x)) >> 8) & 0x00000000FF000000LL) | \
+ ((((u64)(x)) >> 24) & 0x0000000000FF0000LL) | \
+ ((((u64)(x)) >> 40) & 0x000000000000FF00LL) | \
+ ((((u64)(x)) >> 56) & 0x00000000000000FFLL) \
+ ))
+
+#ifdef LENDIAN
+#define htobs(x) be16(x)
+#define htobl(x) be32(x)
+#define htobll(x) be64(x)
+#endif //LENDIAN
+
+#ifdef BENDIAN
+#define htobs (x)
+#define htobl (x)
+#define htobll (x)
+#endif //BENDIAN
+
+#define btohs htobs
+#define btohl htobl
+#define btohll htobll
+
+// Makes x a multiple of y, ceiling style.
+#define align(x, y) ((x) + ((x) % (y)))
+
+#endif //TYPEDEFS_H