2012-07-03 18:26:49 +02:00
|
|
|
/*
|
|
|
|
Copyright (c) 2010 - Wii Banner Player Project
|
|
|
|
Copyright (c) 2012 - Dimok
|
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
arising from the use of this software.
|
|
|
|
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
freely, subject to the following restrictions:
|
|
|
|
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
|
|
claim that you wrote the original software. If you use this software
|
|
|
|
in a product, an acknowledgment in the product documentation would be
|
|
|
|
appreciated but is not required.
|
|
|
|
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
misrepresented as being the original software.
|
|
|
|
|
|
|
|
3. This notice may not be removed or altered from any source
|
|
|
|
distribution.
|
|
|
|
*/
|
|
|
|
#include <malloc.h>
|
|
|
|
#include "U8Archive.h"
|
|
|
|
#include "LanguageCode.h"
|
|
|
|
#include "AnimatedBanner.h"
|
|
|
|
#include "text.hpp"
|
|
|
|
#include "lz77.h"
|
|
|
|
#include "ash.h"
|
|
|
|
|
2012-07-03 19:33:24 +02:00
|
|
|
AnimatedBanner::AnimatedBanner()
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
layout_banner = NULL;
|
|
|
|
newBanner = NULL;
|
2012-07-03 19:33:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AnimatedBanner::LoadFont(u8 *font1, u8 *font2)
|
|
|
|
{
|
2012-07-03 18:26:49 +02:00
|
|
|
sysFont1 = font1;
|
|
|
|
sysFont2 = font2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AnimatedBanner::Clear()
|
|
|
|
{
|
2012-07-27 19:26:49 +02:00
|
|
|
if(layout_banner != NULL)
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
delete layout_banner;
|
|
|
|
layout_banner = NULL;
|
|
|
|
}
|
2012-07-27 19:26:49 +02:00
|
|
|
if(newBanner != NULL)
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
2012-07-27 19:26:49 +02:00
|
|
|
free(newBanner);
|
2012-07-03 18:26:49 +02:00
|
|
|
newBanner = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AnimatedBanner::LoadBanner(Banner *banner)
|
|
|
|
{
|
|
|
|
u32 banner_bin_size;
|
2012-07-27 19:26:49 +02:00
|
|
|
u8 *banner_bin = banner->GetFile((char*)"banner.bin", &banner_bin_size);
|
2012-07-03 18:26:49 +02:00
|
|
|
if(banner_bin == NULL)
|
|
|
|
return false;
|
2012-07-27 19:26:49 +02:00
|
|
|
bool ret = LoadBannerBin(banner_bin, banner_bin_size);
|
|
|
|
free(banner_bin);
|
|
|
|
return ret;
|
2012-07-06 02:36:45 +02:00
|
|
|
}
|
2012-07-03 18:26:49 +02:00
|
|
|
|
2012-07-27 19:26:49 +02:00
|
|
|
bool AnimatedBanner::LoadBannerBin(u8 *banner_bin, u32 banner_bin_size)
|
2012-07-06 02:36:45 +02:00
|
|
|
{
|
|
|
|
Clear();
|
2012-07-03 18:26:49 +02:00
|
|
|
layout_banner = LoadLayout(banner_bin, banner_bin_size, "banner", CONF_GetLanguageString());
|
|
|
|
return (layout_banner != NULL);
|
|
|
|
}
|
|
|
|
|
2012-07-06 02:36:45 +02:00
|
|
|
void AnimatedBanner::SetBannerText(const char *text_name, const wchar_t *wText)
|
|
|
|
{
|
|
|
|
if(!layout_banner || !wText)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Textbox *tbox = dynamic_cast<Textbox *>(layout_banner->FindPane(text_name));
|
|
|
|
if(tbox)
|
|
|
|
{
|
|
|
|
int len = wcslen(wText);
|
|
|
|
u16 *text_char16 = new u16[len+1];
|
|
|
|
|
|
|
|
for(int i = 0; i < len; i++)
|
|
|
|
text_char16[i] = (u16) wText[i];
|
|
|
|
text_char16[len] = 0;
|
|
|
|
|
|
|
|
tbox->SetText(text_char16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AnimatedBanner::SetBannerTexture(const char *tex_name, const u8 *data, float width, float height, u8 fmt)
|
|
|
|
{
|
|
|
|
if(!layout_banner)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Texture *texture = layout_banner->FindTexture( tex_name );
|
|
|
|
if(texture != NULL && data != NULL) {
|
|
|
|
texture->LoadTextureData(data, width, height, fmt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-27 19:26:49 +02:00
|
|
|
Layout* AnimatedBanner::LoadLayout(u8 *bnr, u32 bnr_size, const std::string& lyt_name, const std::string &language)
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
u32 brlyt_size = 0;
|
|
|
|
newBanner = DecompressCopy(bnr, bnr_size, &bnr_size);
|
2012-07-27 19:26:49 +02:00
|
|
|
if(newBanner == NULL)
|
|
|
|
return NULL;
|
2012-07-03 18:26:49 +02:00
|
|
|
|
|
|
|
const u8 *brlyt = u8_get_file(newBanner, (char*)fmt("%s.brlyt", lyt_name.c_str()), &brlyt_size);
|
|
|
|
if(!brlyt)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
Layout *layout = new Layout(sysFont1, sysFont2);
|
|
|
|
layout->Load(brlyt);
|
|
|
|
|
|
|
|
u32 length_start = 0, length_loop = 0;
|
|
|
|
|
|
|
|
u32 brlan_start_size = 0;
|
|
|
|
const u8 *brlan_start = u8_get_file(newBanner, (char*)fmt("%s_Start.brlan", lyt_name.c_str()), &brlan_start_size);
|
|
|
|
const u8 *brlan_loop = 0;
|
|
|
|
|
|
|
|
// try the alternative file
|
|
|
|
if(!brlan_start)
|
|
|
|
brlan_start = u8_get_file(newBanner, (char*)fmt("%s_In.brlan", lyt_name.c_str()), &brlan_start_size);
|
|
|
|
|
|
|
|
if(brlan_start)
|
|
|
|
length_start = Animator::LoadAnimators((const RLAN_Header *)brlan_start, *layout, 0);
|
|
|
|
|
|
|
|
u32 brlan_loop_size = 0;
|
|
|
|
brlan_loop = u8_get_file(newBanner, (char*)fmt("%s.brlan", lyt_name.c_str()), &brlan_loop_size);
|
|
|
|
if(!brlan_loop)
|
|
|
|
brlan_loop = u8_get_file(newBanner, (char*)fmt("%s_Loop.brlan", lyt_name.c_str()), &brlan_loop_size);
|
|
|
|
if(!brlan_loop)
|
|
|
|
brlan_loop = u8_get_file(newBanner, (char*)fmt("%s_Rso0.brlan", lyt_name.c_str()), &brlan_loop_size); // added for "artstyle" wiiware
|
|
|
|
|
|
|
|
if(brlan_loop)
|
|
|
|
length_loop = Animator::LoadAnimators((const RLAN_Header *)brlan_loop, *layout, 1);
|
|
|
|
|
|
|
|
// load textures after loading the animations so we get the list of tpl filenames from the brlans
|
|
|
|
layout->LoadTextures(newBanner);
|
|
|
|
layout->LoadFonts(newBanner);
|
|
|
|
layout->SetLanguage(language);
|
|
|
|
layout->SetLoopStart(length_start);
|
|
|
|
layout->SetLoopEnd(length_start + length_loop);
|
|
|
|
layout->SetFrame(0);
|
|
|
|
|
|
|
|
return layout;
|
|
|
|
}
|
|
|
|
|
2012-07-27 19:26:49 +02:00
|
|
|
u8 *DecompressCopy(u8 *stuff, u32 len, u32 *size)
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
// check for IMD5 header and skip it
|
2012-07-27 19:26:49 +02:00
|
|
|
if(len > 0x40 && *(u32*)stuff == 0x494d4435) // IMD5
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
stuff += 0x20;
|
|
|
|
len -= 0x20;
|
|
|
|
}
|
|
|
|
|
2012-07-27 19:26:49 +02:00
|
|
|
u8 *ret = NULL;
|
2012-07-03 18:26:49 +02:00
|
|
|
// determine if it needs to be decompressed
|
2012-07-27 19:26:49 +02:00
|
|
|
if(IsAshCompressed(stuff, len))
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
//u32 len2 = len;
|
|
|
|
// ASH0
|
2012-07-27 19:26:49 +02:00
|
|
|
ret = DecompressAsh(stuff, len);
|
|
|
|
if(!ret)
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
2012-07-27 19:26:49 +02:00
|
|
|
gprintf("out of memory\n");
|
2012-07-03 18:26:49 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2012-07-27 19:26:49 +02:00
|
|
|
else if(isLZ77compressed(stuff))
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
// LZ77 with no magic word
|
2012-07-27 19:26:49 +02:00
|
|
|
if(decompressLZ77content(stuff, len, &ret, &len))
|
2012-07-03 18:26:49 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2012-07-27 19:26:49 +02:00
|
|
|
else if(*(u32*)(stuff) == 0x4C5A3737) // LZ77
|
2012-07-03 18:26:49 +02:00
|
|
|
{
|
|
|
|
// LZ77 with a magic word
|
2012-07-27 19:26:49 +02:00
|
|
|
if(decompressLZ77content(stuff + 4, len - 4, &ret, &len ))
|
2012-07-03 18:26:49 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// just copy the data out of the archive
|
|
|
|
ret = (u8*)memalign( 32, len );
|
|
|
|
if( !ret )
|
|
|
|
{
|
|
|
|
gprintf( "out of memory\n" );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
memcpy( ret, stuff, len );
|
|
|
|
}
|
2012-07-27 19:26:49 +02:00
|
|
|
if(size)
|
2012-07-03 18:26:49 +02:00
|
|
|
*size = len;
|
|
|
|
|
|
|
|
// flush the cache so if there are any textures in this data, it will be ready for the GX
|
2012-07-27 19:26:49 +02:00
|
|
|
DCFlushRange(ret, len);
|
2012-07-03 18:26:49 +02:00
|
|
|
return ret;
|
|
|
|
}
|