WiiFlow_Lite/source/banner/AnimatedBanner.cpp
fix94.1 3bc03871fe -fixed a mixed up background (thanks ayatus)
-set wiiflow version to beta 4.2.2
-added another memory manager just for wii games and banners
-changed THP file playback, for sound you now need to have a ogg file with the same name, that fixes all audio shutters and crashes
-optimized THP file playback and JPG extraction alot, it should now work fine with 640x480 30fps without any crash or freeze anymore
2014-02-28 23:11:02 +00:00

202 lines
5.2 KiB
C++

/*
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 "LanguageCode.h"
#include "AnimatedBanner.h"
#include "gui/text.hpp"
#include "memory/mem2.hpp"
#include "unzip/U8Archive.h"
#include "unzip/lz77.h"
#include "unzip/ash.h"
AnimatedBanner gameBanner;
AnimatedBanner::AnimatedBanner()
{
layout_banner = NULL;
newBanner = NULL;
oriBanner = NULL;
}
void AnimatedBanner::LoadFont(u8 *font1, u8 *font2)
{
sysFont1 = font1;
sysFont2 = font2;
}
void AnimatedBanner::Clear()
{
if(layout_banner != NULL)
{
delete layout_banner;
layout_banner = NULL;
}
if(newBanner != NULL)
{
if(newBanner != oriBanner)
free(newBanner);
newBanner = NULL;
oriBanner = NULL;
}
}
bool AnimatedBanner::LoadBanner()
{
u32 banner_bin_size;
u8 *banner_bin = CurrentBanner.GetFile("banner.bin", &banner_bin_size);
if(banner_bin == NULL)
return false;
bool ret = LoadBannerBin(banner_bin, banner_bin_size);
free(banner_bin);
return ret;
}
bool AnimatedBanner::LoadBannerBin(const u8 *banner_bin, u32 banner_bin_size)
{
Clear();
layout_banner = LoadLayout(banner_bin, banner_bin_size, "banner", CONF_GetLanguageString());
return (layout_banner != NULL);
}
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);
}
}
Layout* AnimatedBanner::LoadLayout(const u8 *bnr, u32 bnr_size, const std::string& lyt_name, const std::string &language)
{
u32 brlyt_size = 0;
oriBanner = bnr;
newBanner = DecompressCopy(bnr, bnr_size, &bnr_size);
if(newBanner == NULL)
return NULL;
const u8 *brlyt = u8_get_file(newBanner, 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, 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, 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, fmt("%s.brlan", lyt_name.c_str()), &brlan_loop_size);
if(!brlan_loop)
brlan_loop = u8_get_file(newBanner, fmt("%s_Loop.brlan", lyt_name.c_str()), &brlan_loop_size);
if(!brlan_loop)
brlan_loop = u8_get_file(newBanner, 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;
}
u8 *DecompressCopy(const u8 *stuff, u32 len, u32 *size)
{
// check for IMD5 header and skip it
if(len > 0x40 && *(u32*)stuff == 0x494d4435) // IMD5
{
stuff += 0x20;
len -= 0x20;
}
u8 *ret = NULL;
// determine if it needs to be decompressed
if(IsAshCompressed(stuff, len))
{
//u32 len2 = len;
// ASH0
ret = DecompressAsh(stuff, len);
if(!ret)
{
gprintf("out of memory\n");
return NULL;
}
}
else if(isLZ77compressed(stuff))
{
// LZ77 with no magic word
if(decompressLZ77content(stuff, len, &ret, &len))
return NULL;
}
else if(*(u32*)(stuff) == 0x4C5A3737) // LZ77
{
// LZ77 with a magic word
if(decompressLZ77content(stuff + 4, len - 4, &ret, &len))
return NULL;
}
else //I hate to do that
ret = (u8*)stuff;
if(size)
*size = len;
// flush the cache so if there are any textures in this data, it will be ready for the GX
DCFlushRange(ret, len);
return ret;
}