diff options
Diffstat (limited to 'player/brlan.c')
| -rw-r--r-- | player/brlan.c | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/player/brlan.c b/player/brlan.c new file mode 100644 index 0000000..5fc7d7b --- /dev/null +++ b/player/brlan.c @@ -0,0 +1,215 @@ +/* + * brlan.c + * BannerPlayer + * + * Created by Alex Marshall on 09/03/16. + * Copyright 2009 __MyCompanyName__. All rights reserved. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "brlan.h" +#include "types.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); +} + + + + + + + + + + + + |
