WiiFlow_Lite/source/banner/AnimatedBanner.cpp
fix94.1 88955e9461 -changed the memory management yet again, now just use the mem
which has enough space left instead of fixed memory in most parts
-fixed alot of things about banner playing, now shouldnt randomly
codedump anymore or things like this, also some banner sounds
which did not play before should work fine now
-removed unused code and added better debug prints
-using some fixed voice for game banner and not always a new one
per banner
-fixed DIOS-MIOS cheats for sure now :P
-fixed possible memory allocation bug in wbfs alloc (thanks to
cfg-loader)
-removed MEM2_memalign since it did not work correctly
-fixed a few wrong memset sizes
2012-07-27 17:26:49 +00:00

206 lines
5.3 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 <malloc.h>
#include "U8Archive.h"
#include "LanguageCode.h"
#include "AnimatedBanner.h"
#include "text.hpp"
#include "lz77.h"
#include "ash.h"
AnimatedBanner::AnimatedBanner()
{
layout_banner = NULL;
newBanner = 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)
{
free(newBanner);
newBanner = NULL;
}
}
bool AnimatedBanner::LoadBanner(Banner *banner)
{
u32 banner_bin_size;
u8 *banner_bin = banner->GetFile((char*)"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(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(u8 *bnr, u32 bnr_size, const std::string& lyt_name, const std::string &language)
{
u32 brlyt_size = 0;
newBanner = DecompressCopy(bnr, bnr_size, &bnr_size);
if(newBanner == NULL)
return NULL;
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;
}
u8 *DecompressCopy(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
{
// 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 );
}
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;
}