mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 00:55:06 +01:00
-internal wii game and channel banner playback, still work in
progress, thanks alot to dimok and the whole usb loader gx team for help and the code for it! To zoom the banner to fullscreen click the back button, to zoom out the back button again, known bugs: -some games fuck up the textures of buttons (e.g. wii play motion) -if no wii game or channel was selected and you try to launch a game or exit wiiflow it will most likely codedump
This commit is contained in:
parent
757fd2021b
commit
706e18c6c0
2
Makefile
2
Makefile
@ -18,6 +18,7 @@ include $(DEVKITPPC)/wii_rules
|
|||||||
TARGET := boot
|
TARGET := boot
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := source \
|
SOURCES := source \
|
||||||
|
source/banner \
|
||||||
source/cheats \
|
source/cheats \
|
||||||
source/config \
|
source/config \
|
||||||
source/data \
|
source/data \
|
||||||
@ -45,6 +46,7 @@ DATA := data \
|
|||||||
data/help
|
data/help
|
||||||
|
|
||||||
INCLUDES := source \
|
INCLUDES := source \
|
||||||
|
source/banner \
|
||||||
source/cheats \
|
source/cheats \
|
||||||
source/config \
|
source/config \
|
||||||
source/devicemounter \
|
source/devicemounter \
|
||||||
|
174
source/banner/AnimatedBanner.cpp
Normal file
174
source/banner/AnimatedBanner.cpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
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(u8 *font1, u8 *font2)
|
||||||
|
{
|
||||||
|
first = true;
|
||||||
|
layout_banner = NULL;
|
||||||
|
newBanner = NULL;
|
||||||
|
sysFont1 = font1;
|
||||||
|
sysFont2 = font2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedBanner::Clear()
|
||||||
|
{
|
||||||
|
if(first)
|
||||||
|
return;
|
||||||
|
if(layout_banner)
|
||||||
|
{
|
||||||
|
delete layout_banner;
|
||||||
|
layout_banner = NULL;
|
||||||
|
}
|
||||||
|
if(newBanner)
|
||||||
|
{
|
||||||
|
delete newBanner;
|
||||||
|
newBanner = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnimatedBanner::LoadBanner(Banner *banner)
|
||||||
|
{
|
||||||
|
first = false;
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
u32 banner_bin_size;
|
||||||
|
const u8 *banner_bin = banner->GetFile((char*)"banner.bin", &banner_bin_size);
|
||||||
|
if(banner_bin == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
layout_banner = LoadLayout(banner_bin, banner_bin_size, "banner", CONF_GetLanguageString());
|
||||||
|
return (layout_banner != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout* AnimatedBanner::LoadLayout(const 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);
|
||||||
|
|
||||||
|
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 *AnimatedBanner::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( (u8*)stuff ) )
|
||||||
|
{
|
||||||
|
// LZ77 with no magic word
|
||||||
|
if( decompressLZ77content( (u8*)stuff, len, &ret, &len ) )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( *(u32*)( stuff ) == 0x4C5A3737 )// LZ77
|
||||||
|
{
|
||||||
|
// LZ77 with a magic word
|
||||||
|
if( decompressLZ77content( (u8*)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;
|
||||||
|
}
|
51
source/banner/AnimatedBanner.h
Normal file
51
source/banner/AnimatedBanner.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ANIMATEDBANNER_H_
|
||||||
|
#define _ANIMATEDBANNER_H_
|
||||||
|
|
||||||
|
#include "Layout.h"
|
||||||
|
#include "disc.h"
|
||||||
|
#include "channel/banner.h"
|
||||||
|
|
||||||
|
class AnimatedBanner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnimatedBanner(u8 *font1, u8 *font2);
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
bool LoadBanner(Banner *banner);
|
||||||
|
Layout *getBanner() const { return layout_banner; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Layout* LoadLayout(const u8 *bnr, u32 bnr_size, const std::string& lyt_name, const std::string &language);
|
||||||
|
u8 *DecompressCopy( const u8 * stuff, u32 len, u32 *size );
|
||||||
|
Layout *layout_banner;
|
||||||
|
u8 *newBanner;
|
||||||
|
u8 *sysFont1;
|
||||||
|
u8 *sysFont2;
|
||||||
|
bool first;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
260
source/banner/Animator.cpp
Normal file
260
source/banner/Animator.cpp
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
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 <math.h>
|
||||||
|
#include "Animator.h"
|
||||||
|
#include "Layout.h"
|
||||||
|
|
||||||
|
// load keyframes from a brlan file
|
||||||
|
u32 Animator::LoadAnimators(const RLAN_Header *header, Layout& layout, u8 key_set)
|
||||||
|
{
|
||||||
|
u32 frame_count = 0;
|
||||||
|
|
||||||
|
if (!header || header->magic != MAGIC_ANIMATION || header->endian != 0xFEFF || header->version != 0x0008)
|
||||||
|
return 0; // bad header
|
||||||
|
|
||||||
|
// first section
|
||||||
|
const u8 *position = ((const u8 *) header) + header->offset;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < header->section_count; ++i)
|
||||||
|
{
|
||||||
|
section_t *section = (section_t *) position;
|
||||||
|
position += section->size;
|
||||||
|
|
||||||
|
if (section->magic == MAGIC_PANE_ANIMATION_INFO)
|
||||||
|
{
|
||||||
|
const PAI1_Header *pai = (const PAI1_Header *) section;
|
||||||
|
u16 animator_count = pai->animator_count;
|
||||||
|
frame_count += pai->frame_count;
|
||||||
|
|
||||||
|
// read animation file names
|
||||||
|
const u32 *nameOffsets = (const u32 *)(pai + 1);
|
||||||
|
for(u32 i = 0; i < pai->file_count; i++)
|
||||||
|
{
|
||||||
|
const char* name = (((const char *) nameOffsets) + nameOffsets[i]);
|
||||||
|
layout.AddPalette(name, key_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 *offsets = (const u32 *) (((const u8 *)section) + pai->entry_offset);
|
||||||
|
// read each animator
|
||||||
|
for(u32 n = 0; n < animator_count; n++)
|
||||||
|
{
|
||||||
|
const AnimatorHeader *animHdr = (const AnimatorHeader *) (((const u8 *)section) + offsets[n]);
|
||||||
|
std::string anim_name(animHdr->name, 0, 20);
|
||||||
|
|
||||||
|
Animator* animator = animHdr->is_material ?
|
||||||
|
(Animator*) layout.FindMaterial(anim_name) :
|
||||||
|
(Animator*) layout.FindPane(anim_name);
|
||||||
|
|
||||||
|
if (animator)
|
||||||
|
animator->LoadKeyFrames((const u8 *) animHdr, animHdr->tag_count, sizeof(AnimatorHeader), key_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gprintf("Unknown: %c%c%c%c\n", position[0], position[1], position[2], position[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animator::LoadKeyFrames(const u8 *file, u8 tag_count, u32 offset, u8 key_set)
|
||||||
|
{
|
||||||
|
const u32 *tag_offsets = (const u32 *) (file + offset);
|
||||||
|
|
||||||
|
for(u32 tag = 0; tag < tag_count; tag++)
|
||||||
|
{
|
||||||
|
const Anim_Header *animHdr = (const Anim_Header *) (file + tag_offsets[tag]);
|
||||||
|
|
||||||
|
u32 animation_type = animHdr->animation_type;
|
||||||
|
u8 frame_count = animHdr->frame_count;
|
||||||
|
|
||||||
|
const u32 *frame_offsets = (const u32 *) (animHdr + 1);
|
||||||
|
|
||||||
|
for(u32 frame = 0; frame < frame_count; frame++)
|
||||||
|
{
|
||||||
|
const KeyFrame_Header *keyFrame = (const KeyFrame_Header *)(((const u8 *) animHdr) + frame_offsets[frame]);
|
||||||
|
const KeyType frame_type(static_cast<AnimationType>(animation_type), keyFrame->index, keyFrame->target);
|
||||||
|
|
||||||
|
switch (keyFrame->data_type)
|
||||||
|
{
|
||||||
|
// step key frame
|
||||||
|
case 0x01:
|
||||||
|
keys[key_set].step_keys[frame_type].Load((const u8 *) (keyFrame+1), keyFrame->key_count);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// hermite key frame
|
||||||
|
case 0x02:
|
||||||
|
keys[key_set].hermite_keys[frame_type].Load((const u8 *) (keyFrame+1), keyFrame->key_count);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animator::SetFrame(FrameNumber frame_number, u8 key_set)
|
||||||
|
{
|
||||||
|
std::map<KeyType, HermiteKeyHandler>::iterator itr;
|
||||||
|
for(itr = keys[key_set].hermite_keys.begin(); itr != keys[key_set].hermite_keys.end(); itr++)
|
||||||
|
{
|
||||||
|
const KeyType& frame_type = itr->first;
|
||||||
|
const float frame_value = itr->second.GetFrame(frame_number);
|
||||||
|
|
||||||
|
ProcessHermiteKey(frame_type, frame_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<KeyType, StepKeyHandler>::iterator itr2;
|
||||||
|
for(itr2 = keys[key_set].step_keys.begin(); itr2 != keys[key_set].step_keys.end(); itr2++)
|
||||||
|
{
|
||||||
|
const KeyType& frame_type = itr2->first;
|
||||||
|
StepKeyHandler::KeyData const frame_data = itr2->second.GetFrame(frame_number);
|
||||||
|
|
||||||
|
ProcessStepKey(frame_type, frame_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepKeyHandler::Load(const u8 *file, u16 count)
|
||||||
|
{
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
FrameNumber frame;
|
||||||
|
frame = *((FrameNumber *) file);
|
||||||
|
file += 4;
|
||||||
|
|
||||||
|
KeyData& data = keys[frame];
|
||||||
|
data.data1 = *file;
|
||||||
|
file++;
|
||||||
|
data.data2 = *file;
|
||||||
|
file++;
|
||||||
|
|
||||||
|
file += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HermiteKeyHandler::Load(const u8 *file, u16 count)
|
||||||
|
{
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
std::pair<FrameNumber, KeyData> pair;
|
||||||
|
|
||||||
|
// read the frame number, value and slope
|
||||||
|
pair.first = *((FrameNumber *) file);
|
||||||
|
file += 4;
|
||||||
|
pair.second.value = *((float *) file);
|
||||||
|
file += 4;
|
||||||
|
pair.second.slope = *((float *) file);
|
||||||
|
file += 4;
|
||||||
|
|
||||||
|
keys.insert(pair);
|
||||||
|
|
||||||
|
//std::cout << "\t\t\t" "frame: " << frame << ' ' << keys[frame] << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StepKeyHandler::KeyData StepKeyHandler::GetFrame(FrameNumber frame_number) const
|
||||||
|
{
|
||||||
|
// assuming not empty, a safe assumption currently
|
||||||
|
|
||||||
|
// find the current frame, or the one after it
|
||||||
|
std::map<FrameNumber, KeyData>::const_iterator frame_it = keys.lower_bound(frame_number);
|
||||||
|
|
||||||
|
// current frame is higher than any keyframe, use the last keyframe
|
||||||
|
if (keys.end() == frame_it)
|
||||||
|
--frame_it;
|
||||||
|
|
||||||
|
// if this is after the current frame and not the first keyframe, use the previous one
|
||||||
|
if (frame_number < frame_it->first && keys.begin() != frame_it)
|
||||||
|
--frame_it;
|
||||||
|
|
||||||
|
return frame_it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
float HermiteKeyHandler::GetFrame(FrameNumber frame_number) const
|
||||||
|
{
|
||||||
|
// assuming not empty, a safe assumption currently
|
||||||
|
|
||||||
|
// find the current keyframe, or the one after it
|
||||||
|
std::multimap<FrameNumber, KeyData>::const_iterator next = keys.lower_bound(frame_number);
|
||||||
|
|
||||||
|
// current frame is higher than any keyframe, use the last keyframe
|
||||||
|
if (keys.end() == next)
|
||||||
|
--next;
|
||||||
|
|
||||||
|
std::multimap<FrameNumber, KeyData>::const_iterator prev = next;
|
||||||
|
|
||||||
|
// if this is after the current frame and not the first keyframe, use the previous one
|
||||||
|
if (frame_number < prev->first && keys.begin() != prev)
|
||||||
|
--prev;
|
||||||
|
|
||||||
|
const float nf = next->first - prev->first;
|
||||||
|
if (fabs(nf) < 0.01)
|
||||||
|
{
|
||||||
|
// same frame numbers, just return the first's value
|
||||||
|
return prev->second.value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// different frames, blend them together
|
||||||
|
// this is a "Cubic Hermite spline" apparently
|
||||||
|
|
||||||
|
frame_number = (frame_number < prev->first) ? prev->first :
|
||||||
|
((frame_number > next->first) ? next->first : frame_number);
|
||||||
|
|
||||||
|
const float t = (frame_number - prev->first) / nf;
|
||||||
|
|
||||||
|
// old curve-less code
|
||||||
|
//return prev->second.value + (next->second.value - prev->second.value) * t;
|
||||||
|
|
||||||
|
// curvy code from marcan, :p
|
||||||
|
return
|
||||||
|
prev->second.slope * nf * (t + powf(t, 3) - 2 * powf(t, 2)) +
|
||||||
|
next->second.slope * nf * (powf(t, 3) - powf(t, 2)) +
|
||||||
|
prev->second.value * (1 + (2 * powf(t, 3) - 3 * powf(t, 2))) +
|
||||||
|
next->second.value * (-2 * powf(t, 3) + 3 * powf(t, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animator::ProcessHermiteKey(const KeyType& type, float value)
|
||||||
|
{
|
||||||
|
// std::cout << "unhandled key (" << GetName() << "): type: " << FourCC(type.type)
|
||||||
|
// << " index: " << (int)type.index
|
||||||
|
// << " target: " << (int)type.target
|
||||||
|
// << " value: " << value
|
||||||
|
// << '\n';
|
||||||
|
gprintf("Animator::ProcessHermiteKey\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animator::ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data)
|
||||||
|
{
|
||||||
|
// std::cout << "unhandled key (" << GetName() << "): type: " << FourCC(type.type)
|
||||||
|
// << " index: " << (int)type.index
|
||||||
|
// << " target: " << (int)type.target
|
||||||
|
// << " data:" << (int)data.data1 << " " << (int)data.data2
|
||||||
|
// << '\n';
|
||||||
|
gprintf("Animator::ProcessStepKey\n");
|
||||||
|
}
|
169
source/banner/Animator.h
Normal file
169
source/banner/Animator.h
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WII_BNR_ANIMATOR_H_
|
||||||
|
#define WII_BNR_ANIMATOR_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include "BannerTools.h"
|
||||||
|
|
||||||
|
typedef float FrameNumber;
|
||||||
|
|
||||||
|
enum AnimationType
|
||||||
|
{
|
||||||
|
ANIMATION_TYPE_PANE = MAKE_FOURCC('R', 'L', 'P', 'A'),
|
||||||
|
ANIMATION_TYPE_TEXTURE_SRT = MAKE_FOURCC('R', 'L', 'T', 'S'),
|
||||||
|
ANIMATION_TYPE_VISIBILITY = MAKE_FOURCC('R', 'L', 'V', 'I'),
|
||||||
|
ANIMATION_TYPE_VERTEX_COLOR = MAKE_FOURCC('R', 'L', 'V', 'C'),
|
||||||
|
ANIMATION_TYPE_MATERIAL_COLOR = MAKE_FOURCC('R', 'L', 'M', 'C'),
|
||||||
|
ANIMATION_TYPE_TEXTURE_PALETTE = MAKE_FOURCC('R', 'L', 'T', 'P'),
|
||||||
|
ANIMATION_TYPE_IND_MATERIAL = MAKE_FOURCC('R', 'L', 'I', 'M'),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RLAN_Header
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u16 endian;
|
||||||
|
u16 version;
|
||||||
|
u32 file_size;
|
||||||
|
u16 offset;
|
||||||
|
u16 section_count;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct PAI1_Header
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 section_size;
|
||||||
|
u16 frame_count;
|
||||||
|
u8 loop;
|
||||||
|
u8 pad;
|
||||||
|
u16 file_count;
|
||||||
|
u16 animator_count;
|
||||||
|
u32 entry_offset;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct AnimatorHeader
|
||||||
|
{
|
||||||
|
char name[20];
|
||||||
|
u8 tag_count;
|
||||||
|
u8 is_material;
|
||||||
|
u16 apad;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct Anim_Header
|
||||||
|
{
|
||||||
|
u32 animation_type;
|
||||||
|
u8 frame_count;
|
||||||
|
u8 pad[3];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct KeyFrame_Header
|
||||||
|
{
|
||||||
|
u8 index;
|
||||||
|
u8 target;
|
||||||
|
u8 data_type;
|
||||||
|
u8 pad;
|
||||||
|
u16 key_count;
|
||||||
|
u16 pad1;
|
||||||
|
u32 offset;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct KeyType
|
||||||
|
{
|
||||||
|
KeyType(AnimationType _type, u8 _index, u8 _target)
|
||||||
|
: type(_type)
|
||||||
|
, index(_index)
|
||||||
|
, target(_target)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator<(const KeyType& rhs) const
|
||||||
|
{
|
||||||
|
return memcmp(this, &rhs, sizeof(*this)) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimationType type;
|
||||||
|
const u8 index, target;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StepKeyHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Load(const u8* file, u16 count);
|
||||||
|
|
||||||
|
struct KeyData
|
||||||
|
{
|
||||||
|
u8 data1, data2;
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyData GetFrame(FrameNumber frame_number) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<FrameNumber, KeyData> keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HermiteKeyHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Load(const u8* file, u16 count);
|
||||||
|
|
||||||
|
struct KeyData
|
||||||
|
{
|
||||||
|
float value, slope;
|
||||||
|
};
|
||||||
|
|
||||||
|
float GetFrame(FrameNumber frame_number) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::multimap<FrameNumber, KeyData> keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Layout;
|
||||||
|
class Animator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const u32 MAGIC_ANIMATION = MAKE_FOURCC('R', 'L', 'A', 'N');
|
||||||
|
static const u32 MAGIC_PANE_ANIMATION_INFO = MAKE_FOURCC('p', 'a', 'i', '1');
|
||||||
|
|
||||||
|
static u32 LoadAnimators(const RLAN_Header *header, Layout& layout, u8 key_set);
|
||||||
|
|
||||||
|
void LoadKeyFrames(const u8 *file, u8 tag_count, u32 offset, u8 key_set);
|
||||||
|
virtual void SetFrame(FrameNumber frame, u8 key_set);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Animator() {}
|
||||||
|
|
||||||
|
virtual void ProcessHermiteKey(const KeyType& type, float value);
|
||||||
|
virtual void ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data);
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
std::map<KeyType, StepKeyHandler> step_keys;
|
||||||
|
std::map<KeyType, HermiteKeyHandler> hermite_keys;
|
||||||
|
} keys[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
148
source/banner/BannerTexture.cpp
Normal file
148
source/banner/BannerTexture.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010 - Wii Banner Player Project
|
||||||
|
Copyright (c) 2012 - Dimok
|
||||||
|
Copyright (c) 2012 - giantpune
|
||||||
|
|
||||||
|
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 <set>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "BannerTexture.hpp"
|
||||||
|
|
||||||
|
Texture::~Texture()
|
||||||
|
{
|
||||||
|
if(texture_data)
|
||||||
|
free(texture_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::Load(const u8 *file )
|
||||||
|
{
|
||||||
|
if(!file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
header = (Texture::Header *) file;
|
||||||
|
|
||||||
|
if (header->magic != MAGIC) {
|
||||||
|
header = NULL;
|
||||||
|
return; // bad header
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 texture_count = header->num_textures;
|
||||||
|
// only support a single texture
|
||||||
|
if (texture_count > 1)
|
||||||
|
{
|
||||||
|
// Never saw it happen
|
||||||
|
texture_count = 1;
|
||||||
|
gprintf("texture count > 1\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read textures
|
||||||
|
const TPL_Texture *tpl_list = (const TPL_Texture *) (file + header->header_size);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < texture_count; i++)
|
||||||
|
{
|
||||||
|
// seek to texture header
|
||||||
|
const TPL_Texture_Header *texture = (const TPL_Texture_Header *) (file + tpl_list[i].texture_offset);
|
||||||
|
|
||||||
|
u8 mipmap = 0;
|
||||||
|
u8 bias_clamp = 0;
|
||||||
|
|
||||||
|
if(texture->max_lod > 0)
|
||||||
|
mipmap = GX_TRUE;
|
||||||
|
if(texture->lod_bias > 0.0f)
|
||||||
|
bias_clamp = GX_ENABLE;
|
||||||
|
|
||||||
|
// texture data
|
||||||
|
u8 *texture_data = (u8 *) (file + texture->offset);
|
||||||
|
|
||||||
|
// seek to/read palette header
|
||||||
|
if (tpl_list[i].palette_offset != 0)
|
||||||
|
{
|
||||||
|
palette = (TPL_Palette_Header *) (file + tpl_list[i].palette_offset);
|
||||||
|
|
||||||
|
// load the texture
|
||||||
|
GX_InitTexObjCI(&texobj, texture_data, texture->width, texture->height, texture->format,
|
||||||
|
texture->wrap_s, texture->wrap_t, mipmap, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// load the texture
|
||||||
|
GX_InitTexObj(&texobj, texture_data, texture->width, texture->height, texture->format,
|
||||||
|
texture->wrap_s, texture->wrap_t, mipmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter mode
|
||||||
|
if(mipmap)
|
||||||
|
{
|
||||||
|
GX_InitTexObjLOD(&texobj, texture->min, texture->mag, texture->min_lod, texture->max_lod,
|
||||||
|
texture->lod_bias, bias_clamp, bias_clamp, texture->edge_lod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! This function is to load custom texture data and replace the original one.
|
||||||
|
void Texture::LoadTextureData(const u8 *data, u16 width, u16 height, u8 fmt)
|
||||||
|
{
|
||||||
|
if(texture_data)
|
||||||
|
free(texture_data);
|
||||||
|
|
||||||
|
int tex_size = GX_GetTexBufferSize(width, height, fmt, GX_FALSE, 0);
|
||||||
|
texture_data = (u8*) memalign(32, tex_size);
|
||||||
|
if(!texture_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(texture_data, data, tex_size);
|
||||||
|
DCFlushRange(texture_data, tex_size);
|
||||||
|
|
||||||
|
GX_InitTexObj(&texobj, texture_data, width, height, fmt, 0, 0, GX_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::Apply(u8 &tlutName, u8 map_id, u8 wrap_s, u8 wrap_t) const
|
||||||
|
{
|
||||||
|
if(!header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(tlutName >= 20 || map_id >= 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// create a temporary texture object to not modify the original with the wrap_s and wrap_t parameters
|
||||||
|
GXTexObj tmpTexObj;
|
||||||
|
for(int i = 0; i < 8; ++i)
|
||||||
|
tmpTexObj.val[i] = texobj.val[i];
|
||||||
|
|
||||||
|
// assume that if there is a palette header, then this format is a CIx one
|
||||||
|
if(palette)
|
||||||
|
{
|
||||||
|
// seek to/read palette data
|
||||||
|
u8 *tlut_data = (u8 *) (((u8 *) header) + palette->offset);
|
||||||
|
|
||||||
|
// load tlut
|
||||||
|
GXTlutObj tlutobj;
|
||||||
|
GX_InitTlutObj(&tlutobj, tlut_data, palette->format, palette->num_items );
|
||||||
|
GX_LoadTlut(&tlutobj, tlutName);
|
||||||
|
GX_InitTexObjTlut((GXTexObj *) &tmpTexObj, tlutName);
|
||||||
|
tlutName++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_InitTexObjWrapMode((GXTexObj *) &tmpTexObj, wrap_s, wrap_t);
|
||||||
|
GX_LoadTexObj((GXTexObj *) &tmpTexObj, map_id);
|
||||||
|
}
|
102
source/banner/BannerTexture.hpp
Normal file
102
source/banner/BannerTexture.hpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010 - Wii Banner Player Project
|
||||||
|
Copyright (c) 2012 - Dimok
|
||||||
|
Copyright (c) 2012 - giantpune
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef TEXTURE_H_
|
||||||
|
#define TEXTURE_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <gccore.h>
|
||||||
|
#include "BannerTools.h"
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC(0x00, ' ', 0xAF, 0x30);
|
||||||
|
|
||||||
|
Texture() : header(NULL), palette(NULL), texture_data(NULL) {}
|
||||||
|
virtual ~Texture();
|
||||||
|
|
||||||
|
void Load(const u8 *texture);
|
||||||
|
const std::string &getName() const { return name; }
|
||||||
|
void setName(const std::string& _name) { name = _name; }
|
||||||
|
|
||||||
|
// load custom data into the texture object
|
||||||
|
void LoadTextureData(const u8 *data, u16 width, u16 height, u8 fmt);
|
||||||
|
|
||||||
|
void Apply(u8 &tlutName, u8 map_id, u8 wrap_s, u8 wrap_t) const;
|
||||||
|
private:
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 num_textures;
|
||||||
|
u32 header_size;
|
||||||
|
} __attribute__((packed)) ;
|
||||||
|
|
||||||
|
struct TPL_Texture
|
||||||
|
{
|
||||||
|
u32 texture_offset;
|
||||||
|
u32 palette_offset;
|
||||||
|
} __attribute__((packed)) ;
|
||||||
|
|
||||||
|
struct TPL_Texture_Header
|
||||||
|
{
|
||||||
|
u16 height;
|
||||||
|
u16 width;
|
||||||
|
u32 format;
|
||||||
|
u32 offset;
|
||||||
|
u32 wrap_s;
|
||||||
|
u32 wrap_t;
|
||||||
|
u32 min;
|
||||||
|
u32 mag;
|
||||||
|
f32 lod_bias;
|
||||||
|
u8 edge_lod;
|
||||||
|
u8 min_lod;
|
||||||
|
u8 max_lod;
|
||||||
|
u8 unpacked;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct TPL_Palette_Header
|
||||||
|
{
|
||||||
|
u16 num_items;
|
||||||
|
u8 unpacked;
|
||||||
|
u8 pad;
|
||||||
|
u32 format;
|
||||||
|
u32 offset;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
Texture::Header *header;
|
||||||
|
TPL_Palette_Header *palette;
|
||||||
|
u8 *texture_data;
|
||||||
|
GXTexObj texobj;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextureList : public std::vector<Texture *>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('t', 'x', 'l', '1');
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
61
source/banner/BannerTools.h
Normal file
61
source/banner/BannerTools.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef BANNER_TOOLS_H_
|
||||||
|
#define BANNER_TOOLS_H_
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include "gecko.h"
|
||||||
|
|
||||||
|
#define MAKE_FOURCC(a, b, c, d) ((a) * (1 << 24) + (b) * (1 << 16) + (c) * (1 << 8) + (d) * (1 << 0))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 size;
|
||||||
|
} section_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
} Vec2f;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
} Vec3f;
|
||||||
|
|
||||||
|
#define ALIGN32(x) (((x) + 31) & ~31)
|
||||||
|
#define LIMIT(x, min, max) \
|
||||||
|
({ \
|
||||||
|
typeof( x ) _x = x; \
|
||||||
|
typeof( min ) _min = min; \
|
||||||
|
typeof( max ) _max = max; \
|
||||||
|
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define MultiplyAlpha(a1, a2) ((u16) (a1) * (u16) (a2) / 0xFF)
|
||||||
|
#define FLOAT_2_U8(x) ((u8)((x) > 255.0f ? 255.0f : ((x) < 0.0f ? 0.0f : (x) + 0.5f)))
|
||||||
|
#define FLOAT_2_S16(x) ((s16)((x) > 32767.0f ? 32767.0f : ((x) < -32768.0f ? 32768.0f : (x) + 0.5f)))
|
||||||
|
|
||||||
|
#endif
|
271
source/banner/BannerWindow.cpp
Normal file
271
source/banner/BannerWindow.cpp
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2012 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "BannerWindow.hpp"
|
||||||
|
#include "menu.hpp"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "gx_addons.h"
|
||||||
|
#include "gecko.h"
|
||||||
|
|
||||||
|
void BannerWindow::LoadBanner(Banner *banner, CVideo *vid, u8 *font1, u8 *font2)
|
||||||
|
{
|
||||||
|
MaxAnimSteps = 30;
|
||||||
|
returnVal = -1;
|
||||||
|
reducedVol = false;
|
||||||
|
ScreenProps.x = 620; //620
|
||||||
|
ScreenProps.y = 400; //400
|
||||||
|
sysFont1 = font1;
|
||||||
|
sysFont2 = font2;
|
||||||
|
|
||||||
|
video = vid;
|
||||||
|
guMtxIdentity(modelview);
|
||||||
|
guMtxTransApply(modelview, modelview, (!video->wide() || video->vid_50hz()) ? 0.0f : 2.0f, video->vid_50hz() ? -1.0f : 0.0f, 0.0F);
|
||||||
|
|
||||||
|
AnimPosX = 0.5f * (ScreenProps.x - fIconWidth);
|
||||||
|
AnimPosY = 0.5f * (ScreenProps.y - fIconHeight);
|
||||||
|
AnimZoomIn = false;
|
||||||
|
AnimZoomOut = false;
|
||||||
|
AnimationRunning = false;
|
||||||
|
BannerAlpha = 255.f;
|
||||||
|
ChangeGame(banner);
|
||||||
|
gameSelected = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::DeleteBanner()
|
||||||
|
{
|
||||||
|
gameSelected = 0;
|
||||||
|
gameBanner->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
BannerWindow::BannerWindow()
|
||||||
|
{
|
||||||
|
AnimStep = 20;
|
||||||
|
gameSelected = 0;
|
||||||
|
firstRun = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::ChangeGame(Banner *banner)
|
||||||
|
{
|
||||||
|
gameSelected = 0;
|
||||||
|
if(firstRun)
|
||||||
|
{
|
||||||
|
gameBanner = new AnimatedBanner(sysFont1, sysFont2);
|
||||||
|
firstRun = false;
|
||||||
|
}
|
||||||
|
gameBanner->LoadBanner(banner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::ZoomIn(void)
|
||||||
|
{
|
||||||
|
AnimZoomIn = true;
|
||||||
|
AnimZoomOut = false;
|
||||||
|
if(AnimStep <= 20)
|
||||||
|
AnimStep++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::PauseZoom(void)
|
||||||
|
{
|
||||||
|
AnimZoomIn = false;
|
||||||
|
AnimZoomOut = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::ZoomOut(void)
|
||||||
|
{
|
||||||
|
AnimZoomIn = false;
|
||||||
|
AnimZoomOut = true;
|
||||||
|
if(AnimStep >= MaxAnimSteps)
|
||||||
|
AnimStep--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::Animate(void)
|
||||||
|
{
|
||||||
|
// animation is on going
|
||||||
|
if(AnimStep < MaxAnimSteps)
|
||||||
|
{
|
||||||
|
AnimationRunning = true;
|
||||||
|
if(AnimZoomIn && AnimStep < MaxAnimSteps)
|
||||||
|
AnimStep++;
|
||||||
|
else if(AnimZoomOut && AnimStep > 20)
|
||||||
|
AnimStep--;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// zoom in animation
|
||||||
|
if(AnimZoomIn) {
|
||||||
|
BGAlpha = std::min(255.f * AnimStep * 2.f / MaxAnimSteps, 255.f);
|
||||||
|
//if(AnimStep < 0.4f * MaxAnimSteps)
|
||||||
|
//BannerAlpha = 0;
|
||||||
|
//else
|
||||||
|
//BannerAlpha = std::min(255.f * (AnimStep - 0.4f * MaxAnimSteps) / (0.6f * MaxAnimSteps), 255.f);
|
||||||
|
}
|
||||||
|
// zoom out animation
|
||||||
|
else {
|
||||||
|
BGAlpha = std::min(255.f * (MaxAnimSteps-AnimStep) * 2.f / MaxAnimSteps, 255.f);
|
||||||
|
//if((MaxAnimSteps - AnimStep) < 0.4f * MaxAnimSteps)
|
||||||
|
//BannerAlpha = 0;
|
||||||
|
//else
|
||||||
|
//BannerAlpha = std::min(255.f * ((MaxAnimSteps - AnimStep) - 0.4f * MaxAnimSteps) / (0.6f * MaxAnimSteps), 255.f);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
float curAnimStep = ((float)(MaxAnimSteps - AnimStep)/(float)MaxAnimSteps);
|
||||||
|
|
||||||
|
float stepx1 = -AnimPosX;
|
||||||
|
float stepy1 = -AnimPosY;
|
||||||
|
float stepx2 = (640 - 1) - (AnimPosX + fIconWidth);
|
||||||
|
float stepy2 = (480 - 1) - (AnimPosY + fIconHeight);
|
||||||
|
|
||||||
|
float top = AnimPosY + stepy1 * curAnimStep;
|
||||||
|
float bottom = AnimPosY + fIconHeight + stepy2 * curAnimStep;
|
||||||
|
float left = AnimPosX + stepx1 * curAnimStep;
|
||||||
|
float right = AnimPosX + fIconWidth + stepx2 * curAnimStep;
|
||||||
|
|
||||||
|
// set main projection of all GUI stuff if we are using the banner browser
|
||||||
|
//if(dynamic_cast<GuiBannerGrid *>(browserMenu->GetGameBrowser()) != NULL)
|
||||||
|
// guOrtho(FSProjection2D, top, bottom, left, right, 0, 10000);
|
||||||
|
|
||||||
|
float xDiff = 0.5f * (video->wide() ? (video->vid_50hz() ? 616 : 620.0f) : 608.0f);
|
||||||
|
float yDiff = 0.5f * (video->vid_50hz() ? 448.0f : 470.0f);
|
||||||
|
|
||||||
|
// this just looks better for banner/icon ratio
|
||||||
|
float iconWidth = fIconWidth - 20;
|
||||||
|
float iconHeight = fIconHeight - 20;
|
||||||
|
|
||||||
|
f32 ratioX = xDiff * 2.f / iconWidth;
|
||||||
|
f32 ratioY = yDiff * 2.f / iconHeight;
|
||||||
|
stepx1 = ((ScreenProps.x * 0.1f - xDiff) - (AnimPosX + 0.1f * fIconWidth - 0.1f * iconWidth)) * ratioX;
|
||||||
|
stepx2 = ((ScreenProps.x * 0.1f + xDiff) - (AnimPosX + 0.1f * fIconWidth + 0.1f * iconWidth)) * ratioX;
|
||||||
|
stepy1 = ((ScreenProps.y * 0.7f - yDiff) - (AnimPosY + 0.7f * fIconHeight - 0.7f * iconHeight)) * ratioY;
|
||||||
|
stepy2 = ((ScreenProps.y * 0.7f + yDiff) - (AnimPosY + 0.7f * fIconHeight + 0.7f * iconHeight)) * ratioY;
|
||||||
|
|
||||||
|
//! This works good for banners
|
||||||
|
top = (ScreenProps.y * 0.5f - yDiff) + stepy1 * curAnimStep;
|
||||||
|
bottom = (ScreenProps.y * 0.5f + yDiff) + stepy2 * curAnimStep;
|
||||||
|
left = (ScreenProps.x * 0.5f - xDiff) + stepx1 * curAnimStep;
|
||||||
|
right = (ScreenProps.x * 0.5f + xDiff) + stepx2 * curAnimStep;
|
||||||
|
|
||||||
|
// set banner projection
|
||||||
|
guOrtho(projection,top, bottom, left, right,-100,10000);
|
||||||
|
}
|
||||||
|
// last animation step
|
||||||
|
else if(AnimationRunning)
|
||||||
|
{
|
||||||
|
// set back original projection and stop animation/render of the browser (save some CPU ;P)
|
||||||
|
//memcpy(&video->projMtx, &originalProjection, sizeof(Mtx44));
|
||||||
|
AnimationRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::Draw(void)
|
||||||
|
{
|
||||||
|
// draw a black background image first
|
||||||
|
//DrawRectangle(0.0f, 0.0f, ScreenProps.x, ScreenProps.y, (GXColor) {0, 0, 0, BGAlpha}, true);
|
||||||
|
|
||||||
|
// Run window animation
|
||||||
|
Animate();
|
||||||
|
|
||||||
|
// no banner alpha means its the start of the animation
|
||||||
|
if(BannerAlpha == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// cut the unneeded crap
|
||||||
|
Mtx mv1, mv2, mv3;
|
||||||
|
guMtxIdentity(mv2);
|
||||||
|
guMtxIdentity(mv3);
|
||||||
|
guMtxScaleApply(modelview,mv1, 1.f, -1.f, 1.f);
|
||||||
|
guMtxTransApply(mv1,mv1, 0.5f * ScreenProps.x, 0.5f * ScreenProps.y, 0.f);
|
||||||
|
guMtxTransApply(mv2,mv2, -0.5f * fBannerWidth, 0.5f * fBannerHeight, 0.f);
|
||||||
|
guMtxTransApply(mv3,mv3, 0.5f * fBannerWidth, -0.5f * fBannerHeight, 0.f);
|
||||||
|
guMtxConcat(mv1, mv2, mv2);
|
||||||
|
guMtxConcat(mv1, mv3, mv3);
|
||||||
|
|
||||||
|
f32 viewportv[6];
|
||||||
|
f32 projectionv[7];
|
||||||
|
|
||||||
|
GX_GetViewportv(viewportv, video->vid_mode());
|
||||||
|
GX_GetProjectionv(projectionv, projection, GX_ORTHOGRAPHIC);
|
||||||
|
|
||||||
|
guVector vecTL;
|
||||||
|
guVector vecBR;
|
||||||
|
GX_Project(0.0f, 0.0f, 0.0f, mv2, projectionv, viewportv, &vecTL.x, &vecTL.y, &vecTL.z);
|
||||||
|
GX_Project(0.0f, 0.0f, 0.0f, mv3, projectionv, viewportv, &vecBR.x, &vecBR.y, &vecBR.z);
|
||||||
|
|
||||||
|
// round up scissor box offset and round down the size
|
||||||
|
u32 scissorX = (u32)(0.5f + std::max(vecTL.x, 0.0f));
|
||||||
|
u32 scissorY = (u32)(0.5f + std::max(vecTL.y, 0.0f));
|
||||||
|
u32 scissorW = (u32)std::max(vecBR.x - vecTL.x, 0.0f);
|
||||||
|
u32 scissorH = (u32)std::max(vecBR.y - vecTL.y, 0.0f);
|
||||||
|
|
||||||
|
GX_SetScissor(scissorX, scissorY, scissorW, scissorH);
|
||||||
|
|
||||||
|
// load projection matrix
|
||||||
|
GX_LoadProjectionMtx(projection, GX_ORTHOGRAPHIC);
|
||||||
|
|
||||||
|
if(gameBanner->getBanner())
|
||||||
|
{
|
||||||
|
gameBanner->getBanner()->Render(modelview, ScreenProps, video->wide(), BannerAlpha);
|
||||||
|
gameBanner->getBanner()->AdvanceFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(AnimationRunning)
|
||||||
|
GX_SetScissor(0, 0, video->width(), video->height());
|
||||||
|
|
||||||
|
// Clear and back to previous projection
|
||||||
|
video->setup2DProjection();
|
||||||
|
GX_InvVtxCache();
|
||||||
|
GX_InvalidateTexAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BannerWindow::DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 filled)
|
||||||
|
{
|
||||||
|
Mtx modelViewMtx;
|
||||||
|
guMtxIdentity(modelViewMtx);
|
||||||
|
GX_LoadPosMtxImm(modelViewMtx, GX_PNMTX0);
|
||||||
|
|
||||||
|
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
|
||||||
|
GX_ClearVtxDesc();
|
||||||
|
GX_InvVtxCache();
|
||||||
|
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||||
|
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
||||||
|
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
|
||||||
|
|
||||||
|
u8 fmt;
|
||||||
|
long n;
|
||||||
|
int i;
|
||||||
|
f32 x2 = x + width;
|
||||||
|
f32 y2 = y + height;
|
||||||
|
guVector v[] = { { x, y, 0.0f }, { x2, y, 0.0f }, { x2, y2, 0.0f }, { x, y2, 0.0f }, { x, y, 0.0f } };
|
||||||
|
|
||||||
|
if (!filled)
|
||||||
|
{
|
||||||
|
fmt = GX_LINESTRIP;
|
||||||
|
n = 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fmt = GX_TRIANGLEFAN;
|
||||||
|
n = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_Begin(fmt, GX_VTXFMT0, n);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
GX_Position3f32(v[i].x, v[i].y, v[i].z);
|
||||||
|
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||||
|
}
|
||||||
|
GX_End();
|
||||||
|
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
|
||||||
|
}
|
82
source/banner/BannerWindow.hpp
Normal file
82
source/banner/BannerWindow.hpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2012 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef BANNERWINDOW_HPP_
|
||||||
|
#define BANNERWINDOW_HPP_
|
||||||
|
|
||||||
|
#include <gccore.h>
|
||||||
|
|
||||||
|
#include "disc.h"
|
||||||
|
#include "AnimatedBanner.h"
|
||||||
|
#include "gui_sound.h"
|
||||||
|
#include "video.hpp"
|
||||||
|
#include "channel/banner.h"
|
||||||
|
|
||||||
|
#define FAVORITE_STARS 5
|
||||||
|
|
||||||
|
class BannerWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BannerWindow();
|
||||||
|
void DeleteBanner();
|
||||||
|
void LoadBanner(Banner *banner, CVideo *vid, u8 *font1, u8 *font2);
|
||||||
|
int GetSelectedGame() { return gameSelected; }
|
||||||
|
void Draw(void);
|
||||||
|
void ZoomIn(void);
|
||||||
|
void PauseZoom(void);
|
||||||
|
void ZoomOut(void);
|
||||||
|
protected:
|
||||||
|
int MainLoop();
|
||||||
|
void Animate(void);
|
||||||
|
void ChangeGame(Banner *banner);
|
||||||
|
void DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 filled);
|
||||||
|
|
||||||
|
static const float fBannerWidth = 608.f;
|
||||||
|
static const float fBannerHeight = 448.f;
|
||||||
|
static const float fIconWidth = 128.f;
|
||||||
|
static const float fIconHeight = 96.f;
|
||||||
|
|
||||||
|
CVideo *video;
|
||||||
|
bool reducedVol;
|
||||||
|
int returnVal;
|
||||||
|
int gameSelected;
|
||||||
|
dir_discHdr dvdheader;
|
||||||
|
|
||||||
|
int MaxAnimSteps;
|
||||||
|
|
||||||
|
int AnimStep;
|
||||||
|
float AnimPosX, AnimPosY;
|
||||||
|
float fAnimScale;
|
||||||
|
bool AnimZoomIn;
|
||||||
|
bool AnimZoomOut;
|
||||||
|
bool AnimationRunning;
|
||||||
|
bool oldAnimationRunning;
|
||||||
|
bool firstRun;
|
||||||
|
|
||||||
|
u8 BGAlpha;
|
||||||
|
u8 BannerAlpha;
|
||||||
|
|
||||||
|
Mtx modelview;
|
||||||
|
Mtx44 projection;
|
||||||
|
Mtx44 originalProjection;
|
||||||
|
Vec2f ScreenProps;
|
||||||
|
|
||||||
|
AnimatedBanner *gameBanner;
|
||||||
|
u8 *sysFont1;
|
||||||
|
u8 *sysFont2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
26
source/banner/LanguageCode.c
Normal file
26
source/banner/LanguageCode.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include <gccore.h>
|
||||||
|
|
||||||
|
const char* CONF_GetLanguageString(void)
|
||||||
|
{
|
||||||
|
static int confLang = 0xdead;
|
||||||
|
|
||||||
|
if(confLang == 0xdead)
|
||||||
|
confLang = CONF_GetLanguage();
|
||||||
|
|
||||||
|
const char*lang;
|
||||||
|
switch( confLang )
|
||||||
|
{
|
||||||
|
case CONF_LANG_JAPANESE: lang = "JPN"; break;
|
||||||
|
default:
|
||||||
|
case CONF_LANG_ENGLISH: lang = "ENG"; break;
|
||||||
|
case CONF_LANG_GERMAN: lang = "GER"; break;
|
||||||
|
case CONF_LANG_FRENCH: lang = "FRA"; break;
|
||||||
|
case CONF_LANG_SPANISH: lang = "SPA"; break;
|
||||||
|
case CONF_LANG_ITALIAN: lang = "ITA"; break;
|
||||||
|
case CONF_LANG_DUTCH: lang = "NED"; break;
|
||||||
|
case CONF_LANG_SIMP_CHINESE:
|
||||||
|
case CONF_LANG_TRAD_CHINESE: lang = "CHN"; break;
|
||||||
|
case CONF_LANG_KOREAN: lang = "KOR"; break;
|
||||||
|
}
|
||||||
|
return lang;
|
||||||
|
}
|
14
source/banner/LanguageCode.h
Normal file
14
source/banner/LanguageCode.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __LANGUAGE_CODE_H_
|
||||||
|
#define __LANGUAGE_CODE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* CONF_GetLanguageString(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
392
source/banner/Layout.cpp
Normal file
392
source/banner/Layout.cpp
Normal file
@ -0,0 +1,392 @@
|
|||||||
|
/*
|
||||||
|
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 "Layout.h"
|
||||||
|
#include "WiiFont.h"
|
||||||
|
#include "U8Archive.h"
|
||||||
|
|
||||||
|
Layout::Layout(u8 *font1, u8 *font2)
|
||||||
|
: header(0)
|
||||||
|
{
|
||||||
|
Wbf1Font = font1;
|
||||||
|
Wbf2Font = font2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout::~Layout()
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
delete panes[i];
|
||||||
|
|
||||||
|
for(u32 i = 0; i < resources.materials.size(); ++i)
|
||||||
|
delete resources.materials[i];
|
||||||
|
|
||||||
|
for(u32 i = 0; i < resources.textures.size(); ++i)
|
||||||
|
delete resources.textures[i];
|
||||||
|
|
||||||
|
for(u32 i = 0; i < resources.fonts.size(); ++i)
|
||||||
|
delete resources.fonts[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Layout::Load(const u8 *brlyt)
|
||||||
|
{
|
||||||
|
if(!brlyt)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const BRLYT_Header *brlytFile = (const BRLYT_Header *) brlyt;
|
||||||
|
|
||||||
|
if(brlytFile->magic != BRLYT_MAGIC || brlytFile->version != BRLYT_VERSION)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Group* last_group = NULL;
|
||||||
|
std::stack<std::map<std::string, Group>*> group_stack;
|
||||||
|
group_stack.push(&groups);
|
||||||
|
|
||||||
|
Pane* last_pane = NULL;
|
||||||
|
std::stack<std::vector<Pane*>*> pane_stack;
|
||||||
|
pane_stack.push(&panes);
|
||||||
|
|
||||||
|
const u8 *position = brlyt + brlytFile->header_len;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < brlytFile->section_count; ++i)
|
||||||
|
{
|
||||||
|
section_t *section = (section_t *) position;
|
||||||
|
position += section->size;
|
||||||
|
|
||||||
|
if(section->magic == Layout::MAGIC)
|
||||||
|
{
|
||||||
|
header = (Layout::Header *) (section + 1);
|
||||||
|
}
|
||||||
|
else if (section->magic == TextureList::MAGIC)
|
||||||
|
{
|
||||||
|
const LytItemList *txl1 = (const LytItemList *) (section+1);
|
||||||
|
const char *nameoffset = ((const char *)(txl1+1));
|
||||||
|
const LytStringTable *stringTable = (const LytStringTable *) (((const u8 *)(txl1+1))+txl1->offset_to_first);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < txl1->num_items; ++i)
|
||||||
|
{
|
||||||
|
const char *name = nameoffset+stringTable[i].offset_filename;
|
||||||
|
|
||||||
|
Texture *texture = new Texture;
|
||||||
|
texture->setName(name);
|
||||||
|
resources.textures.push_back(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (section->magic == MaterialList::MAGIC)
|
||||||
|
{
|
||||||
|
const LytItemList *mat1 = (const LytItemList *) (section+1);
|
||||||
|
const u32 *mat_offsets = (const u32 *) (((const u8 *)(mat1+1))+mat1->offset_to_first);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < mat1->num_items; ++i)
|
||||||
|
{
|
||||||
|
Material *material = new Material;
|
||||||
|
material->Load((Material::Header *) (((const u8 *) section)+mat_offsets[i]));
|
||||||
|
resources.materials.push_back(material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (section->magic == FontList::MAGIC)
|
||||||
|
{
|
||||||
|
// load font list
|
||||||
|
const LytItemList *fnl1 = (const LytItemList *) (section+1);
|
||||||
|
const char *nameoffset = ((const char *)(fnl1+1));
|
||||||
|
const LytStringTable *stringTable = (const LytStringTable *) (((const u8 *)(fnl1+1))+fnl1->offset_to_first);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < fnl1->num_items; i++)
|
||||||
|
{
|
||||||
|
const char *name = nameoffset+stringTable[i].offset_filename;
|
||||||
|
|
||||||
|
WiiFont *font;
|
||||||
|
|
||||||
|
if(strcmp(name, "wbf1.brfna") == 0 || strcmp(name, "RevoIpl_RodinNTLGPro_DB_32_I4.brfnt") == 0) {
|
||||||
|
//! 1st system font or alias for it
|
||||||
|
font = new WiiFont;
|
||||||
|
font->SetName("wbf1.brfna");
|
||||||
|
font->Load(Wbf1Font);
|
||||||
|
if(!font) continue;
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "wbf2.brfna") == 0) {
|
||||||
|
//! 2nd system font
|
||||||
|
font = new WiiFont;
|
||||||
|
font->SetName("wbf2.brfna");
|
||||||
|
font->Load(Wbf2Font);
|
||||||
|
if(!font) continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//! font from banner
|
||||||
|
font = new WiiFont;
|
||||||
|
font->SetName(name);
|
||||||
|
}
|
||||||
|
resources.fonts.push_back(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (section->magic == Pane::MAGIC)
|
||||||
|
{
|
||||||
|
Pane* pane = new Pane;
|
||||||
|
pane->Load((Pane::Header *) section);
|
||||||
|
pane_stack.top()->push_back(last_pane = pane);
|
||||||
|
}
|
||||||
|
else if (section->magic == Bounding::MAGIC)
|
||||||
|
{
|
||||||
|
Bounding* pane = new Bounding;
|
||||||
|
pane->Load((Pane::Header *) section);
|
||||||
|
pane_stack.top()->push_back(last_pane = pane);
|
||||||
|
}
|
||||||
|
else if (section->magic == Picture::MAGIC)
|
||||||
|
{
|
||||||
|
Picture* pane = new Picture;
|
||||||
|
pane->Load((Pane::Header *) section);
|
||||||
|
pane_stack.top()->push_back(last_pane = pane);
|
||||||
|
}
|
||||||
|
else if (section->magic == Window::MAGIC)
|
||||||
|
{
|
||||||
|
Window* pane = new Window;
|
||||||
|
pane->Load((Pane::Header *) section);
|
||||||
|
pane_stack.top()->push_back(last_pane = pane);
|
||||||
|
}
|
||||||
|
else if (section->magic == Textbox::MAGIC)
|
||||||
|
{
|
||||||
|
Textbox* pane = new Textbox;
|
||||||
|
pane->Load((Pane::Header *) section);
|
||||||
|
pane_stack.top()->push_back(last_pane = pane);
|
||||||
|
}
|
||||||
|
else if (section->magic == Layout::MAGIC_PANE_PUSH)
|
||||||
|
{
|
||||||
|
if (last_pane)
|
||||||
|
pane_stack.push(&last_pane->panes);
|
||||||
|
}
|
||||||
|
else if (section->magic == Layout::MAGIC_PANE_POP)
|
||||||
|
{
|
||||||
|
if (pane_stack.size() > 1)
|
||||||
|
pane_stack.pop();
|
||||||
|
}
|
||||||
|
else if (section->magic == Group::MAGIC)
|
||||||
|
{
|
||||||
|
const char *grp = (const char *) (section + 1);
|
||||||
|
std::string group_name(grp, 0, Layout::Group::NAME_LENGTH);
|
||||||
|
Group& group_ref = (*group_stack.top())[group_name];
|
||||||
|
grp += Layout::Group::NAME_LENGTH;
|
||||||
|
|
||||||
|
u16 sub_count = *(u16 *) grp;
|
||||||
|
grp += 4; // 2 bytes reserved
|
||||||
|
|
||||||
|
while (sub_count--)
|
||||||
|
{
|
||||||
|
std::string pane_name(grp, 0, Layout::Group::NAME_LENGTH);
|
||||||
|
group_ref.panes.push_back(pane_name);
|
||||||
|
grp += Layout::Group::NAME_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_group = &group_ref;
|
||||||
|
}
|
||||||
|
else if (section->magic == Layout::MAGIC_GROUP_PUSH)
|
||||||
|
{
|
||||||
|
if (last_group)
|
||||||
|
group_stack.push(&last_group->groups);
|
||||||
|
}
|
||||||
|
else if (section->magic == Layout::MAGIC_GROUP_POP)
|
||||||
|
{
|
||||||
|
if (group_stack.size() > 1)
|
||||||
|
group_stack.pop();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gprintf("Uknown layout section: %08X\n", section->magic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Layout::LoadTextures(const u8 *banner_file)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < resources.textures.size(); ++i)
|
||||||
|
{
|
||||||
|
u32 filesize;
|
||||||
|
const u8 *file = u8_get_file(banner_file, resources.textures[i]->getName().c_str(), &filesize);
|
||||||
|
if (file)
|
||||||
|
resources.textures[i]->Load(file);
|
||||||
|
else
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Layout::LoadFonts(const u8 *banner_file)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < resources.fonts.size(); ++i)
|
||||||
|
{
|
||||||
|
if(resources.fonts[i]->IsLoaded())
|
||||||
|
continue;
|
||||||
|
u32 filesize;
|
||||||
|
const u8 *file = u8_get_file(banner_file, resources.fonts[i]->getName().c_str(), &filesize);
|
||||||
|
if (file)
|
||||||
|
resources.fonts[i]->Load(file);
|
||||||
|
else
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Layout::Render(Mtx &modelview, const Vec2f &ScreenProps, bool widescreen, u8 render_alpha) const
|
||||||
|
{
|
||||||
|
if(!header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Mtx mv;
|
||||||
|
// we draw inverse
|
||||||
|
guMtxScaleApply(modelview, mv, 1.0f, -1.0f, 1.0f);
|
||||||
|
|
||||||
|
// centered draw
|
||||||
|
if(header->centered)
|
||||||
|
guMtxTransApply(mv, mv, ScreenProps.x * 0.5f, ScreenProps.y * 0.5f, 0.f);
|
||||||
|
|
||||||
|
// render all panes
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
panes[i]->Render(resources, render_alpha, mv, widescreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Layout::SetFrame(FrameNumber frame_number)
|
||||||
|
{
|
||||||
|
frame_current = frame_number;
|
||||||
|
|
||||||
|
const u8 key_set = (frame_current >= frame_loop_start);
|
||||||
|
if (key_set)
|
||||||
|
frame_number -= frame_loop_start;
|
||||||
|
|
||||||
|
resources.cur_set = key_set;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
panes[i]->SetFrame(frame_number, key_set);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < resources.materials.size(); ++i)
|
||||||
|
resources.materials[i]->SetFrame(frame_number, key_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Layout::AdvanceFrame()
|
||||||
|
{
|
||||||
|
++frame_current;
|
||||||
|
|
||||||
|
if (frame_current >= frame_loop_end)
|
||||||
|
frame_current = frame_loop_start;
|
||||||
|
|
||||||
|
SetFrame(frame_current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Layout::SetLanguage(const std::string& language)
|
||||||
|
{
|
||||||
|
if(!header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check if that language is found
|
||||||
|
bool lang_found = false;
|
||||||
|
|
||||||
|
// hide panes of non-matching languages
|
||||||
|
std::map<std::string, Group>::iterator itr;
|
||||||
|
for(itr = groups["RootGroup"].groups.begin(); itr != groups["RootGroup"].groups.end(); itr++)
|
||||||
|
{
|
||||||
|
// check if that language exists
|
||||||
|
if(!lang_found && itr->first == language)
|
||||||
|
lang_found = true;
|
||||||
|
|
||||||
|
// some hax, there are some odd "Rso0" "Rso1" groups that shouldn't be hidden
|
||||||
|
// only the 3 character language groups should be
|
||||||
|
if (itr->first != language && itr->first.length() == 3)
|
||||||
|
{
|
||||||
|
std::list<std::string>::iterator itr2;
|
||||||
|
for(itr2 = itr->second.panes.begin(); itr2 != itr->second.panes.end(); itr2++)
|
||||||
|
{
|
||||||
|
Pane* const found = FindPane(*itr2);
|
||||||
|
if (found)
|
||||||
|
found->SetHide(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// show english if langauge is not found
|
||||||
|
if(!lang_found && language != "ENG")
|
||||||
|
{
|
||||||
|
SetLanguage("ENG");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unhide panes of matching language, some banners list language specific panes in multiple language groups
|
||||||
|
std::list<std::string>::iterator itr2;
|
||||||
|
for(itr2 = groups["RootGroup"].groups[language].panes.begin(); itr2 != groups["RootGroup"].groups[language].panes.end(); itr2++)
|
||||||
|
{
|
||||||
|
Pane* const found = FindPane(*itr2);
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
found->SetHide(false);
|
||||||
|
found->SetVisible(true); // all games with languages start as visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Layout::AddPalette(const std::string &name, u8 key_set)
|
||||||
|
{
|
||||||
|
resources.palettes[key_set].push_back(name);
|
||||||
|
|
||||||
|
if(FindTexture(name) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Texture *texture = new Texture;
|
||||||
|
texture->setName(name);
|
||||||
|
resources.textures.push_back(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pane* Layout::FindPane(const std::string& find_name)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
{
|
||||||
|
Pane* found = panes[i]->FindPane(find_name);
|
||||||
|
if(found)
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Material* Layout::FindMaterial(const std::string& find_name)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < resources.materials.size(); ++i)
|
||||||
|
{
|
||||||
|
if (find_name.compare(0, 20, resources.materials[i]->getName()) == 0)
|
||||||
|
return resources.materials[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture* Layout::FindTexture(const std::string& find_name)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < resources.textures.size(); ++i)
|
||||||
|
{
|
||||||
|
if (find_name == resources.textures[i]->getName())
|
||||||
|
return resources.textures[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
145
source/banner/Layout.h
Normal file
145
source/banner/Layout.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef LAYOUT_H_
|
||||||
|
#define LAYOUT_H_
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
#include "BannerTexture.hpp"
|
||||||
|
#include "Material.h"
|
||||||
|
#include "Pane.h"
|
||||||
|
#include "Picture.h"
|
||||||
|
#include "Window.h"
|
||||||
|
#include "WiiFont.h"
|
||||||
|
#include "Textbox.h"
|
||||||
|
|
||||||
|
typedef std::vector<std::string> PaletteList;
|
||||||
|
|
||||||
|
struct BannerResources
|
||||||
|
{
|
||||||
|
MaterialList materials;
|
||||||
|
TextureList textures;
|
||||||
|
FontList fonts;
|
||||||
|
PaletteList palettes[2];
|
||||||
|
u8 cur_set;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Layout
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Layout(u8 *font1, u8* font2);
|
||||||
|
virtual ~Layout();
|
||||||
|
|
||||||
|
static const u32 BRLYT_MAGIC = MAKE_FOURCC('R', 'L', 'Y', 'T');
|
||||||
|
static const u32 BRLYT_VERSION = 0xFEFF0008;
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('l', 'y', 't', '1');
|
||||||
|
static const u32 MAGIC_PANE_PUSH = MAKE_FOURCC('p', 'a', 's', '1');
|
||||||
|
static const u32 MAGIC_PANE_POP = MAKE_FOURCC('p', 'a', 'e', '1');
|
||||||
|
static const u32 MAGIC_GROUP_PUSH = MAKE_FOURCC('g', 'r', 's', '1');
|
||||||
|
static const u32 MAGIC_GROUP_POP = MAKE_FOURCC('g', 'r', 'e', '1');
|
||||||
|
|
||||||
|
bool Load(const u8 *brlyt);
|
||||||
|
bool LoadTextures(const u8 *banner_file);
|
||||||
|
bool LoadFonts(const u8 *banner_file);
|
||||||
|
|
||||||
|
void Render(Mtx &modelview, const Vec2f &ScreenProps, bool widescreen, u8 render_alpha = 0xFF) const;
|
||||||
|
|
||||||
|
FrameNumber GetFrame() const { return frame_current; }
|
||||||
|
void SetFrame(FrameNumber frame_number);
|
||||||
|
void AdvanceFrame();
|
||||||
|
|
||||||
|
void SetLoopStart(FrameNumber loop_start) { frame_loop_start = loop_start; }
|
||||||
|
void SetLoopEnd(FrameNumber loop_end) { frame_loop_end = loop_end; }
|
||||||
|
|
||||||
|
float GetWidth() const { return header->width; }
|
||||||
|
void SetWidth(float _width) { header->width = _width; }
|
||||||
|
|
||||||
|
float GetHeight() const { return header->height; }
|
||||||
|
void SetHeight(float _height) { header->height = _height; }
|
||||||
|
|
||||||
|
bool isCentered() const { return header->centered; }
|
||||||
|
|
||||||
|
void SetLanguage(const std::string& language);
|
||||||
|
|
||||||
|
Pane* FindPane(const std::string& name);
|
||||||
|
Material* FindMaterial(const std::string& name);
|
||||||
|
Texture *FindTexture(const std::string &name);
|
||||||
|
|
||||||
|
void AddPalette(const std::string &name, u8 key_set);
|
||||||
|
protected:
|
||||||
|
struct BRLYT_Header
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 version;
|
||||||
|
u32 filesize;
|
||||||
|
u16 header_len;
|
||||||
|
u16 section_count;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
u8 centered;
|
||||||
|
u8 pad[3];
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct LytItemList
|
||||||
|
{
|
||||||
|
u16 num_items;
|
||||||
|
u16 offset_to_first;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct LytStringTable
|
||||||
|
{
|
||||||
|
u32 offset_filename;
|
||||||
|
u32 pad;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct Group
|
||||||
|
{
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('g', 'r', 'p', '1');
|
||||||
|
static const u32 NAME_LENGTH = 0x10;
|
||||||
|
|
||||||
|
std::map<std::string, Group> groups;
|
||||||
|
std::list<std::string> panes;
|
||||||
|
};
|
||||||
|
|
||||||
|
Layout::Header *header;
|
||||||
|
u8 *Wbf1Font;
|
||||||
|
u8 *Wbf2Font;
|
||||||
|
|
||||||
|
BannerResources resources;
|
||||||
|
PaneList panes;
|
||||||
|
|
||||||
|
FrameNumber frame_current, frame_loop_start, frame_loop_end;
|
||||||
|
|
||||||
|
std::map<std::string, Group> groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
591
source/banner/Material.cpp
Normal file
591
source/banner/Material.cpp
Normal file
@ -0,0 +1,591 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010 - Wii Banner Player Project
|
||||||
|
Copyright (c) 2012 - Dimok and giantpune
|
||||||
|
|
||||||
|
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 <algorithm>
|
||||||
|
#include <math.h>
|
||||||
|
#include "Layout.h"
|
||||||
|
#include "Material.h"
|
||||||
|
|
||||||
|
Material::Material()
|
||||||
|
: flags(0)
|
||||||
|
, texture_maps(0)
|
||||||
|
, texture_srts(0)
|
||||||
|
, texture_coord_gens(0)
|
||||||
|
, chan_control(0)
|
||||||
|
, mat_color(0)
|
||||||
|
, tev_swap_table(0)
|
||||||
|
, ind_srt(0)
|
||||||
|
, ind_stage(0)
|
||||||
|
, tev_stages(0)
|
||||||
|
, alpha_compare(0)
|
||||||
|
, blend_mode(0)
|
||||||
|
, header(0)
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 8; i++ )
|
||||||
|
palette_texture[i] = DEFAULT_PALETTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::Load(Material::Header *file)
|
||||||
|
{
|
||||||
|
header = file;
|
||||||
|
|
||||||
|
// Flags
|
||||||
|
flags = (MatFlags *) &header->flags;
|
||||||
|
|
||||||
|
flags->texture_map = std::min((int)MAX_TEX_MAP, (int)flags->texture_map);
|
||||||
|
flags->texture_srt = std::min((int)MAX_TEX_SRT, (int)flags->texture_srt);
|
||||||
|
flags->texture_coord_gen = std::min((int)MAX_TEX_GEN, (int)flags->texture_coord_gen);
|
||||||
|
flags->ind_srt = flags->ind_srt;
|
||||||
|
flags->ind_stage = std::min((int)MAX_IND_STAGES, (int)flags->ind_stage);
|
||||||
|
flags->tev_stages = std::min((int)MAX_TEV_STAGES, (int)flags->tev_stages);
|
||||||
|
|
||||||
|
u8 *buf_offset = (u8 *) (header+1);
|
||||||
|
|
||||||
|
// texture map
|
||||||
|
if(flags->texture_map)
|
||||||
|
{
|
||||||
|
texture_maps = (TextureMap *) buf_offset;
|
||||||
|
buf_offset += sizeof(TextureMap) * flags->texture_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// texture srt
|
||||||
|
if(flags->texture_srt)
|
||||||
|
{
|
||||||
|
texture_srts = (TextureSrt *) buf_offset;
|
||||||
|
buf_offset += sizeof(TextureSrt) * flags->texture_srt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// texture coord gen
|
||||||
|
if(flags->texture_coord_gen)
|
||||||
|
{
|
||||||
|
texture_coord_gens = (TextureCoordGen *) buf_offset;
|
||||||
|
buf_offset += sizeof(TextureCoordGen) * flags->texture_coord_gen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// channel control
|
||||||
|
if (flags->channel_control)
|
||||||
|
{
|
||||||
|
chan_control = (ChannelControl *) buf_offset;
|
||||||
|
buf_offset += sizeof(ChannelControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// material color
|
||||||
|
if (flags->material_color)
|
||||||
|
{
|
||||||
|
mat_color = (GXColor *) buf_offset;
|
||||||
|
buf_offset += sizeof(GXColor);
|
||||||
|
}
|
||||||
|
//else Default to 0xFFFFFFFF
|
||||||
|
|
||||||
|
// tev swap table
|
||||||
|
if (flags->tev_swap_table)
|
||||||
|
{
|
||||||
|
tev_swap_table = (TevSwap *) buf_offset;
|
||||||
|
buf_offset += sizeof(TevSwap) * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ind srt
|
||||||
|
if(flags->ind_srt)
|
||||||
|
{
|
||||||
|
ind_srt = (IndSrt *) buf_offset;
|
||||||
|
buf_offset += sizeof(IndSrt) * flags->ind_srt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ind stage
|
||||||
|
if(flags->ind_stage)
|
||||||
|
{
|
||||||
|
ind_stage = (IndStage *) buf_offset;
|
||||||
|
buf_offset += sizeof(IndStage) * flags->ind_stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tev stage
|
||||||
|
if(flags->tev_stages)
|
||||||
|
{
|
||||||
|
tev_stages = (TevStage *) buf_offset;
|
||||||
|
buf_offset += sizeof(TevStage) * flags->tev_stages;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alpha compare
|
||||||
|
if (flags->alpha_compare)
|
||||||
|
{
|
||||||
|
alpha_compare = (AlphaCompareModes *) buf_offset;
|
||||||
|
buf_offset += sizeof(AlphaCompareModes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend mode
|
||||||
|
if (flags->blend_mode)
|
||||||
|
{
|
||||||
|
blend_mode = (BlendModes *) buf_offset;
|
||||||
|
buf_offset += sizeof(BlendModes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Material::ApplyChannelControl(u8 render_alpha, bool &modulate_colors) const
|
||||||
|
{
|
||||||
|
if(flags->channel_control)
|
||||||
|
{
|
||||||
|
GX_SetChanCtrl(0, 0, 0, chan_control->color_matsrc, 0, 0, 2 );
|
||||||
|
GX_SetChanCtrl(2, 0, 0, chan_control->alpha_matsrc, 0, 0, 2 );
|
||||||
|
|
||||||
|
if(chan_control->alpha_matsrc != 1 && chan_control->color_matsrc != 1)
|
||||||
|
modulate_colors = false;
|
||||||
|
|
||||||
|
if(!chan_control->alpha_matsrc || !chan_control->color_matsrc)
|
||||||
|
{
|
||||||
|
GXColor matColor = (GXColor){0xff, 0xff, 0xff, MultiplyAlpha(0xff, render_alpha) };
|
||||||
|
|
||||||
|
if(flags->material_color)
|
||||||
|
matColor = (GXColor){ mat_color->r, mat_color->g, mat_color->b,
|
||||||
|
MultiplyAlpha(mat_color->a, render_alpha) };
|
||||||
|
|
||||||
|
GX_SetChanMatColor(4, matColor);
|
||||||
|
|
||||||
|
if((*(u32 *)&matColor) == 0xFFFFFFFF)
|
||||||
|
modulate_colors = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GX_SetChanCtrl(4, 0, 0, 1, 0, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_SetNumChans(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Material::ApplyTexCoordGens(void) const
|
||||||
|
{
|
||||||
|
// texture coord gen
|
||||||
|
for(u32 i = 0; i != flags->texture_coord_gen; ++i)
|
||||||
|
{
|
||||||
|
const TextureCoordGen &tcg = texture_coord_gens[i];
|
||||||
|
GX_SetTexCoordGen(GX_TEXCOORD0 + i, tcg.tgen_typ, tcg.tgen_src, tcg.mtxsrc);
|
||||||
|
|
||||||
|
const u8 mtrx = (tcg.mtxsrc - GX_TEXMTX0) / 3;
|
||||||
|
|
||||||
|
if (tcg.tgen_typ == 1 && tcg.mtxsrc != GX_IDENTITY && mtrx < flags->texture_srt)
|
||||||
|
{
|
||||||
|
const TextureSrt& srt = texture_srts[mtrx];
|
||||||
|
|
||||||
|
const float rotate_rad = DegToRad(srt.rotate);
|
||||||
|
const float cosF = cosf(rotate_rad);
|
||||||
|
const float sinF = sinf(rotate_rad);
|
||||||
|
|
||||||
|
// setup texture matrix
|
||||||
|
Mtx m;
|
||||||
|
m[0][0] = srt.scale_x * cosF;
|
||||||
|
m[0][1] = srt.scale_y * -sinF;
|
||||||
|
m[0][2] = 0.0f;
|
||||||
|
m[0][3] = -0.5f * (m[0][0] + m[0][1]) + srt.translate_x + 0.5f;
|
||||||
|
m[1][0] = srt.scale_x * sinF;
|
||||||
|
m[1][1] = srt.scale_y * cosF;
|
||||||
|
m[1][2] = 0.0f;
|
||||||
|
m[1][3] = -0.5f * (m[1][0] + m[1][1]) + srt.translate_y + 0.5f;
|
||||||
|
m[2][0] = 0.0f;
|
||||||
|
m[2][1] = 0.0f;
|
||||||
|
m[2][2] = 1.0f;
|
||||||
|
m[2][3] = 0.0f;
|
||||||
|
|
||||||
|
GX_LoadTexMtxImm(m, tcg.mtxsrc, GX_MTX3x4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_SetNumTexGens(flags->texture_coord_gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Material::ApplyTevSwapTable(void) const
|
||||||
|
{
|
||||||
|
if (flags->tev_swap_table)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP0 + i,
|
||||||
|
tev_swap_table[i].r, tev_swap_table[i].g,
|
||||||
|
tev_swap_table[i].b, tev_swap_table[i].a);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Material::ApplyTevStages(bool modulate_colors) const
|
||||||
|
{
|
||||||
|
u32 tev_stages_cnt = 0;
|
||||||
|
|
||||||
|
if(flags->tev_stages)
|
||||||
|
{
|
||||||
|
// tev stages
|
||||||
|
for(u32 i = 0; i < flags->tev_stages; ++i)
|
||||||
|
{
|
||||||
|
const TevStage &ts = tev_stages[i];
|
||||||
|
|
||||||
|
GX_SetTevOrder(i, ts.texcoord, ts.tex_map | (ts.lowBit << 8), ts.color );
|
||||||
|
GX_SetTevSwapMode(i, ts.ras_sel, ts.tex_sel);
|
||||||
|
|
||||||
|
GX_SetTevColorIn(i, ts.color_in.a, ts.color_in.b, ts.color_in.c, ts.color_in.d);
|
||||||
|
GX_SetTevColorOp(i, ts.color_in.tevop, ts.color_in.tevbias, ts.color_in.tevscale, ts.color_in.clamp, ts.color_in.tevregid );
|
||||||
|
GX_SetTevKColorSel(i, ts.color_in.sel );
|
||||||
|
|
||||||
|
GX_SetTevAlphaIn(i, ts.alpha_in.a, ts.alpha_in.b, ts.alpha_in.c, ts.alpha_in.d);
|
||||||
|
GX_SetTevAlphaOp(i, ts.alpha_in.tevop, ts.alpha_in.tevbias, ts.alpha_in.tevscale, ts.alpha_in.clamp, ts.alpha_in.tevregid );
|
||||||
|
GX_SetTevKAlphaSel(i, ts.alpha_in.sel );
|
||||||
|
|
||||||
|
GX_SetTevIndirect(i, ts.ind.indtexid, ts.ind.format, ts.ind.bias, ts.ind.mtxid,
|
||||||
|
ts.ind.wrap_s, ts.ind.wrap_t, ts.ind.addprev, ts.ind.utclod, ts.ind.a);
|
||||||
|
|
||||||
|
tev_stages_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(flags->texture_map == 0)
|
||||||
|
{
|
||||||
|
// 1st stage
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0, 0xFF, 0xFF, 4);
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0, 0xF, 4, 0xA, 0xF);
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0, 0x7, 2, 0x5, 0x7);
|
||||||
|
tev_stages_cnt++;
|
||||||
|
}
|
||||||
|
else if(flags->texture_map == 1)
|
||||||
|
{
|
||||||
|
// 1st stage
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0, 0, 0, 0xFF);
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0, 2, 4, 8, 0xF);
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0, 1, 2, 4, 7);
|
||||||
|
tev_stages_cnt++;
|
||||||
|
|
||||||
|
// 2nd stage
|
||||||
|
if(modulate_colors)
|
||||||
|
{
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0 + tev_stages_cnt, 0xFF, 0xFF, 4);
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0 + tev_stages_cnt, 0xF, 0, 0xA, 0xF);
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0 + tev_stages_cnt, 7, 0, 5, 7);
|
||||||
|
tev_stages_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(flags->texture_map == 2)
|
||||||
|
{
|
||||||
|
// 1st stage
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0, 0, 0, 0xFF);
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0, 0xF, 0xF, 0xF, 8);
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0, 7, 7, 7, 4);
|
||||||
|
tev_stages_cnt++;
|
||||||
|
|
||||||
|
// 2nd stage
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0 + tev_stages_cnt, 1, 1, 0xFF);
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0 + tev_stages_cnt, 8, 0, 0xE, 0xF);
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0 + tev_stages_cnt, 4, 0, 6, 7);
|
||||||
|
GX_SetTevKColorSel(GX_TEVSTAGE0 + tev_stages_cnt, 0x1f);
|
||||||
|
GX_SetTevKAlphaSel(GX_TEVSTAGE0 + tev_stages_cnt, 0x1f);
|
||||||
|
tev_stages_cnt++;
|
||||||
|
|
||||||
|
// 3rd stage
|
||||||
|
if(modulate_colors)
|
||||||
|
{
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0 + tev_stages_cnt, 0xFF, 0xFF, 4);
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0 + tev_stages_cnt, 0xF, 0, 0xA, 0xF);
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0 + tev_stages_cnt, 7, 0, 5, 7);
|
||||||
|
tev_stages_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u32 TevKDefault[] = { 0x1F, 0x1B, 0x17, 0x13, 0x1E, 0x1A, 0x16, 0x12 };
|
||||||
|
|
||||||
|
for(int i = 0; i < flags->texture_map; i++)
|
||||||
|
{
|
||||||
|
GX_SetTevOrder(i, i, i, 0xff );
|
||||||
|
|
||||||
|
GX_SetTevColorIn(i, 0xf, 8, 0xe, i ? 0xf : 0 );
|
||||||
|
GX_SetTevAlphaIn(i, 7, 4, 6, i ? 7 : 0 );
|
||||||
|
GX_SetTevKColorSel(i, TevKDefault[i] );
|
||||||
|
GX_SetTevKAlphaSel(i, TevKDefault[i] );
|
||||||
|
tev_stages_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0 + tev_stages_cnt, 0xff, 0xff, 0xff );
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0 + tev_stages_cnt, 2, 4, 0, 0xf );
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0 + tev_stages_cnt, 1, 2, 0, 7 );
|
||||||
|
tev_stages_cnt++;
|
||||||
|
|
||||||
|
if(modulate_colors)
|
||||||
|
{
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0 + tev_stages_cnt, 0xFF, 0xFF, 4);
|
||||||
|
GX_SetTevColorIn(GX_TEVSTAGE0 + tev_stages_cnt, 0xF, 0, 0xA, 0xF);
|
||||||
|
GX_SetTevAlphaIn(GX_TEVSTAGE0 + tev_stages_cnt, 7, 0, 5, 7);
|
||||||
|
tev_stages_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(u32 i = 0; i < tev_stages_cnt; i++)
|
||||||
|
{
|
||||||
|
GX_SetTevColorOp(GX_TEVSTAGE0 + i, 0, 0, 0, 1, 0);
|
||||||
|
GX_SetTevAlphaOp(GX_TEVSTAGE0 + i, 0, 0, 0, 1, 0);
|
||||||
|
GX_SetTevDirect(GX_TEVSTAGE0 + i);
|
||||||
|
GX_SetTevSwapMode(GX_TEVSTAGE0 + i, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable correct number of tev stages
|
||||||
|
GX_SetNumTevStages(tev_stages_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Material::ApplyIndStages(void) const
|
||||||
|
{
|
||||||
|
for( int i = 0; i < flags->ind_srt; i++ )
|
||||||
|
{
|
||||||
|
const IndSrt &ind = ind_srt[i];
|
||||||
|
|
||||||
|
const float rotate_rad = DegToRad(ind.rotate);
|
||||||
|
// maybe add a look up table
|
||||||
|
float cosF = cosf(rotate_rad);
|
||||||
|
float sinF = sinf(rotate_rad);
|
||||||
|
|
||||||
|
int scale_exp = 0;
|
||||||
|
f32 mtx23[2][3];
|
||||||
|
f32 mtxabs23[2][3];
|
||||||
|
|
||||||
|
mtx23[0][0] = ind.scale_x * cosF;
|
||||||
|
mtx23[0][1] = ind.scale_y * -sinF;
|
||||||
|
mtx23[0][2] = ind.translate_x;
|
||||||
|
|
||||||
|
mtx23[1][0] = ind.scale_x * sinF;
|
||||||
|
mtx23[1][1] = ind.scale_y * cosF;
|
||||||
|
mtx23[1][2] = ind.translate_y;
|
||||||
|
|
||||||
|
// create matrix with abs values
|
||||||
|
// compiler will optimize the loops
|
||||||
|
for(int n = 0; n < 2; n++)
|
||||||
|
for(int m = 0; m < 3; m++)
|
||||||
|
mtxabs23[n][m] = fabs(mtx23[n][m]);
|
||||||
|
|
||||||
|
// hardcore clamping going on here
|
||||||
|
if( (mtxabs23[0][0] >= 1.0f)
|
||||||
|
|| (mtxabs23[0][1] >= 1.0f)
|
||||||
|
|| (mtxabs23[0][2] >= 1.0f)
|
||||||
|
|| (mtxabs23[1][0] >= 1.0f)
|
||||||
|
|| (mtxabs23[1][1] >= 1.0f)
|
||||||
|
|| (mtxabs23[1][2] >= 1.0f))
|
||||||
|
{
|
||||||
|
while( scale_exp < 0x2E
|
||||||
|
&& ((mtxabs23[0][0] >= 1.0f)
|
||||||
|
|| (mtxabs23[0][1] >= 1.0f)
|
||||||
|
|| (mtxabs23[0][2] >= 1.0f)
|
||||||
|
|| (mtxabs23[1][0] >= 1.0f)
|
||||||
|
|| (mtxabs23[1][1] >= 1.0f)
|
||||||
|
|| (mtxabs23[1][2] >= 1.0f)))
|
||||||
|
{
|
||||||
|
for(int n = 0; n < 2; n++)
|
||||||
|
{
|
||||||
|
for(int m = 0; m < 3; m++)
|
||||||
|
{
|
||||||
|
mtx23[n][m] *= 0.5f;
|
||||||
|
mtxabs23[n][m] *= 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scale_exp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( (mtxabs23[0][0] < 0.5f)
|
||||||
|
&& (mtxabs23[0][1] < 0.5f)
|
||||||
|
&& (mtxabs23[0][2] < 0.5f)
|
||||||
|
&& (mtxabs23[1][0] < 0.5f)
|
||||||
|
&& (mtxabs23[1][1] < 0.5f)
|
||||||
|
&& (mtxabs23[1][2] < 0.5f))
|
||||||
|
{
|
||||||
|
while( scale_exp > -0x11
|
||||||
|
&& (mtxabs23[0][0] < 0.5f)
|
||||||
|
&& (mtxabs23[0][1] < 0.5f)
|
||||||
|
&& (mtxabs23[0][2] < 0.5f)
|
||||||
|
&& (mtxabs23[1][0] < 0.5f)
|
||||||
|
&& (mtxabs23[1][1] < 0.5f)
|
||||||
|
&& (mtxabs23[1][2] < 0.5f))
|
||||||
|
{
|
||||||
|
for(int n = 0; n < 2; n++)
|
||||||
|
{
|
||||||
|
for(int m = 0; m < 3; m++)
|
||||||
|
{
|
||||||
|
mtx23[n][m] *= 2.0f;
|
||||||
|
mtxabs23[n][m] *= 2.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scale_exp--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_SetIndTexMatrix(GX_ITM_0 + i, mtx23, scale_exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0; i < flags->ind_stage; i++ )
|
||||||
|
{
|
||||||
|
const IndStage &stage = ind_stage[i];
|
||||||
|
GX_SetIndTexOrder(i, stage.texcoord, stage.tex_map);
|
||||||
|
GX_SetIndTexCoordScale(i, stage.scale_s, stage.scale_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_SetNumIndStages(flags->ind_stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Material::ApplyTextures(const BannerResources& resources) const
|
||||||
|
{
|
||||||
|
u8 tlut_name = 0;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < flags->texture_map; ++i)
|
||||||
|
{
|
||||||
|
const TextureMap &tr = texture_maps[i];
|
||||||
|
|
||||||
|
if(palette_texture[i] == DEFAULT_PALETTE)
|
||||||
|
{
|
||||||
|
if (tr.tex_index < resources.textures.size())
|
||||||
|
resources.textures[tr.tex_index]->Apply(tlut_name, i, tr.wrap_s, tr.wrap_t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// find texture from palette
|
||||||
|
if(palette_texture[i] >= resources.palettes[resources.cur_set].size())
|
||||||
|
{
|
||||||
|
gprintf( "palette index is out of range %i\n", palette_texture[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(u32 n = 0; n < resources.textures.size(); n++)
|
||||||
|
{
|
||||||
|
if(resources.textures[n]->getName() == resources.palettes[resources.cur_set][palette_texture[i]])
|
||||||
|
{
|
||||||
|
resources.textures[n]->Apply(tlut_name, i, tr.wrap_s, tr.wrap_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// invalidate texture cache
|
||||||
|
GX_InvalidateTexAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::Apply(const BannerResources& resources, u8 render_alpha, bool modulate_colors) const
|
||||||
|
{
|
||||||
|
// channel control and material color
|
||||||
|
ApplyChannelControl(render_alpha, modulate_colors);
|
||||||
|
|
||||||
|
// texture coordinates gen
|
||||||
|
ApplyTexCoordGens();
|
||||||
|
|
||||||
|
// bind textures
|
||||||
|
ApplyTextures(resources);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
// tev reg colors
|
||||||
|
if(i < 3)
|
||||||
|
GX_SetTevColorS10(GX_TEVREG0 + i, header->color_regs[i]);
|
||||||
|
|
||||||
|
// tev k colors
|
||||||
|
GX_SetTevKColor(GX_KCOLOR0 + i, header->color_constants[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tev swap colors
|
||||||
|
ApplyTevSwapTable();
|
||||||
|
|
||||||
|
// tev stages
|
||||||
|
ApplyTevStages(modulate_colors);
|
||||||
|
|
||||||
|
// ind stages
|
||||||
|
ApplyIndStages();
|
||||||
|
|
||||||
|
// alpha compare
|
||||||
|
if(flags->alpha_compare)
|
||||||
|
GX_SetAlphaCompare(alpha_compare->compare & 0xf, alpha_compare->ref0,
|
||||||
|
alpha_compare->op, alpha_compare->compare >> 4, alpha_compare->ref1);
|
||||||
|
else
|
||||||
|
GX_SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
||||||
|
|
||||||
|
// blend mode
|
||||||
|
if (flags->blend_mode)
|
||||||
|
GX_SetBlendMode(blend_mode->type, blend_mode->src_factor, blend_mode->dst_factor, blend_mode->logical_op);
|
||||||
|
else
|
||||||
|
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::ProcessHermiteKey(const KeyType& type, float value)
|
||||||
|
{
|
||||||
|
if (type.type == ANIMATION_TYPE_TEXTURE_SRT) // texture scale/rotate/translate
|
||||||
|
{
|
||||||
|
if (type.target < 5 && type.index < flags->texture_srt)
|
||||||
|
{
|
||||||
|
(&texture_srts[type.index].translate_x)[type.target] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: Something is still here: target 0-4 and index 1-9 while texture_srt is 1, value is always 0 or 1
|
||||||
|
return; // TODO remove this
|
||||||
|
}
|
||||||
|
else if (type.type == ANIMATION_TYPE_IND_MATERIAL) // ind texture crap
|
||||||
|
{
|
||||||
|
if (type.target < 5 && type.index < flags->ind_srt)
|
||||||
|
{
|
||||||
|
(&ind_srt[type.index].translate_x)[type.target] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return; // TODO remove this
|
||||||
|
}
|
||||||
|
else if (type.type == ANIMATION_TYPE_MATERIAL_COLOR) // material color
|
||||||
|
{
|
||||||
|
if (type.target < 4)
|
||||||
|
{
|
||||||
|
// mat_color
|
||||||
|
if(flags->material_color)
|
||||||
|
(&mat_color->r)[type.target] = FLOAT_2_U8(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (type.target < 0x10)
|
||||||
|
{
|
||||||
|
(&header->color_regs->r)[type.target - 4] = FLOAT_2_S16(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (type.target < 0x20)
|
||||||
|
{
|
||||||
|
(&header->color_constants->r)[type.target - 0x10] = FLOAT_2_U8(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Base::ProcessHermiteKey(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data)
|
||||||
|
{
|
||||||
|
if (type.type == ANIMATION_TYPE_TEXTURE_PALETTE) // tpl palette
|
||||||
|
{
|
||||||
|
if(type.index < MAX_TEX_MAP)
|
||||||
|
{
|
||||||
|
palette_texture[type.index] = data.data2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Base::ProcessStepKey(type, data);
|
||||||
|
}
|
253
source/banner/Material.h
Normal file
253
source/banner/Material.h
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010 - Wii Banner Player Project
|
||||||
|
Copyright (c) 2012 - Dimok and giantpune
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WII_BNR_MATERIAL_H_
|
||||||
|
#define WII_BNR_MATERIAL_H_
|
||||||
|
|
||||||
|
#include "Animator.h"
|
||||||
|
#include "BannerTexture.hpp"
|
||||||
|
|
||||||
|
struct BannerResources;
|
||||||
|
|
||||||
|
class Material : public Animator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Animator Base;
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
char name[20];
|
||||||
|
GXColorS10 color_regs[3];
|
||||||
|
GXColor color_constants[4];
|
||||||
|
u32 flags;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
Material();
|
||||||
|
|
||||||
|
void Load(Material::Header *mat);
|
||||||
|
void Apply(const BannerResources& resources, u8 render_alpha, bool modulate) const;
|
||||||
|
const char *getName() const { return header->name; }
|
||||||
|
|
||||||
|
const Material::Header *GetHeader() const { return header; }
|
||||||
|
protected:
|
||||||
|
void ProcessHermiteKey(const KeyType& type, float value);
|
||||||
|
void ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ApplyChannelControl(u8 render_alpha, bool &modulate_colors) const;
|
||||||
|
void ApplyTevSwapTable(void) const;
|
||||||
|
void ApplyTexCoordGens(void) const;
|
||||||
|
void ApplyTevStages(bool modulate_colors) const;
|
||||||
|
void ApplyIndStages(void) const;
|
||||||
|
void ApplyTextures(const BannerResources& resources) const;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MAX_TEX_MAP = 8,
|
||||||
|
MAX_TEX_SRT = 10,
|
||||||
|
MAX_TEX_GEN = 8,
|
||||||
|
MAX_IND_STAGES = 4,
|
||||||
|
MAX_TEV_STAGES = 16,
|
||||||
|
DEFAULT_PALETTE = 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MatFlags
|
||||||
|
{
|
||||||
|
u32 pad2 : 4;
|
||||||
|
u32 material_color : 1;
|
||||||
|
u32 pad : 1;
|
||||||
|
u32 channel_control : 1;
|
||||||
|
u32 blend_mode : 1;
|
||||||
|
u32 alpha_compare : 1;
|
||||||
|
u32 tev_stages : 5;
|
||||||
|
u32 ind_stage : 3;
|
||||||
|
u32 ind_srt : 2;
|
||||||
|
u32 tev_swap_table : 1;
|
||||||
|
u32 texture_coord_gen : 4;
|
||||||
|
u32 texture_srt : 4;
|
||||||
|
u32 texture_map : 4;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct TextureMap
|
||||||
|
{
|
||||||
|
u16 tex_index;
|
||||||
|
u8 wrap_s;
|
||||||
|
u8 wrap_t;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct TextureSrt
|
||||||
|
{
|
||||||
|
f32 translate_x;
|
||||||
|
f32 translate_y;
|
||||||
|
f32 rotate;
|
||||||
|
f32 scale_x;
|
||||||
|
f32 scale_y;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct TextureCoordGen
|
||||||
|
{
|
||||||
|
u8 tgen_typ;
|
||||||
|
u8 tgen_src;
|
||||||
|
u8 mtxsrc;
|
||||||
|
u8 pad;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct ChannelControl
|
||||||
|
{
|
||||||
|
u8 color_matsrc;
|
||||||
|
u8 alpha_matsrc;
|
||||||
|
u16 pad;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct IndSrt
|
||||||
|
{
|
||||||
|
f32 translate_x;
|
||||||
|
f32 translate_y;
|
||||||
|
f32 rotate;
|
||||||
|
f32 scale_x;
|
||||||
|
f32 scale_y;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct IndStage
|
||||||
|
{
|
||||||
|
u8 texcoord;
|
||||||
|
u8 tex_map;
|
||||||
|
u8 scale_s;
|
||||||
|
u8 scale_t;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct BlendModes
|
||||||
|
{
|
||||||
|
u8 type, src_factor, dst_factor, logical_op;
|
||||||
|
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct AlphaCompareModes
|
||||||
|
{
|
||||||
|
u8 compare, op, ref0, ref1;
|
||||||
|
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct TevSwap
|
||||||
|
{
|
||||||
|
u32 a : 2;
|
||||||
|
u32 b : 2;
|
||||||
|
u32 g : 2;
|
||||||
|
u32 r : 2;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct TevStage
|
||||||
|
{
|
||||||
|
u32 texcoord : 8;
|
||||||
|
u32 color : 8;
|
||||||
|
u32 tex_map : 8;
|
||||||
|
|
||||||
|
u32 unk : 3;
|
||||||
|
u32 tex_sel : 2;
|
||||||
|
u32 ras_sel : 2;
|
||||||
|
u32 lowBit : 1;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 b : 4;
|
||||||
|
u32 a : 4;
|
||||||
|
|
||||||
|
u32 d : 4;
|
||||||
|
u32 c : 4;
|
||||||
|
|
||||||
|
u32 tevscale : 2;
|
||||||
|
u32 tevbias : 2;
|
||||||
|
u32 tevop : 4;
|
||||||
|
|
||||||
|
u32 sel : 5;
|
||||||
|
u32 tevregid : 2;
|
||||||
|
u32 clamp : 1;
|
||||||
|
|
||||||
|
} __attribute__((packed)) color_in, __attribute__((packed)) alpha_in;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 unk1 : 6;
|
||||||
|
u32 indtexid : 2;
|
||||||
|
|
||||||
|
u32 unk2 : 1;
|
||||||
|
u32 mtxid : 4;
|
||||||
|
u32 bias : 3;
|
||||||
|
|
||||||
|
u32 unk3 : 2;
|
||||||
|
u32 wrap_t : 3;
|
||||||
|
u32 wrap_s : 3;
|
||||||
|
|
||||||
|
u32 unk4 : 2;
|
||||||
|
u32 a : 2;
|
||||||
|
u32 utclod : 1;
|
||||||
|
u32 addprev : 1;
|
||||||
|
u32 format : 2;
|
||||||
|
|
||||||
|
} __attribute__((packed)) ind;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// Material flags
|
||||||
|
MatFlags *flags;
|
||||||
|
|
||||||
|
// Texture
|
||||||
|
TextureMap *texture_maps;
|
||||||
|
TextureSrt *texture_srts;
|
||||||
|
TextureCoordGen *texture_coord_gens;
|
||||||
|
|
||||||
|
// Color channels
|
||||||
|
ChannelControl *chan_control;
|
||||||
|
|
||||||
|
// Material colors
|
||||||
|
GXColor *mat_color;
|
||||||
|
|
||||||
|
// Tev color swap
|
||||||
|
TevSwap *tev_swap_table;
|
||||||
|
|
||||||
|
// Indirect textures
|
||||||
|
IndSrt *ind_srt;
|
||||||
|
IndStage *ind_stage;
|
||||||
|
|
||||||
|
// Texture environment
|
||||||
|
TevStage *tev_stages;
|
||||||
|
|
||||||
|
// Blending and alpha compare
|
||||||
|
AlphaCompareModes *alpha_compare;
|
||||||
|
BlendModes *blend_mode;
|
||||||
|
|
||||||
|
// palette animation
|
||||||
|
u8 palette_texture[MAX_TEX_MAP];
|
||||||
|
|
||||||
|
//! Material header
|
||||||
|
Material::Header *header;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MaterialList : public std::vector<Material*>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('m', 'a', 't', '1');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
165
source/banner/Pane.cpp
Normal file
165
source/banner/Pane.cpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
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 "Pane.h"
|
||||||
|
#include "Layout.h"
|
||||||
|
|
||||||
|
void Pane::Load(Pane::Header *pan)
|
||||||
|
{
|
||||||
|
if(!pan)
|
||||||
|
return;
|
||||||
|
|
||||||
|
header = pan;
|
||||||
|
hide = false;
|
||||||
|
RootPane = !strcmp( header->name, "RootPane" );
|
||||||
|
AlignHor = header->origin % 3;
|
||||||
|
AlignVer = 2 - header->origin / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pane::~Pane()
|
||||||
|
{
|
||||||
|
// delete children
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
delete panes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pane::SetFrame(FrameNumber frame, u8 key_set)
|
||||||
|
{
|
||||||
|
// setframe on self
|
||||||
|
Animator::SetFrame(frame, key_set);
|
||||||
|
|
||||||
|
// setframe on children
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
panes[i]->SetFrame(frame, key_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pane::Render(const BannerResources& resources, u8 parent_alpha, Mtx &modelview,
|
||||||
|
bool widescreen, bool modify_alpha) const
|
||||||
|
{
|
||||||
|
if (!header || !GetVisible() || GetHide())
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8 render_alpha = header->alpha;
|
||||||
|
|
||||||
|
if(RootPane && parent_alpha != 0xFF)
|
||||||
|
{
|
||||||
|
modify_alpha = true;
|
||||||
|
render_alpha = MultiplyAlpha(header->alpha, parent_alpha);
|
||||||
|
}
|
||||||
|
if(!RootPane && modify_alpha)
|
||||||
|
{
|
||||||
|
render_alpha = MultiplyAlpha(header->alpha, parent_alpha);
|
||||||
|
}
|
||||||
|
else if(GetInfluencedAlpha() && header->alpha != 0xff)
|
||||||
|
{
|
||||||
|
modify_alpha = true;
|
||||||
|
parent_alpha = MultiplyAlpha(header->alpha, parent_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ws_scale = 1.0f;
|
||||||
|
|
||||||
|
if(widescreen && GetWidescren())
|
||||||
|
{
|
||||||
|
ws_scale *= 0.82f; // should actually be 0.75?
|
||||||
|
widescreen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mtx m1,m2,m3,m4, mv;
|
||||||
|
guMtxIdentity (m1);
|
||||||
|
|
||||||
|
// Scale
|
||||||
|
guMtxScaleApply(m1,m1, header->scale.x * ws_scale, header->scale.y, 1.f);
|
||||||
|
|
||||||
|
// Rotate
|
||||||
|
guMtxRotDeg ( m2, 'x', header->rotate.x );
|
||||||
|
guMtxRotDeg ( m3, 'y', header->rotate.y );
|
||||||
|
guMtxRotDeg ( m4, 'z', header->rotate.z );
|
||||||
|
guMtxConcat(m2, m3, m2);
|
||||||
|
guMtxConcat(m2, m4, m2);
|
||||||
|
guMtxConcat(m1, m2, m1);
|
||||||
|
|
||||||
|
// Translate
|
||||||
|
guMtxTransApply(m1,m1, header->translate.x, header->translate.y, header->translate.z);
|
||||||
|
|
||||||
|
guMtxConcat (modelview, m1, mv);
|
||||||
|
|
||||||
|
// render self
|
||||||
|
Draw(resources, render_alpha, ws_scale, mv);
|
||||||
|
|
||||||
|
// render children
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
panes[i]->Render(resources, render_alpha, mv, widescreen, modify_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pane* Pane::FindPane(const std::string& find_name)
|
||||||
|
{
|
||||||
|
if(!header)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (find_name.compare(0, 0x10, getName()) == 0)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < panes.size(); ++i)
|
||||||
|
{
|
||||||
|
Pane *found = panes[i]->FindPane(find_name);
|
||||||
|
if (found)
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pane::ProcessHermiteKey(const KeyType& type, float value)
|
||||||
|
{
|
||||||
|
if (type.type == ANIMATION_TYPE_VERTEX_COLOR) // vertex color
|
||||||
|
{
|
||||||
|
// only alpha is supported for Panes afaict
|
||||||
|
if (0x10 == type.target)
|
||||||
|
{
|
||||||
|
header->alpha = FLOAT_2_U8(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type.type == ANIMATION_TYPE_PANE) // pane animation
|
||||||
|
{
|
||||||
|
if (type.target < 10)
|
||||||
|
{
|
||||||
|
(&header->translate.x)[type.target] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Base::ProcessHermiteKey(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pane::ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data)
|
||||||
|
{
|
||||||
|
if (type.type == ANIMATION_TYPE_VISIBILITY) // visibility
|
||||||
|
{
|
||||||
|
SetVisible(!!data.data2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Base::ProcessStepKey(type, data);
|
||||||
|
}
|
143
source/banner/Pane.h
Normal file
143
source/banner/Pane.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WII_BNR_PANE_H_
|
||||||
|
#define WII_BNR_PANE_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <gccore.h>
|
||||||
|
|
||||||
|
#include "Animator.h"
|
||||||
|
|
||||||
|
struct BannerResources;
|
||||||
|
|
||||||
|
class Pane;
|
||||||
|
typedef std::vector<Pane*> PaneList;
|
||||||
|
|
||||||
|
class Pane : public Animator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Animator Base;
|
||||||
|
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('p', 'a', 'n', '1');
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 size_section;
|
||||||
|
u8 flags;
|
||||||
|
u8 origin;
|
||||||
|
u8 alpha;
|
||||||
|
u8 padding;
|
||||||
|
char name [0x10];
|
||||||
|
char user_data [0x08];
|
||||||
|
Vec3f translate;
|
||||||
|
Vec3f rotate;
|
||||||
|
Vec2f scale;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
Pane() : header(NULL) {}
|
||||||
|
virtual ~Pane();
|
||||||
|
|
||||||
|
void Load(Pane::Header *file);
|
||||||
|
|
||||||
|
const char *getName() const { if(!header) return ""; return header->name; }
|
||||||
|
|
||||||
|
void Render(const BannerResources& resources, u8 parent_alpha, Mtx &modelview,
|
||||||
|
bool widescreen, bool modify_alpha = false) const;
|
||||||
|
|
||||||
|
void SetFrame(FrameNumber frame, u8 key_set);
|
||||||
|
|
||||||
|
void SetScale(float scale) { if(header) header->scale.x = header->scale.y = scale; }
|
||||||
|
|
||||||
|
bool GetHide() const { return hide; }
|
||||||
|
void SetHide(bool _hide) { hide = _hide; }
|
||||||
|
|
||||||
|
bool GetVisible() const { if(!header) return false; return ((header->flags & (1 << FLAG_VISIBLE)) != 0); }
|
||||||
|
void SetVisible(bool visible)
|
||||||
|
{
|
||||||
|
if(!header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(visible)
|
||||||
|
header->flags |= (1 << FLAG_VISIBLE);
|
||||||
|
else
|
||||||
|
header->flags &= ~(1 << FLAG_VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 GetOriginX() const { return AlignHor; }
|
||||||
|
u8 GetOriginY() const { return AlignVer; }
|
||||||
|
|
||||||
|
float GetWidth() const { if(!header) return 0.f; return header->width; }
|
||||||
|
float GetHeight() const { if(!header) return 0.f; return header->height; }
|
||||||
|
|
||||||
|
bool GetInfluencedAlpha() const { if(!header) return false; return ((header->flags & (1 << FLAG_INFLUENCED_ALPHA)) != 0); }
|
||||||
|
void SetInfluencedAlpha(bool influenced)
|
||||||
|
{
|
||||||
|
if(!header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(influenced)
|
||||||
|
header->flags |= (1 << FLAG_INFLUENCED_ALPHA);
|
||||||
|
else
|
||||||
|
header->flags &= ~(1 << FLAG_INFLUENCED_ALPHA);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetWidescren() const { return ((header->flags & (1 << FLAG_WIDESCREEN)) != 0); }
|
||||||
|
|
||||||
|
Pane* FindPane(const std::string& name); // recursive
|
||||||
|
|
||||||
|
PaneList panes;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ProcessHermiteKey(const KeyType& type, float value);
|
||||||
|
void ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void Draw(const BannerResources&, u8, const float, Mtx&) const {}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FLAG_VISIBLE = 0x00,
|
||||||
|
FLAG_INFLUENCED_ALPHA = 0x01,
|
||||||
|
FLAG_WIDESCREEN = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
Pane::Header *header;
|
||||||
|
bool hide; // used by the groups
|
||||||
|
bool RootPane;
|
||||||
|
u8 AlignVer;
|
||||||
|
u8 AlignHor;
|
||||||
|
};
|
||||||
|
|
||||||
|
// apparently Bounding is just a regular pane
|
||||||
|
class Bounding : public Pane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('b', 'n', 'd', '1');
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
34
source/banner/Picture.cpp
Normal file
34
source/banner/Picture.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
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 "Picture.h"
|
||||||
|
|
||||||
|
void Picture::Load(Pane::Header * file)
|
||||||
|
{
|
||||||
|
if(!file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Pane::Load(file);
|
||||||
|
QuadPane::Load((QuadPane::Header *) (file+1));
|
||||||
|
}
|
40
source/banner/Picture.h
Normal file
40
source/banner/Picture.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WII_BNR_PICTURE_H_
|
||||||
|
#define WII_BNR_PICTURE_H_
|
||||||
|
|
||||||
|
#include "QuadPane.h"
|
||||||
|
|
||||||
|
class Picture : public QuadPane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef QuadPane Base;
|
||||||
|
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('p', 'i', 'c', '1');
|
||||||
|
|
||||||
|
void Load(Pane::Header *hdr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
126
source/banner/QuadPane.cpp
Normal file
126
source/banner/QuadPane.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
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 "QuadPane.h"
|
||||||
|
#include "Layout.h"
|
||||||
|
|
||||||
|
void QuadPane::Load(QuadPane::Header* file)
|
||||||
|
{
|
||||||
|
if(!file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
header = file;
|
||||||
|
tex_coords = (const TexCoords *) (header+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void QuadPane::SetVertex(int ind, float x, float y, u8 render_alpha) const
|
||||||
|
{
|
||||||
|
// position
|
||||||
|
GX_Position3f32(x, y, 0.f);
|
||||||
|
|
||||||
|
const GXColor &vertex_color = header->vertex_colors[ind];
|
||||||
|
// color
|
||||||
|
GX_Color4u8(vertex_color.r, vertex_color.g, vertex_color.b,
|
||||||
|
MultiplyAlpha(vertex_color.a, render_alpha));
|
||||||
|
|
||||||
|
// texture coord
|
||||||
|
for(u32 i = 0; i < header->tex_coord_count; i++)
|
||||||
|
GX_TexCoord2f32(tex_coords[i].coords[ind].s, tex_coords[i].coords[ind].t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool IsModulateColor(GXColor *colors, u8 render_alpha)
|
||||||
|
{
|
||||||
|
if(render_alpha != 0xFF)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
u32 *colorPtr = (u32 *) colors;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
if(colorPtr[i] != 0xFFFFFFFF)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuadPane::Draw(const BannerResources& resources, u8 render_alpha, const float ws_scale, Mtx &modelview, u16 material_index, u8 texture_flip) const
|
||||||
|
{
|
||||||
|
if(!header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (material_index < resources.materials.size())
|
||||||
|
{
|
||||||
|
bool modulate_color = IsModulateColor(header->vertex_colors, render_alpha);
|
||||||
|
resources.materials[material_index]->Apply(resources, render_alpha, modulate_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mtx m, mv;
|
||||||
|
guMtxIdentity (m);
|
||||||
|
|
||||||
|
guMtxTransApply(m,m, -0.5f * GetOriginX(), -0.5f * GetOriginY(), 0.f);
|
||||||
|
guMtxScaleApply(m,m, GetWidth(), GetHeight(), 1.f);
|
||||||
|
|
||||||
|
guMtxConcat (modelview, m, mv);
|
||||||
|
|
||||||
|
GX_LoadPosMtxImm (mv, GX_PNMTX0);
|
||||||
|
|
||||||
|
GX_ClearVtxDesc();
|
||||||
|
GX_InvVtxCache();
|
||||||
|
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||||
|
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
||||||
|
for(u32 i = 0; i < header->tex_coord_count; i++)
|
||||||
|
GX_SetVtxDesc(GX_VA_TEX0+i, GX_DIRECT);
|
||||||
|
|
||||||
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||||
|
if(texture_flip)
|
||||||
|
{
|
||||||
|
SetVertex(0, 0.f, 0.f, render_alpha);
|
||||||
|
SetVertex(1, 1.f, 0.f, render_alpha);
|
||||||
|
SetVertex(3, 1.f, 1.f, render_alpha);
|
||||||
|
SetVertex(2, 0.f, 1.f, render_alpha);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetVertex(2, 0.f, 0.f, render_alpha);
|
||||||
|
SetVertex(3, 1.f, 0.f, render_alpha);
|
||||||
|
SetVertex(1, 1.f, 1.f, render_alpha);
|
||||||
|
SetVertex(0, 0.f, 1.f, render_alpha);
|
||||||
|
}
|
||||||
|
GX_End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuadPane::ProcessHermiteKey(const KeyType& type, float value)
|
||||||
|
{
|
||||||
|
if (type.type == ANIMATION_TYPE_VERTEX_COLOR) // vertex color
|
||||||
|
{
|
||||||
|
if (type.target < 0x10)
|
||||||
|
{
|
||||||
|
// vertex colors
|
||||||
|
(&header->vertex_colors->r)[type.target] = FLOAT_2_U8(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Base::ProcessHermiteKey(type, value);
|
||||||
|
}
|
73
source/banner/QuadPane.h
Normal file
73
source/banner/QuadPane.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef _QUAD_PANE_H_
|
||||||
|
#define _QUAD_PANE_H_
|
||||||
|
|
||||||
|
#include "Pane.h"
|
||||||
|
|
||||||
|
// used by Picture and Window
|
||||||
|
class QuadPane : public Pane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Pane Base;
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
GXColor vertex_colors[4];
|
||||||
|
u16 material_index;
|
||||||
|
u8 tex_coord_count;
|
||||||
|
u8 pad;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
QuadPane() : header(NULL) {}
|
||||||
|
void Load(QuadPane::Header *file);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ProcessHermiteKey(const KeyType& type, float value);
|
||||||
|
//! overload
|
||||||
|
void Draw(const BannerResources& resources, u8 render_alpha, const float ws_scale, Mtx &view,
|
||||||
|
u16 material_index, u8 texture_flip) const;
|
||||||
|
//! main virtual draw function
|
||||||
|
void Draw(const BannerResources& resources, u8 render_alpha, const float ws_scale, Mtx &view) const {
|
||||||
|
Draw(resources, render_alpha, ws_scale, view, header->material_index, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetVertex(int ind, float x, float y, u8 render_alpha) const;
|
||||||
|
|
||||||
|
struct TexCoords
|
||||||
|
{
|
||||||
|
struct TexCoord
|
||||||
|
{
|
||||||
|
float s;
|
||||||
|
float t;
|
||||||
|
|
||||||
|
} coords[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
QuadPane::Header *header;
|
||||||
|
const TexCoords *tex_coords;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
280
source/banner/Textbox.cpp
Normal file
280
source/banner/Textbox.cpp
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010 - Wii Banner Player Project
|
||||||
|
Copyright (c) 2012 - giantpune
|
||||||
|
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 "Textbox.h"
|
||||||
|
#include "Layout.h"
|
||||||
|
|
||||||
|
void Textbox::Load(Pane::Header *file)
|
||||||
|
{
|
||||||
|
if(!file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Pane::Load(file);
|
||||||
|
header = (Textbox::Header *) (file + 1);
|
||||||
|
text = (const u16 *) (header + 1);
|
||||||
|
|
||||||
|
textAlignVer = (header->text_alignment / 3);
|
||||||
|
textAlignHor = (header->text_alignment % 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Textbox::SetTextWidth(WiiFont *font)
|
||||||
|
{
|
||||||
|
lineWidths.clear();
|
||||||
|
frameWidth = 0.f;
|
||||||
|
frameHeight = header->font_size;
|
||||||
|
float currentLine = 0.f;
|
||||||
|
float scale = header->font_size /(float)font->CharacterHeight();
|
||||||
|
|
||||||
|
for(const u16 *txtString = text; *txtString != 0; txtString++)
|
||||||
|
{
|
||||||
|
if(*txtString == '\n')
|
||||||
|
{
|
||||||
|
currentLine *= scale;
|
||||||
|
lineWidths.push_back(currentLine);
|
||||||
|
frameWidth = MAX(frameWidth, currentLine);
|
||||||
|
frameHeight += header->font_size + header->space_line;
|
||||||
|
currentLine = 0.f;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WiiFont::CharInfo *charInfo = font->GetCharInfo(*txtString);
|
||||||
|
if(!charInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(charInfo->unk)
|
||||||
|
currentLine += (float) charInfo->advanceKerning;
|
||||||
|
|
||||||
|
currentLine += (float) charInfo->advanceGlyphX;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLine *= scale;
|
||||||
|
lineWidths.push_back(currentLine);
|
||||||
|
frameWidth = MAX(frameWidth, currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Textbox::SetupGX(const BannerResources& resources) const
|
||||||
|
{
|
||||||
|
GX_ClearVtxDesc();
|
||||||
|
GX_InvVtxCache();
|
||||||
|
|
||||||
|
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||||
|
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
||||||
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||||
|
|
||||||
|
// channel control
|
||||||
|
GX_SetNumChans(1);
|
||||||
|
GX_SetChanCtrl(GX_COLOR0A0,GX_DISABLE,GX_SRC_REG,GX_SRC_VTX,GX_LIGHTNULL,GX_DF_NONE,GX_AF_NONE);
|
||||||
|
|
||||||
|
// texture gen.
|
||||||
|
GX_SetNumTexGens(1);
|
||||||
|
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||||
|
// texture environment
|
||||||
|
GX_SetNumTevStages(1);
|
||||||
|
GX_SetNumIndStages(0);
|
||||||
|
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
|
||||||
|
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
||||||
|
GX_SetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
||||||
|
GX_SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_1_4);
|
||||||
|
GX_SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_1);
|
||||||
|
GX_SetTevDirect(GX_TEVSTAGE0);
|
||||||
|
// swap table
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
|
||||||
|
GX_SetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
|
||||||
|
// alpha compare and blend mode
|
||||||
|
GX_SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
||||||
|
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
|
||||||
|
|
||||||
|
if(header->material_index < resources.materials.size())
|
||||||
|
{
|
||||||
|
const Material::Header *matHead = resources.materials[header->material_index]->GetHeader();
|
||||||
|
if(!matHead)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//GX_SetFog(0, 0.0f, 0.0f, 0.0f, 0.0f, (GXColor){0xff, 0xff, 0xff, 0xff});
|
||||||
|
GX_SetTevSwapModeTable(0, 0, 1, 2, 3);
|
||||||
|
//GX_SetZTexture(0, 0x11, 0);
|
||||||
|
GX_SetNumChans(1 );
|
||||||
|
GX_SetChanCtrl(4, 0, 0, 1, 0, 0, 2);
|
||||||
|
GX_SetChanCtrl(5, 0, 0, 0, 0, 0, 2);
|
||||||
|
GX_SetNumTexGens(1);
|
||||||
|
GX_SetTexCoordGen2(0, 1, 4, 0x3c, 0, 0x7D);
|
||||||
|
GX_SetNumIndStages(0);
|
||||||
|
GX_SetBlendMode(1, 4, 5, 0xf);
|
||||||
|
GX_SetNumTevStages(2);
|
||||||
|
GX_SetTevDirect(0);
|
||||||
|
GX_SetTevDirect(1);
|
||||||
|
GX_SetTevSwapMode(0, 0, 0);
|
||||||
|
GX_SetTevSwapMode(1, 0, 0);
|
||||||
|
GX_SetTevOrder(0, 0, 0, 0xff);
|
||||||
|
|
||||||
|
for( int i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
GX_SetTevColor(i + 1, (GXColor){ LIMIT(matHead->color_regs[i].r, 0, 0xFF),
|
||||||
|
LIMIT(matHead->color_regs[i].g, 0, 0xFF),
|
||||||
|
LIMIT(matHead->color_regs[i].b, 0, 0xFF),
|
||||||
|
LIMIT(matHead->color_regs[i].a, 0, 0xFF) });
|
||||||
|
}
|
||||||
|
|
||||||
|
GX_SetTevColorIn(0, 2, 4, 8, 0xf);
|
||||||
|
GX_SetTevAlphaIn(0, 1, 2, 4, 7);
|
||||||
|
GX_SetTevColorOp(0, 0, 0, 0, 1, 0);
|
||||||
|
GX_SetTevAlphaOp(0, 0, 0, 0, 1, 0);
|
||||||
|
GX_SetTevOrder(1, 0xff, 0xff, 4);
|
||||||
|
GX_SetTevColorIn(1, 0xf, 0, 0xa, 0xf);
|
||||||
|
GX_SetTevAlphaIn(1, 7, 0, 5, 7);
|
||||||
|
GX_SetTevColorOp(1, 0, 0, 0, 1, 0);
|
||||||
|
GX_SetTevAlphaOp(1, 0, 0, 0, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Textbox::Draw(const BannerResources& resources, u8 parent_alpha, const float ws_scale, Mtx &modelview) const
|
||||||
|
{
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(header->font_index >= resources.fonts.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
WiiFont *font = resources.fonts[header->font_index];
|
||||||
|
if(!font->IsLoaded())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ugly...but doing it by going through all panes is more ugly
|
||||||
|
// TODO: move it to somewhere else
|
||||||
|
if(lineWidths.empty())
|
||||||
|
((Textbox *) this)->SetTextWidth(font);
|
||||||
|
|
||||||
|
if(lineWidths.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetupGX(resources);
|
||||||
|
|
||||||
|
GX_LoadPosMtxImm(modelview, GX_PNMTX0);
|
||||||
|
|
||||||
|
// Setup text color
|
||||||
|
GXColor color0 = { header->color[0].r,
|
||||||
|
header->color[0].g,
|
||||||
|
header->color[0].b,
|
||||||
|
MultiplyAlpha(header->color[0].a, parent_alpha) };
|
||||||
|
|
||||||
|
GXColor color1 = { header->color[1].r,
|
||||||
|
header->color[1].g,
|
||||||
|
header->color[1].b,
|
||||||
|
MultiplyAlpha(header->color[1].a, parent_alpha) };
|
||||||
|
|
||||||
|
u32 lastSheetIdx = 0xffff;
|
||||||
|
float scale = header->font_size /(float)font->CharacterHeight();
|
||||||
|
|
||||||
|
// use complete text width if not aligned to middle
|
||||||
|
float textWidth = (GetAlignHor() == 1) ? lineWidths[0] : frameWidth;
|
||||||
|
|
||||||
|
// position offset calculation for first line...why the hell is it that complex?
|
||||||
|
float xPos = -0.5f * ( GetOriginX() * GetWidth() * ws_scale +
|
||||||
|
GetAlignHor() * (-GetWidth() * ws_scale + textWidth) );
|
||||||
|
float yPos = -0.5f * ( GetAlignVer() * -frameHeight +
|
||||||
|
GetHeight() * (GetAlignVer() - (2 - GetOriginY())) )
|
||||||
|
- header->font_size;
|
||||||
|
|
||||||
|
// store the character width here for later use, it's constant over the text
|
||||||
|
float charWidth = scale * (float)font->CharacterWidth();
|
||||||
|
int lineNumber = 0;
|
||||||
|
|
||||||
|
for(const u16 *txtString = text; *txtString != 0; txtString++)
|
||||||
|
{
|
||||||
|
if(*txtString == '\n')
|
||||||
|
{
|
||||||
|
lineNumber++;
|
||||||
|
// use complete text width if not aligned to middle
|
||||||
|
textWidth = (GetAlignHor() == 1) ? lineWidths[lineNumber] : frameWidth;
|
||||||
|
// calculate text position depending on line width
|
||||||
|
xPos = -0.5f * (GetOriginX() * GetWidth() * ws_scale +
|
||||||
|
GetAlignHor() * (-GetWidth() * ws_scale + textWidth));
|
||||||
|
// go one line down
|
||||||
|
yPos -= (header->font_size + header->space_line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WiiFont::CharInfo *charInfo = font->GetCharInfo(*txtString);
|
||||||
|
if(!charInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(charInfo->sheetIdx != lastSheetIdx)
|
||||||
|
{
|
||||||
|
lastSheetIdx = charInfo->sheetIdx;
|
||||||
|
|
||||||
|
if(!font->Apply(charInfo->sheetIdx))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(charInfo->unk)
|
||||||
|
xPos += scale * (float)charInfo->advanceKerning;
|
||||||
|
|
||||||
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||||
|
|
||||||
|
GX_Position3f32(xPos, yPos, 0.f);
|
||||||
|
GX_Color4u8(color1.r, color1.g, color1.b, color1.a);
|
||||||
|
GX_TexCoord2f32(charInfo->s1, charInfo->t2);
|
||||||
|
|
||||||
|
GX_Position3f32(xPos + charWidth, yPos, 0.f);
|
||||||
|
GX_Color4u8(color1.r, color1.g, color1.b, color1.a);
|
||||||
|
GX_TexCoord2f32(charInfo->s2, charInfo->t2);
|
||||||
|
|
||||||
|
GX_Position3f32(xPos + charWidth, yPos + header->font_size, 0.f);
|
||||||
|
GX_Color4u8(color0.r, color0.g, color0.b, color0.a);
|
||||||
|
GX_TexCoord2f32(charInfo->s2, charInfo->t1);
|
||||||
|
|
||||||
|
GX_Position3f32(xPos, yPos + header->font_size, 0.f);
|
||||||
|
GX_Color4u8(color0.r, color0.g, color0.b, color0.a);
|
||||||
|
GX_TexCoord2f32(charInfo->s1, charInfo->t1);
|
||||||
|
|
||||||
|
GX_End();
|
||||||
|
|
||||||
|
xPos += scale * (float)charInfo->advanceGlyphX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Textbox::ProcessHermiteKey(const KeyType& type, float value)
|
||||||
|
{
|
||||||
|
if (type.type == ANIMATION_TYPE_VERTEX_COLOR) // vertex color
|
||||||
|
{
|
||||||
|
if(type.target < 4)
|
||||||
|
{
|
||||||
|
(&header->color[0].r)[type.target] = FLOAT_2_U8(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(type.target >= 8 && type.target < 12)
|
||||||
|
{
|
||||||
|
(&header->color[1].r)[type.target - 8] = FLOAT_2_U8(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Base::ProcessHermiteKey(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Textbox::ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data)
|
||||||
|
{
|
||||||
|
Base::ProcessStepKey(type, data);
|
||||||
|
}
|
85
source/banner/Textbox.h
Normal file
85
source/banner/Textbox.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010 - Wii Banner Player Project
|
||||||
|
Copyright (c) 2012 - giantpune
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WII_BNR_TEXTBOX_H_
|
||||||
|
#define WII_BNR_TEXTBOX_H_
|
||||||
|
|
||||||
|
#include "Pane.h"
|
||||||
|
|
||||||
|
class WiiFont;
|
||||||
|
|
||||||
|
class Textbox : public Pane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Pane Base;
|
||||||
|
|
||||||
|
Textbox() : header(NULL), text(NULL), frameWidth(0.f), frameHeight(0.f)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('t', 'x', 't', '1');
|
||||||
|
|
||||||
|
void Load(Pane::Header *file);
|
||||||
|
|
||||||
|
u8 GetAlignHor() const { return textAlignHor; }
|
||||||
|
u8 GetAlignVer() const { return textAlignVer; }
|
||||||
|
|
||||||
|
void SetText(const u16 *t) { text = t; lineWidths.clear(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ProcessHermiteKey(const KeyType& type, float value);
|
||||||
|
void ProcessStepKey(const KeyType& type, StepKeyHandler::KeyData data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Draw(const BannerResources& resources, u8 render_alpha, const float ws_scale, Mtx &view) const;
|
||||||
|
void SetupGX(const BannerResources& resources) const;
|
||||||
|
void SetTextWidth(WiiFont *font);
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
u16 text_buf_bytes;
|
||||||
|
u16 text_str_bytes;
|
||||||
|
u16 material_index;
|
||||||
|
u16 font_index;
|
||||||
|
u8 text_alignment;
|
||||||
|
u8 pad1; // ?
|
||||||
|
u8 pad2[2];
|
||||||
|
u32 text_str_offset;
|
||||||
|
GXColor color[2];
|
||||||
|
float font_size;
|
||||||
|
float height; // seems to work better for offset calculation
|
||||||
|
float space_char;
|
||||||
|
float space_line;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
Textbox::Header *header;
|
||||||
|
const u16 *text;
|
||||||
|
float frameWidth;
|
||||||
|
float frameHeight;
|
||||||
|
u8 textAlignVer;
|
||||||
|
u8 textAlignHor;
|
||||||
|
std::vector<float> lineWidths;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
387
source/banner/WiiFont.cpp
Normal file
387
source/banner/WiiFont.cpp
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2012 - giantpune
|
||||||
|
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 "WiiFont.h"
|
||||||
|
|
||||||
|
WiiFont::WiiFont()
|
||||||
|
: header(NULL)
|
||||||
|
, finf(NULL)
|
||||||
|
, tglp(NULL)
|
||||||
|
, cwdh(NULL)
|
||||||
|
, font_loaded(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WiiFont::~WiiFont()
|
||||||
|
{
|
||||||
|
std::map<u16, TextureCache>::iterator itr;
|
||||||
|
|
||||||
|
for (itr = textureMap.begin(); itr != textureMap.end(); itr++)
|
||||||
|
{
|
||||||
|
if(itr->second.allocated && itr->second.texture_data)
|
||||||
|
free(itr->second.texture_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiiFont::Load(const u8 *file)
|
||||||
|
{
|
||||||
|
if(!file)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
header = (WiiFont::Header *) file;
|
||||||
|
|
||||||
|
if((header->magic != MAGIC_FONT && header->magic != MAGIC_FONT_ARCHIVE)
|
||||||
|
|| header->version != MAGIC_VERSION)
|
||||||
|
{
|
||||||
|
header = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 *position = ((const u8 *)header) + header->header_len;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < header->section_count; ++i)
|
||||||
|
{
|
||||||
|
section_t *section = (section_t *) position;
|
||||||
|
position += section->size;
|
||||||
|
|
||||||
|
switch( section->magic )
|
||||||
|
{
|
||||||
|
case MAGIC_GLYPH_GROUP:
|
||||||
|
glgr = (GlgrHeader *) section;
|
||||||
|
break;
|
||||||
|
case MAGIC_FONT_INFORMATION:
|
||||||
|
finf = (FinfHeader *) section;
|
||||||
|
break;
|
||||||
|
case MAGIC_TEXTURE_GLYPH:
|
||||||
|
tglp = (TglpHeader *) section;
|
||||||
|
break;
|
||||||
|
case MAGIC_CHARACTER_WIDTH:
|
||||||
|
cwdh = (CwdhHeader *) section;
|
||||||
|
break;
|
||||||
|
case MAGIC_CHARACTER_CODE_MAP:
|
||||||
|
ParseCmap((CmapEntry *) (section + 1));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// ignore
|
||||||
|
gprintf("Uknown section %.4s\n", (char *) §ion->magic);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some sanity checks
|
||||||
|
if(!finf || !tglp || !cwdh)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(finf->tglpOffset > header->filesize || finf->cwdhOffset > header->filesize
|
||||||
|
|| finf->cmapOffset > header->filesize)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
font_loaded = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool WiiFont::CheckCmap(u16 charCode, u16 mapValue)
|
||||||
|
{
|
||||||
|
std::map<u16, u16>::iterator it = cmap.find(charCode);
|
||||||
|
if(it != cmap.end())
|
||||||
|
{
|
||||||
|
if((*it).second != mapValue)
|
||||||
|
{
|
||||||
|
gprintf("Duplicate characters\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiiFont::ParseCmap(CmapEntry *cmapEntry)
|
||||||
|
{
|
||||||
|
if(!cmapEntry)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
switch(cmapEntry->type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
for(u16 i = cmapEntry->charCode, j = cmapEntry->start; j < cmapEntry->end; j++, i++)
|
||||||
|
{
|
||||||
|
if(!CheckCmap(j, i))
|
||||||
|
return false;
|
||||||
|
cmap[j] = i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
u16 idx = 0;
|
||||||
|
u16 *idxPointer = &cmapEntry->charCode;
|
||||||
|
for(u32 i = cmapEntry->start; i < cmapEntry->end; i++)
|
||||||
|
{
|
||||||
|
u16 m_idx = idxPointer[idx++];
|
||||||
|
if(m_idx == 0xffff)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!CheckCmap(i, m_idx))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cmap[i] = m_idx;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
u16 ind, character;
|
||||||
|
u16 *charData = (u16 *) (cmapEntry + 1);
|
||||||
|
for(u32 i = 0; i < cmapEntry->charCode; i++)
|
||||||
|
{
|
||||||
|
character = charData[0];
|
||||||
|
ind = charData[1];
|
||||||
|
charData += 2;
|
||||||
|
|
||||||
|
if(!CheckCmap(character, ind))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cmap[character] = ind;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
gprintf( "unknown cmap type\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cmapEntry->pos == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
cmapEntry = (CmapEntry *)(((u8 *)header) + cmapEntry->pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const WiiFont::CharInfo *WiiFont::GetCharInfo(u16 charCode)
|
||||||
|
{
|
||||||
|
if(!finf || !tglp || !cwdh)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// see if the character already exists in our cache
|
||||||
|
std::map<u16, CharInfo>::iterator itr = charInfoMap.find(charCode);
|
||||||
|
if(itr != charInfoMap.end())
|
||||||
|
return &itr->second;
|
||||||
|
|
||||||
|
u16 idx = CharToIdx(charCode);
|
||||||
|
if(idx > cwdh->endIdx)
|
||||||
|
{
|
||||||
|
gprintf( "idx > cwdh->endIdx" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cwdh *cwdh2 = (Cwdh*) (((u8 *)header) + finf->cwdhOffset + 8);
|
||||||
|
|
||||||
|
u32 chars_per_texture = (tglp->charColumns * tglp->charRows);
|
||||||
|
u32 tex_idx = idx / chars_per_texture;
|
||||||
|
u32 row = (idx - chars_per_texture * tex_idx) / tglp->charColumns;
|
||||||
|
u32 col = (idx - chars_per_texture * tex_idx) - ( tglp->charColumns * row );
|
||||||
|
|
||||||
|
f32 _s1 = ((tglp->cellWidth + 1) * col) / (f32)tglp->width;
|
||||||
|
f32 _s2 = _s1 + CharacterWidth() / (f32)tglp->width;
|
||||||
|
|
||||||
|
// this is good vertically but horizontal without it it looks clearer
|
||||||
|
f32 _t1 = ((tglp->cellHeight + 1) * row + 0.5f * (CharacterHeight() - (tglp->cellHeight + 1))) / (f32)tglp->height;
|
||||||
|
f32 _t2 = _t1 + CharacterHeight() / (f32)tglp->height;
|
||||||
|
|
||||||
|
CharInfo charInfo;
|
||||||
|
charInfo.sheetIdx = tex_idx;
|
||||||
|
charInfo.s1 = _s1;
|
||||||
|
charInfo.s2 = _s2;
|
||||||
|
charInfo.t1 = _t1;
|
||||||
|
charInfo.t2 = _t2;
|
||||||
|
charInfo.advanceGlyphX = cwdh2[idx].advanceGlyphX;
|
||||||
|
charInfo.unk = cwdh2[idx].unk;
|
||||||
|
charInfo.advanceKerning = cwdh2[idx].advanceKerning;
|
||||||
|
|
||||||
|
charInfoMap[charCode] = charInfo;
|
||||||
|
return &charInfoMap[charCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
GXTexObj *WiiFont::LoadTextureObj(u16 tex_idx)
|
||||||
|
{
|
||||||
|
if(!font_loaded || tex_idx >= tglp->texCnt)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// init texture and add it to the list
|
||||||
|
TextureCache chacheStruct;
|
||||||
|
|
||||||
|
if(header->magic == MAGIC_FONT_ARCHIVE)
|
||||||
|
{
|
||||||
|
chacheStruct.texture_data = GetUnpackedTexture(tex_idx);
|
||||||
|
chacheStruct.allocated = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chacheStruct.texture_data = ((u8 *) header) + tglp->dataOffset + tex_idx * tglp->texSize;
|
||||||
|
chacheStruct.allocated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!chacheStruct.texture_data)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
GX_InitTexObj( &chacheStruct.texObj, chacheStruct.texture_data, tglp->width, tglp->height, 0, 0, 0, true );
|
||||||
|
GX_InitTexObjLOD( &chacheStruct.texObj, GX_LINEAR,GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_DISABLE, GX_FALSE, GX_ANISO_1 );
|
||||||
|
|
||||||
|
textureMap[tex_idx] = chacheStruct;
|
||||||
|
return &textureMap[tex_idx].texObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiiFont::Apply(u16 tex_indx)
|
||||||
|
{
|
||||||
|
if(!font_loaded)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(tex_indx >= tglp->texCnt)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GXTexObj *tex_obj;
|
||||||
|
|
||||||
|
// Load character texture from cache if available otherwise create cache
|
||||||
|
std::map<u16, TextureCache>::iterator itr = textureMap.find(tex_indx);
|
||||||
|
if(itr != textureMap.end())
|
||||||
|
tex_obj = &itr->second.texObj;
|
||||||
|
else
|
||||||
|
tex_obj = LoadTextureObj(tex_indx);
|
||||||
|
|
||||||
|
// no texture for this character found
|
||||||
|
if(!tex_obj)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GX_LoadTexObj(tex_obj, GX_TEXMAP0);
|
||||||
|
GX_InvalidateTexAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// giantpunes little magic function
|
||||||
|
bool WiiFont::Decompress_0x28( unsigned char *outBuf, u32 outLen, const unsigned char *inBuf, u32 inLen )
|
||||||
|
{
|
||||||
|
if( outLen & 3 )// this copies 32 bits at a time, so it probably needs to be aligned
|
||||||
|
{
|
||||||
|
gprintf( "length not aligned to 32 bits\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const u32 root_offset = 5;
|
||||||
|
u32 symbol = 0;
|
||||||
|
u32 counter = 0;
|
||||||
|
u32 inIdx = 0;
|
||||||
|
u32 outIdx = 0;
|
||||||
|
u32 *in32 = (u32*)( ( inBuf + 6 ) + ( ( inBuf[ 4 ] << 1 ) ) );
|
||||||
|
u32 *out32 = (u32*)outBuf;
|
||||||
|
u8 *p = (u8*)inBuf + root_offset;
|
||||||
|
|
||||||
|
outLen >>= 2; //we are copying 4 bytes at a time
|
||||||
|
while( outLen )
|
||||||
|
{
|
||||||
|
for( u32 i = 0, leaf = p[ 0 ], bits = __builtin_bswap32( in32[ inIdx ] )
|
||||||
|
; i < 0x20 && outLen
|
||||||
|
; i++, leaf = p[ 0 ], bits <<= 1 )
|
||||||
|
{
|
||||||
|
u32 topBit = bits >> 31;
|
||||||
|
u8 d = 2 - ((u64)p & 1);
|
||||||
|
p += topBit + ( ( leaf << 1 ) & 0x7e ) + d;
|
||||||
|
|
||||||
|
if( !( p > (u8*)inBuf ) && ( p < (u8*)inBuf + inLen ) )
|
||||||
|
{
|
||||||
|
gprintf( "out of range 1\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( ( leaf << ( topBit ) ) & ( 1 << 7 ) ) ) // p->isLeaf
|
||||||
|
{
|
||||||
|
symbol = ( ( p[ 0 ] << 0x18 ) | ( symbol >> 8 ) );
|
||||||
|
p = (u8*)inBuf + root_offset; // p = root
|
||||||
|
if( counter++ > 2 )
|
||||||
|
{
|
||||||
|
out32[ outIdx++ ] = __builtin_bswap32( symbol );// buf[bufcur++] = p->symbol
|
||||||
|
counter = 0; // reset counter
|
||||||
|
outLen--; // decrease amount to copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( inIdx++ >= ( inLen >> 2 ) )
|
||||||
|
{
|
||||||
|
gprintf( "out of range 2\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *WiiFont::GetUnpackedTexture(u16 sheetNo)
|
||||||
|
{
|
||||||
|
u8 *data = (u8 *) header;
|
||||||
|
u32 compressedSize;
|
||||||
|
u32 off = 0;
|
||||||
|
|
||||||
|
// skip over all the sheets till we get the one we want
|
||||||
|
for( u32 i = 0; i < sheetNo; i++ )
|
||||||
|
{
|
||||||
|
compressedSize = *(u32*)( data + tglp->dataOffset + off );
|
||||||
|
off += compressedSize + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
compressedSize = *(u32*)( data + tglp->dataOffset + off );
|
||||||
|
|
||||||
|
u32 uncompressedSize = *(u32*)( data + tglp->dataOffset + off + 4 );
|
||||||
|
if( (uncompressedSize & 0xff000000) != 0x28000000 )// looks like all the sheets in wbf1 and wbf2.brfna are 0x28
|
||||||
|
{
|
||||||
|
gprintf( "Brfna::LoadSheets(): unknown data type\n" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
uncompressedSize = ( __builtin_bswap32( uncompressedSize ) >> 8 );
|
||||||
|
if( !uncompressedSize )// is this right? it looks like it is. but it SHOULD only happen for files over 0xffffff bytes
|
||||||
|
{
|
||||||
|
uncompressedSize = __builtin_bswap32(*(u32*)( data + tglp->dataOffset + off + 8 ));
|
||||||
|
}
|
||||||
|
if( uncompressedSize != glgr->sheet_size )
|
||||||
|
{
|
||||||
|
gprintf( "uncompressedSize != glgr->sheet_size %08x\n", uncompressedSize );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decompress
|
||||||
|
u8* sheetData = (u8*)memalign( 32, uncompressedSize );// buffer needs to be 32bit aligned
|
||||||
|
if( !sheetData )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if( !Decompress_0x28( sheetData, uncompressedSize, ( data + tglp->dataOffset + off + 4 ), compressedSize ) )
|
||||||
|
{
|
||||||
|
free( sheetData );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush cache
|
||||||
|
DCFlushRange(sheetData, uncompressedSize);
|
||||||
|
|
||||||
|
return sheetData;
|
||||||
|
}
|
226
source/banner/WiiFont.h
Normal file
226
source/banner/WiiFont.h
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2012 - giantpune
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WII_FONT_H_
|
||||||
|
#define __WII_FONT_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Pane.h"
|
||||||
|
|
||||||
|
class WiiFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const u32 MAGIC_FONT = MAKE_FOURCC('R', 'F', 'N', 'T');
|
||||||
|
static const u32 MAGIC_FONT_ARCHIVE = MAKE_FOURCC('R', 'F', 'N', 'A');
|
||||||
|
static const u32 MAGIC_VERSION = 0xFEFF0104;
|
||||||
|
static const u32 MAGIC_GLYPH_GROUP = MAKE_FOURCC('G', 'L', 'G', 'R');
|
||||||
|
static const u32 MAGIC_FONT_INFORMATION = MAKE_FOURCC('F', 'I', 'N', 'F');
|
||||||
|
static const u32 MAGIC_TEXTURE_GLYPH = MAKE_FOURCC('T', 'G', 'L', 'P');
|
||||||
|
static const u32 MAGIC_CHARACTER_CODE_MAP = MAKE_FOURCC('C', 'M', 'A', 'P');
|
||||||
|
static const u32 MAGIC_CHARACTER_WIDTH = MAKE_FOURCC('C', 'W', 'D', 'H');
|
||||||
|
|
||||||
|
WiiFont();
|
||||||
|
~WiiFont();
|
||||||
|
|
||||||
|
// load the file
|
||||||
|
bool Load(const u8 *file);
|
||||||
|
|
||||||
|
// apply texture, non-const because we load texture on demand
|
||||||
|
bool Apply(u16 tex_idx);
|
||||||
|
|
||||||
|
// struct to hold info for a character to keep from searching and calculating it all every frame
|
||||||
|
struct CharInfo
|
||||||
|
{
|
||||||
|
u32 sheetIdx;
|
||||||
|
f32 s1;
|
||||||
|
f32 t1;
|
||||||
|
f32 s2;
|
||||||
|
f32 t2;
|
||||||
|
s8 advanceKerning;
|
||||||
|
u8 unk;
|
||||||
|
s8 advanceGlyphX;
|
||||||
|
};
|
||||||
|
|
||||||
|
// get the character information
|
||||||
|
const CharInfo *GetCharInfo(u16 charCode);
|
||||||
|
|
||||||
|
// check if the font was loaded correctly
|
||||||
|
bool IsLoaded() const { return font_loaded; }
|
||||||
|
|
||||||
|
// get some parameters from the FINF header
|
||||||
|
u8 CharacterWidth() const { return finf ? finf->charWidth : 0; }
|
||||||
|
u8 CharacterHeight() const { return finf ? finf->height : 0; }
|
||||||
|
|
||||||
|
const std::string& getName() const { return name; }
|
||||||
|
void SetName(const std::string& _name) { name = _name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 version;
|
||||||
|
u32 filesize;
|
||||||
|
u16 header_len;
|
||||||
|
u16 section_count;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct GlgrHeader
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 sectionSize;
|
||||||
|
u32 sheet_size;
|
||||||
|
u16 glyphs_per_sheet;
|
||||||
|
u16 set_count;
|
||||||
|
u16 sheet_count;
|
||||||
|
u16 cwdh_count;
|
||||||
|
u16 cmap_count;
|
||||||
|
}__attribute__(( packed ));
|
||||||
|
|
||||||
|
struct FinfHeader
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 headerSize; // finf size
|
||||||
|
u8 unk8_1; // font type?
|
||||||
|
u8 leading; //
|
||||||
|
u16 defaultChar;
|
||||||
|
u8 leftMargin;
|
||||||
|
u8 charWidth;
|
||||||
|
u8 fullWidth;
|
||||||
|
u8 encoding;
|
||||||
|
u32 tglpOffset; // TLGP offset
|
||||||
|
u32 cwdhOffset; // CWDH offset
|
||||||
|
u32 cmapOffset; // CMAP offset
|
||||||
|
u8 height;
|
||||||
|
u8 width;
|
||||||
|
u8 ascent;
|
||||||
|
u8 unk8_10;
|
||||||
|
} __attribute__(( packed ));
|
||||||
|
|
||||||
|
struct TglpHeader
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 tglpSize; // TGLP size
|
||||||
|
|
||||||
|
u8 cellWidth; // font width - 1
|
||||||
|
u8 cellHeight; // font heigh - 1
|
||||||
|
u8 baselinePos;
|
||||||
|
u8 maxCharWidth;
|
||||||
|
|
||||||
|
u32 texSize; // length of 1 image
|
||||||
|
|
||||||
|
u16 texCnt; // number of images
|
||||||
|
u16 texType; //
|
||||||
|
u16 charColumns; // character per row
|
||||||
|
u16 charRows; // characters per column
|
||||||
|
u16 width; // width of image
|
||||||
|
u16 height; // height of image
|
||||||
|
u32 dataOffset; // data offset
|
||||||
|
} __attribute__(( packed ));
|
||||||
|
|
||||||
|
struct CwdhHeader
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 length; // section length?
|
||||||
|
u16 startIdx; //
|
||||||
|
u16 endIdx; //
|
||||||
|
u32 next; //
|
||||||
|
|
||||||
|
} __attribute__(( packed ));
|
||||||
|
|
||||||
|
struct CmapEntry
|
||||||
|
{
|
||||||
|
u16 start;
|
||||||
|
u16 end;
|
||||||
|
u16 type;
|
||||||
|
u16 pad;
|
||||||
|
u32 pos;
|
||||||
|
u16 charCode;
|
||||||
|
} __attribute__(( packed ));
|
||||||
|
|
||||||
|
struct Cwdh
|
||||||
|
{
|
||||||
|
s8 advanceKerning;
|
||||||
|
u8 unk;
|
||||||
|
s8 advanceGlyphX;
|
||||||
|
} __attribute__(( packed ));
|
||||||
|
|
||||||
|
// font texture decompress functions
|
||||||
|
static bool Decompress_0x28( unsigned char *outBuf, u32 outLen, const unsigned char *inBuf, u32 inLen );
|
||||||
|
u8 *GetUnpackedTexture(u16 sheetNo);
|
||||||
|
|
||||||
|
// load a GX texture from index
|
||||||
|
GXTexObj *LoadTextureObj(u16 texture_idx);
|
||||||
|
|
||||||
|
// cmap parser
|
||||||
|
bool ParseCmap(CmapEntry *cmapEntry);
|
||||||
|
|
||||||
|
// just a duplicate check
|
||||||
|
bool CheckCmap(u16 charCode, u16 mapValue);
|
||||||
|
|
||||||
|
// get index of a character
|
||||||
|
u16 CharToIdx(u16 charCode)
|
||||||
|
{
|
||||||
|
std::map<u16, u16>::iterator itr = cmap.find(charCode);
|
||||||
|
if(itr != cmap.end())
|
||||||
|
return itr->second;
|
||||||
|
|
||||||
|
return finf->defaultChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiiFont::Header *header;
|
||||||
|
|
||||||
|
// pointers to each sections
|
||||||
|
FinfHeader *finf;
|
||||||
|
TglpHeader *tglp;
|
||||||
|
CwdhHeader *cwdh;
|
||||||
|
GlgrHeader *glgr;
|
||||||
|
|
||||||
|
// struct to contain a decompressed texture caches
|
||||||
|
struct TextureCache
|
||||||
|
{
|
||||||
|
u8* texture_data;
|
||||||
|
bool allocated;
|
||||||
|
GXTexObj texObj;
|
||||||
|
};
|
||||||
|
std::map<u16, TextureCache> textureMap;
|
||||||
|
|
||||||
|
// character info cache map
|
||||||
|
std::map<u16, CharInfo> charInfoMap;
|
||||||
|
|
||||||
|
// holds all the character codes and their index within the font
|
||||||
|
std::map<u16, u16> cmap;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
bool font_loaded;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FontList : public std::vector<WiiFont *>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('f', 'n', 'l', '1');
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
51
source/banner/Window.cpp
Normal file
51
source/banner/Window.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
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 "Window.h"
|
||||||
|
|
||||||
|
void Window::Load(Pane::Header *file)
|
||||||
|
{
|
||||||
|
if(!file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const u8 *section_start = (const u8 *)file;
|
||||||
|
|
||||||
|
Pane::Load(file);
|
||||||
|
header = (Window::Header *) (file+1);
|
||||||
|
|
||||||
|
// read content
|
||||||
|
QuadPane::Load((QuadPane::Header *)(section_start + header->content_offset));
|
||||||
|
|
||||||
|
// read frames
|
||||||
|
const u32 *frame_offsets = (const u32 *) (section_start + header->frame_table_offset);
|
||||||
|
for(u32 i = 0; i < header->frame_count; i++)
|
||||||
|
frames.push_back((Frame *) (section_start + frame_offsets[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::Draw(const BannerResources& resources, u8 render_alpha, const float ws_scale, Mtx &view) const
|
||||||
|
{
|
||||||
|
// TODO: handle "inflation"
|
||||||
|
// TODO: handle "frames" and "texture_flip"
|
||||||
|
|
||||||
|
QuadPane::Draw(resources, render_alpha, ws_scale, view);
|
||||||
|
}
|
65
source/banner/Window.h
Normal file
65
source/banner/Window.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#ifndef WII_BNR_WINDOW_H_
|
||||||
|
#define WII_BNR_WINDOW_H_
|
||||||
|
|
||||||
|
#include "QuadPane.h"
|
||||||
|
|
||||||
|
class Window : public QuadPane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef QuadPane Base;
|
||||||
|
|
||||||
|
static const u32 MAGIC = MAKE_FOURCC('w', 'n', 'd', '1');
|
||||||
|
|
||||||
|
void Load(Pane::Header *file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Draw(const BannerResources& resources, u8 render_alpha, const float ws_scale, Mtx &view) const;
|
||||||
|
|
||||||
|
struct inflation
|
||||||
|
{
|
||||||
|
float l, r, t, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
inflation infl;
|
||||||
|
u8 frame_count;
|
||||||
|
u8 pad[3];
|
||||||
|
u32 content_offset;
|
||||||
|
u32 frame_table_offset;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct Frame
|
||||||
|
{
|
||||||
|
u16 material_index;
|
||||||
|
u8 texture_flip;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
Header *header;
|
||||||
|
std::vector<Frame *> frames;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
455
source/banner/ash.cpp
Normal file
455
source/banner/ash.cpp
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2012 giantpune
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "ash.h"
|
||||||
|
#include "gecko.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
//#include <memory.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool IsAshCompressed( const u8 *stuff, u32 len )
|
||||||
|
{
|
||||||
|
return ( len > 0x10 &&
|
||||||
|
((*(u32*)( stuff )) & 0xFFFFFF00 ) == 0x41534800 );
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* DecompressAsh( const u8 *stuff, u32 &len )
|
||||||
|
{
|
||||||
|
if( !IsAshCompressed( stuff, len ) )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int r[32];
|
||||||
|
unsigned int count = 0;
|
||||||
|
unsigned int t;
|
||||||
|
|
||||||
|
r[4] = (u32)stuff; //in
|
||||||
|
|
||||||
|
r[5] = 0x415348;
|
||||||
|
r[6] = 0x415348;
|
||||||
|
|
||||||
|
r[5] = s32(*(unsigned int *)(r[4]+4));
|
||||||
|
r[5] = r[5] & 0x00FFFFFF;
|
||||||
|
|
||||||
|
u32 size = r[5];
|
||||||
|
//gprintf("Decompressed size: %d\n", size);
|
||||||
|
u8* buf1 = (u8*)memalign( 32, size );
|
||||||
|
if( !buf1 )
|
||||||
|
{
|
||||||
|
gprintf( "ASH: no memory\n" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
r[3] = (u32)buf1; //out
|
||||||
|
memset( (void*)buf1, 0, size );
|
||||||
|
//printf("r[3] :%08X\n", r[3]);
|
||||||
|
|
||||||
|
//printf("\n\n");
|
||||||
|
|
||||||
|
r[24] = 0x10;
|
||||||
|
r[28] = s32(*(unsigned int *)(r[4]+8));
|
||||||
|
r[25] = 0;
|
||||||
|
r[29] = 0;
|
||||||
|
r[26] = s32(*(unsigned int *)(r[4]+0xC));
|
||||||
|
r[30] = s32(*(unsigned int *)(r[4]+r[28]));
|
||||||
|
r[28] = r[28] + 4;
|
||||||
|
//r[8] = 0x8108<<16;
|
||||||
|
//HACK, pointer to RAM
|
||||||
|
u8* workingBuffer = (u8*)memalign( 32, 0x100000 );
|
||||||
|
if( !workingBuffer )
|
||||||
|
{
|
||||||
|
gprintf( "ASH: no memory 2\n" );
|
||||||
|
free( buf1 );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
r[8] = (u32)workingBuffer;
|
||||||
|
memset( (void*)workingBuffer, 0, 0x100000 );
|
||||||
|
//printf("r[8] :%08X\n", r[8]);
|
||||||
|
|
||||||
|
r[8] = r[8];
|
||||||
|
r[9] = r[8] + 0x07FE;
|
||||||
|
r[10] = r[9] + 0x07FE;
|
||||||
|
r[11] = r[10] + 0x1FFE;
|
||||||
|
r[31] = r[11] + 0x1FFE;
|
||||||
|
r[23] = 0x200;
|
||||||
|
r[22] = 0x200;
|
||||||
|
r[27] = 0;
|
||||||
|
|
||||||
|
loc_81332124:
|
||||||
|
|
||||||
|
if( r[25] != 0x1F )
|
||||||
|
goto loc_81332140;
|
||||||
|
|
||||||
|
r[0] = r[26] >> 31;
|
||||||
|
r[26]= s32(*(unsigned int *)(r[4] + r[24]));
|
||||||
|
r[25]= 0;
|
||||||
|
r[24]= r[24] + 4;
|
||||||
|
goto loc_8133214C;
|
||||||
|
|
||||||
|
loc_81332140:
|
||||||
|
|
||||||
|
r[0] = r[26] >> 31;
|
||||||
|
r[25]= r[25] + 1;
|
||||||
|
r[26]= r[26] << 1;
|
||||||
|
|
||||||
|
loc_8133214C:
|
||||||
|
|
||||||
|
if( r[0] == 0 )
|
||||||
|
goto loc_81332174;
|
||||||
|
|
||||||
|
r[0] = r[23] | 0x8000;
|
||||||
|
*(unsigned short *)(r[31]) = s16(r[0]);
|
||||||
|
r[0] = r[23] | 0x4000;
|
||||||
|
*(unsigned short *)(r[31]+2) = s16(r[0]);
|
||||||
|
|
||||||
|
r[31] = r[31] + 4;
|
||||||
|
r[27] = r[27] + 2;
|
||||||
|
r[23] = r[23] + 1;
|
||||||
|
r[22] = r[22] + 1;
|
||||||
|
|
||||||
|
goto loc_81332124;
|
||||||
|
|
||||||
|
loc_81332174:
|
||||||
|
|
||||||
|
r[12] = 9;
|
||||||
|
r[21] = r[25] + r[12];
|
||||||
|
t = r[21];
|
||||||
|
if( r[21] > 0x20 )
|
||||||
|
goto loc_813321AC;
|
||||||
|
|
||||||
|
r[21] = (~(r[12] - 0x20))+1;
|
||||||
|
r[6] = r[26] >> r[21];
|
||||||
|
if( t == 0x20 )
|
||||||
|
goto loc_8133219C;
|
||||||
|
|
||||||
|
r[26] = r[26] << r[12];
|
||||||
|
r[25] = r[25] + r[12];
|
||||||
|
goto loc_813321D0;
|
||||||
|
|
||||||
|
loc_8133219C:
|
||||||
|
|
||||||
|
r[26]= s32(*(unsigned int *)(r[4] + r[24]));
|
||||||
|
r[25]= 0;
|
||||||
|
r[24]= r[24] + 4;
|
||||||
|
goto loc_813321D0;
|
||||||
|
|
||||||
|
loc_813321AC:
|
||||||
|
|
||||||
|
r[0] = (~(r[12] - 0x20))+1;
|
||||||
|
r[6] = r[26] >> r[0];
|
||||||
|
r[26]= s32(*(unsigned int *)(r[4] + r[24]));
|
||||||
|
r[0] = (~(r[21] - 0x40))+1;
|
||||||
|
r[24]= r[24] + 4;
|
||||||
|
r[0] = r[26] >> r[0];
|
||||||
|
r[6] = r[6] | r[0];
|
||||||
|
r[25] = r[21] - 0x20;
|
||||||
|
r[26] = r[26] << r[25];
|
||||||
|
|
||||||
|
loc_813321D0:
|
||||||
|
|
||||||
|
r[12]= s16(*(unsigned short *)(r[31] - 2));
|
||||||
|
r[31] -= 2;
|
||||||
|
r[27]= r[27] - 1;
|
||||||
|
r[0] = r[12] & 0x8000;
|
||||||
|
r[12]= (r[12] & 0x1FFF) << 1;
|
||||||
|
if( r[0] == 0 )
|
||||||
|
goto loc_813321F8;
|
||||||
|
|
||||||
|
*(unsigned short *)(r[9]+r[12]) = s16(r[6]);
|
||||||
|
r[6] = (r[12] & 0x3FFF)>>1; // extrwi %r6, %r12, 14,17
|
||||||
|
if( r[27] != 0 )
|
||||||
|
goto loc_813321D0;
|
||||||
|
|
||||||
|
goto loc_81332204;
|
||||||
|
|
||||||
|
loc_813321F8:
|
||||||
|
|
||||||
|
*(unsigned short *)(r[8]+r[12]) = s16(r[6]);
|
||||||
|
r[23] = r[22];
|
||||||
|
goto loc_81332124;
|
||||||
|
|
||||||
|
loc_81332204:
|
||||||
|
|
||||||
|
r[23] = 0x800;
|
||||||
|
r[22] = 0x800;
|
||||||
|
|
||||||
|
loc_8133220C:
|
||||||
|
|
||||||
|
if( r[29] != 0x1F )
|
||||||
|
goto loc_81332228;
|
||||||
|
|
||||||
|
r[0] = r[30] >> 31;
|
||||||
|
r[30]= s32(*(unsigned int *)(r[4] + r[28]));
|
||||||
|
r[29]= 0;
|
||||||
|
r[28]= r[28] + 4;
|
||||||
|
goto loc_81332234;
|
||||||
|
|
||||||
|
loc_81332228:
|
||||||
|
|
||||||
|
r[0] = r[30] >> 31;
|
||||||
|
r[29]= r[29] + 1;
|
||||||
|
r[30]= r[30] << 1;
|
||||||
|
|
||||||
|
loc_81332234:
|
||||||
|
|
||||||
|
if( r[0] == 0 )
|
||||||
|
goto loc_8133225C;
|
||||||
|
|
||||||
|
r[0] = r[23] | 0x8000;
|
||||||
|
*(unsigned short *)(r[31]) = s16(r[0]);
|
||||||
|
r[0] = r[23] | 0x4000;
|
||||||
|
*(unsigned short *)(r[31]+2) = s16(r[0]);
|
||||||
|
|
||||||
|
r[31] = r[31] + 4;
|
||||||
|
r[27] = r[27] + 2;
|
||||||
|
r[23] = r[23] + 1;
|
||||||
|
r[22] = r[22] + 1;
|
||||||
|
|
||||||
|
goto loc_8133220C;
|
||||||
|
|
||||||
|
loc_8133225C:
|
||||||
|
|
||||||
|
r[12] = 0xB;
|
||||||
|
r[21] = r[29] + r[12];
|
||||||
|
t = r[21];
|
||||||
|
if( r[21] > 0x20 )
|
||||||
|
goto loc_81332294;
|
||||||
|
|
||||||
|
r[21] = (~(r[12] - 0x20))+1;
|
||||||
|
r[7] = r[30] >> r[21];
|
||||||
|
if( t == 0x20 )
|
||||||
|
goto loc_81332284;
|
||||||
|
|
||||||
|
r[30] = r[30] << r[12];
|
||||||
|
r[29] = r[29] + r[12];
|
||||||
|
goto loc_813322B8;
|
||||||
|
|
||||||
|
loc_81332284:
|
||||||
|
|
||||||
|
r[30]= s32(*(unsigned int *)(r[4] + r[28]));
|
||||||
|
r[29]= 0;
|
||||||
|
r[28]= r[28] + 4;
|
||||||
|
goto loc_813322B8;
|
||||||
|
|
||||||
|
loc_81332294:
|
||||||
|
|
||||||
|
r[0] = (~(r[12] - 0x20))+1;
|
||||||
|
r[7] = r[30] >> r[0];
|
||||||
|
r[30]= s32(*(unsigned int *)(r[4] + r[28]));
|
||||||
|
r[0] = (~(r[21] - 0x40))+1;
|
||||||
|
r[28]= r[28] + 4;
|
||||||
|
r[0] = r[30] >> r[0];
|
||||||
|
r[7] = r[7] | r[0];
|
||||||
|
r[29]= r[21] - 0x20;
|
||||||
|
r[30]= r[30] << r[29];
|
||||||
|
|
||||||
|
loc_813322B8:
|
||||||
|
|
||||||
|
r[12]= s16(*(unsigned short *)(r[31] - 2));
|
||||||
|
r[31] -= 2;
|
||||||
|
r[27]= r[27] - 1;
|
||||||
|
r[0] = r[12] & 0x8000;
|
||||||
|
r[12]= (r[12] & 0x1FFF) << 1;
|
||||||
|
if( r[0] == 0 )
|
||||||
|
goto loc_813322E0;
|
||||||
|
|
||||||
|
*(unsigned short *)(r[11]+r[12]) = s16(r[7]);
|
||||||
|
r[7] = (r[12] & 0x3FFF)>>1; // extrwi %r7, %r12, 14,17
|
||||||
|
if( r[27] != 0 )
|
||||||
|
goto loc_813322B8;
|
||||||
|
|
||||||
|
goto loc_813322EC;
|
||||||
|
|
||||||
|
loc_813322E0:
|
||||||
|
|
||||||
|
*(unsigned short *)(r[10]+r[12]) = s16(r[7]);
|
||||||
|
r[23] = r[22];
|
||||||
|
goto loc_8133220C;
|
||||||
|
|
||||||
|
loc_813322EC:
|
||||||
|
|
||||||
|
r[0] = r[5];
|
||||||
|
|
||||||
|
loc_813322F0:
|
||||||
|
|
||||||
|
r[12]= r[6];
|
||||||
|
|
||||||
|
loc_813322F4:
|
||||||
|
|
||||||
|
if( r[12] < 0x200 )
|
||||||
|
goto loc_8133233C;
|
||||||
|
|
||||||
|
if( r[25] != 0x1F )
|
||||||
|
goto loc_81332318;
|
||||||
|
|
||||||
|
r[31] = r[26] >> 31;
|
||||||
|
r[26] = s32(*(unsigned int *)(r[4] + r[24]));
|
||||||
|
r[24] = r[24] + 4;
|
||||||
|
r[25] = 0;
|
||||||
|
goto loc_81332324;
|
||||||
|
|
||||||
|
loc_81332318:
|
||||||
|
|
||||||
|
r[31] = r[26] >> 31;
|
||||||
|
r[25] = r[25] + 1;
|
||||||
|
r[26] = r[26] << 1;
|
||||||
|
|
||||||
|
loc_81332324:
|
||||||
|
|
||||||
|
r[27] = r[12] << 1;
|
||||||
|
if( r[31] != 0 )
|
||||||
|
goto loc_81332334;
|
||||||
|
|
||||||
|
r[12] = s16(*(unsigned short *)(r[8] + r[27]));
|
||||||
|
goto loc_813322F4;
|
||||||
|
|
||||||
|
loc_81332334:
|
||||||
|
|
||||||
|
r[12] = s16(*(unsigned short *)(r[9] + r[27]));
|
||||||
|
goto loc_813322F4;
|
||||||
|
|
||||||
|
loc_8133233C:
|
||||||
|
|
||||||
|
if( r[12] >= 0x100 )
|
||||||
|
goto loc_8133235C;
|
||||||
|
|
||||||
|
*(unsigned char *)(r[3]) = r[12];
|
||||||
|
r[3] = r[3] + 1;
|
||||||
|
r[5] = r[5] - 1;
|
||||||
|
if( r[5] != 0 )
|
||||||
|
goto loc_813322F0;
|
||||||
|
|
||||||
|
goto loc_81332434;
|
||||||
|
|
||||||
|
loc_8133235C:
|
||||||
|
|
||||||
|
r[23] = r[7];
|
||||||
|
|
||||||
|
loc_81332360:
|
||||||
|
|
||||||
|
if( r[23] < 0x800 )
|
||||||
|
goto loc_813323A8;
|
||||||
|
|
||||||
|
if( r[29] != 0x1F )
|
||||||
|
goto loc_81332384;
|
||||||
|
|
||||||
|
r[31] = r[30] >> 31;
|
||||||
|
r[30] = s32(*(unsigned int *)(r[4] + r[28]));
|
||||||
|
r[28] = r[28] + 4;
|
||||||
|
r[29] = 0;
|
||||||
|
goto loc_81332390;
|
||||||
|
|
||||||
|
loc_81332384:
|
||||||
|
|
||||||
|
r[31] = r[30] >> 31;
|
||||||
|
r[29] = r[29] + 1;
|
||||||
|
r[30] = r[30] << 1;
|
||||||
|
|
||||||
|
loc_81332390:
|
||||||
|
|
||||||
|
r[27] = r[23] << 1;
|
||||||
|
if( r[31] != 0 )
|
||||||
|
goto loc_813323A0;
|
||||||
|
|
||||||
|
r[23] = s16(*(unsigned short *)(r[10] + r[27]));
|
||||||
|
goto loc_81332360;
|
||||||
|
|
||||||
|
loc_813323A0:
|
||||||
|
|
||||||
|
r[23] = s16(*(unsigned short *)(r[11] + r[27]));
|
||||||
|
goto loc_81332360;
|
||||||
|
|
||||||
|
loc_813323A8:
|
||||||
|
|
||||||
|
r[12] = r[12] - 0xFD;
|
||||||
|
r[23] = ~r[23] + r[3] + 1;
|
||||||
|
r[5] = ~r[12] + r[5] + 1;
|
||||||
|
r[31] = r[12] >> 3;
|
||||||
|
|
||||||
|
if( r[31] == 0 )
|
||||||
|
goto loc_81332414;
|
||||||
|
|
||||||
|
count = r[31];
|
||||||
|
|
||||||
|
loc_813323C0:
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] - 1);
|
||||||
|
*(unsigned char *)(r[3]) = r[31];
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23]);
|
||||||
|
*(unsigned char *)(r[3]+1) = r[31];
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] + 1);
|
||||||
|
*(unsigned char *)(r[3]+2) = r[31];
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] + 2);
|
||||||
|
*(unsigned char *)(r[3]+3) = r[31];
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] + 3);
|
||||||
|
*(unsigned char *)(r[3]+4) = r[31];
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] + 4);
|
||||||
|
*(unsigned char *)(r[3]+5) = r[31];
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] + 5);
|
||||||
|
*(unsigned char *)(r[3]+6) = r[31];
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] + 6);
|
||||||
|
*(unsigned char *)(r[3]+7) = r[31];
|
||||||
|
|
||||||
|
r[23] = r[23] + 8;
|
||||||
|
r[3] = r[3] + 8;
|
||||||
|
|
||||||
|
if( --count )
|
||||||
|
goto loc_813323C0;
|
||||||
|
|
||||||
|
r[12] = r[12] & 7;
|
||||||
|
if( r[12] == 0 )
|
||||||
|
goto loc_8133242C;
|
||||||
|
|
||||||
|
loc_81332414:
|
||||||
|
|
||||||
|
count = r[12];
|
||||||
|
|
||||||
|
loc_81332418:
|
||||||
|
|
||||||
|
r[31] = *(unsigned char *)(r[23] - 1);
|
||||||
|
r[23] = r[23] + 1;
|
||||||
|
*(unsigned char *)(r[3]) = r[31];
|
||||||
|
r[3] = r[3] + 1;
|
||||||
|
|
||||||
|
if( --count )
|
||||||
|
goto loc_81332418;
|
||||||
|
|
||||||
|
loc_8133242C:
|
||||||
|
|
||||||
|
if( r[5] != 0 )
|
||||||
|
goto loc_813322F0;
|
||||||
|
|
||||||
|
loc_81332434:
|
||||||
|
|
||||||
|
r[3] = r[0];
|
||||||
|
len = r[3];
|
||||||
|
|
||||||
|
//gprintf("Decompressed %d bytes\n", r[3]);
|
||||||
|
free( workingBuffer );
|
||||||
|
return buf1;
|
||||||
|
}
|
30
source/banner/ash.h
Normal file
30
source/banner/ash.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2012 giantpune
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef ASH_H
|
||||||
|
#define ASH_H
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
|
// check if data is ash compressed
|
||||||
|
bool IsAshCompressed( const u8 *stuff, u32 len );
|
||||||
|
|
||||||
|
// decompress ash compressed data
|
||||||
|
//! len is the size of the compressed data, and is set to the size of the decompressed data
|
||||||
|
//! this allocates memory with memalign, free it when you are done with it
|
||||||
|
|
||||||
|
u8* DecompressAsh( const u8 *stuff, u32 &len );
|
||||||
|
#endif // ASH_H
|
76
source/banner/gx_addons.c
Normal file
76
source/banner/gx_addons.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2012 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <gccore.h>
|
||||||
|
|
||||||
|
void GX_Project(f32 mx, f32 my, f32 mz, Mtx mv, const f32 *projection,
|
||||||
|
const f32 *viewport, f32 *sx, f32 *sy, f32 *sz)
|
||||||
|
{
|
||||||
|
float x, y, z, w;
|
||||||
|
|
||||||
|
guVector vec = (guVector) { mx, my, mz };
|
||||||
|
guVector vecRes;
|
||||||
|
guVecMultiply(mv, &vec, &vecRes);
|
||||||
|
|
||||||
|
if(projection[0] == GX_PERSPECTIVE)
|
||||||
|
{
|
||||||
|
x = (vecRes.x * projection[1]) + (vecRes.z * projection[2]);
|
||||||
|
y = (vecRes.y * projection[3]) + (vecRes.z * projection[4]);
|
||||||
|
z = (vecRes.z * projection[5]) + projection[6];
|
||||||
|
w = -1.0f / vecRes.z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = (vecRes.x * projection[1]) + projection[2];
|
||||||
|
y = (vecRes.y * projection[3]) + projection[4];
|
||||||
|
z = (vecRes.z * projection[5]) + projection[6];
|
||||||
|
w = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sx = viewport[0] + (w * x * viewport[2] + viewport[2]) * 0.5f;
|
||||||
|
*sy = viewport[1] - (w * y * viewport[3] - viewport[3]) * 0.5f;
|
||||||
|
*sz = viewport[5] + (w * z * (viewport[5] - viewport[4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GX_GetProjectionv( f32* ptr, Mtx44 p, u8 type)
|
||||||
|
{
|
||||||
|
ptr[0] = (f32)type;
|
||||||
|
ptr[1] = p[0][0];
|
||||||
|
ptr[3] = p[1][1];
|
||||||
|
ptr[5] = p[2][2];
|
||||||
|
ptr[6] = p[2][3];
|
||||||
|
|
||||||
|
if(type == GX_PERSPECTIVE)
|
||||||
|
{
|
||||||
|
ptr[2] = p[0][2];
|
||||||
|
ptr[4] = p[1][2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr[2] = p[0][3];
|
||||||
|
ptr[4] = p[1][3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GX_GetViewportv( f32* ptr, GXRModeObj *vmode )
|
||||||
|
{
|
||||||
|
ptr[0] = 0.0f;
|
||||||
|
ptr[1] = 0.0f;
|
||||||
|
ptr[2] = vmode->fbWidth;
|
||||||
|
ptr[3] = vmode->efbHeight;
|
||||||
|
ptr[4] = 0.0f;
|
||||||
|
ptr[5] = 1.0f;
|
||||||
|
}
|
35
source/banner/gx_addons.h
Normal file
35
source/banner/gx_addons.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2012 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GX_ADDONS_H_
|
||||||
|
#define GX_ADDONS_H_
|
||||||
|
|
||||||
|
#include <gccore.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void GX_Project(f32 mx, f32 my, f32 mz, Mtx mv, const f32 *projection,
|
||||||
|
const f32 *viewport, f32 *sx, f32 *sy, f32 *sz);
|
||||||
|
void GX_GetProjectionv( f32* ptr, Mtx44 p, u8 type);
|
||||||
|
void GX_GetViewportv( f32* ptr, GXRModeObj *vmode );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -45,7 +45,7 @@ s32 __decompressLZ77_11(u8 *in, u32 inputLen, u8 **output, u32 *outputLen)
|
|||||||
compressedPos += 0x4;
|
compressedPos += 0x4;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Decompressed size : %i\n", decompressedSize);
|
//printf("Decompressed size : %i\n", decompressedSize);
|
||||||
|
|
||||||
out = MEM2_alloc(ALIGN32(decompressedSize));
|
out = MEM2_alloc(ALIGN32(decompressedSize));
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
@ -132,7 +132,7 @@ s32 __decompressLZ77_10(u8 *in, u8 **output, u32 *outputLen)
|
|||||||
|
|
||||||
//int compressionType = (packBytes(in[0], in[1], in[2], in[3]) >> 4) & 0xF;
|
//int compressionType = (packBytes(in[0], in[1], in[2], in[3]) >> 4) & 0xF;
|
||||||
|
|
||||||
printf("Decompressed size : %i\n", decompressedSize);
|
//printf("Decompressed size : %i\n", decompressedSize);
|
||||||
|
|
||||||
out = MEM2_alloc(ALIGN32(decompressedSize));
|
out = MEM2_alloc(ALIGN32(decompressedSize));
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
@ -200,15 +200,15 @@ int decompressLZ77content(u8 *buffer, u32 length, u8 **output, u32 *outputLen)
|
|||||||
switch (buffer[0])
|
switch (buffer[0])
|
||||||
{
|
{
|
||||||
case LZ77_0x10_FLAG:
|
case LZ77_0x10_FLAG:
|
||||||
printf("LZ77 variant 0x10 compressed content...unpacking may take a while...\n");
|
//printf("LZ77 variant 0x10 compressed content...unpacking may take a while...\n");
|
||||||
ret = __decompressLZ77_10(buffer, output, outputLen);
|
ret = __decompressLZ77_10(buffer, output, outputLen);
|
||||||
break;
|
break;
|
||||||
case LZ77_0x11_FLAG:
|
case LZ77_0x11_FLAG:
|
||||||
printf("LZ77 variant 0x11 compressed content...unpacking may take a while...\n");
|
//printf("LZ77 variant 0x11 compressed content...unpacking may take a while...\n");
|
||||||
ret = __decompressLZ77_11(buffer, length, output, outputLen);
|
ret = __decompressLZ77_11(buffer, length, output, outputLen);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Not compressed ...\n");
|
//printf("Not compressed ...\n");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#define WIIFONT_NAME_KOR "Wii-kr_Round Gothic B.ttf"
|
#define WIIFONT_NAME_KOR "Wii-kr_Round Gothic B.ttf"
|
||||||
const u8 WIIFONT_HASH[] = {0x32, 0xb3, 0x39, 0xcb, 0xbb, 0x50, 0x7d, 0x50, 0x27, 0x79, 0x25, 0x9a, 0x78, 0x66, 0x99, 0x5d, 0x03, 0x0b, 0x1d, 0x88};
|
const u8 WIIFONT_HASH[] = {0x32, 0xb3, 0x39, 0xcb, 0xbb, 0x50, 0x7d, 0x50, 0x27, 0x79, 0x25, 0x9a, 0x78, 0x66, 0x99, 0x5d, 0x03, 0x0b, 0x1d, 0x88};
|
||||||
const u8 WIIFONT_HASH_KOR[] = {0xb7, 0x15, 0x6d, 0xf0, 0xf4, 0xae, 0x07, 0x8f, 0xd1, 0x53, 0x58, 0x3e, 0x93, 0x6e, 0x07, 0xc0, 0x98, 0x77, 0x49, 0x0e};
|
const u8 WIIFONT_HASH_KOR[] = {0xb7, 0x15, 0x6d, 0xf0, 0xf4, 0xae, 0x07, 0x8f, 0xd1, 0x53, 0x58, 0x3e, 0x93, 0x6e, 0x07, 0xc0, 0x98, 0x77, 0x49, 0x0e};
|
||||||
|
const u8 WFB_HASH[] = { 0x4f, 0xad, 0x97, 0xfd, 0x4a, 0x28, 0x8c, 0x47, 0xe0, 0x58, 0x7f, 0x3b, 0xbd, 0x29, 0x23, 0x79, 0xf8, 0x70, 0x9e, 0xb9 };
|
||||||
|
|
||||||
#define FONT_BOLD 36u
|
#define FONT_BOLD 36u
|
||||||
#define FONT_NOBOLD 8u
|
#define FONT_NOBOLD 8u
|
||||||
|
@ -169,6 +169,10 @@ void CVideo::init(void)
|
|||||||
GX_SetNumChans(0);
|
GX_SetNumChans(0);
|
||||||
GX_SetZCompLoc(GX_ENABLE);
|
GX_SetZCompLoc(GX_ENABLE);
|
||||||
setup2DProjection();
|
setup2DProjection();
|
||||||
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||||
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||||
|
for(u32 i = 0; i < 8; i++)
|
||||||
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0+i, GX_TEX_ST, GX_F32, 0);
|
||||||
_clearScreen();
|
_clearScreen();
|
||||||
VIDEO_SetBlack(FALSE);
|
VIDEO_SetBlack(FALSE);
|
||||||
VIDEO_Flush();
|
VIDEO_Flush();
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
void setup2DProjection(bool setViewPort = true, bool noScale = false);
|
void setup2DProjection(bool setViewPort = true, bool noScale = false);
|
||||||
u32 width(void) const { return m_rmode->fbWidth; }
|
u32 width(void) const { return m_rmode->fbWidth; }
|
||||||
u32 height(void) const { return m_rmode->efbHeight; }
|
u32 height(void) const { return m_rmode->efbHeight; }
|
||||||
|
GXRModeObj *vid_mode(void) const { return m_rmode; }
|
||||||
u32 width2D(void) { return m_width2D; }
|
u32 width2D(void) { return m_width2D; }
|
||||||
u32 height2D(void) { return m_height2D; }
|
u32 height2D(void) { return m_height2D; }
|
||||||
bool wide(void) const { return m_wide; }
|
bool wide(void) const { return m_wide; }
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "gc/fileOps.h"
|
#include "gc/fileOps.h"
|
||||||
#include "Gekko.h"
|
#include "Gekko.h"
|
||||||
#include "GameTDB.hpp"
|
#include "GameTDB.hpp"
|
||||||
|
#include "BannerWindow.hpp"
|
||||||
|
|
||||||
// Sounds
|
// Sounds
|
||||||
extern const u8 click_wav[];
|
extern const u8 click_wav[];
|
||||||
@ -109,6 +110,10 @@ extern const u8 butzhcnoffs_png[];
|
|||||||
extern const u8 checkbox_png[];
|
extern const u8 checkbox_png[];
|
||||||
extern const u8 checkboxs_png[];
|
extern const u8 checkboxs_png[];
|
||||||
|
|
||||||
|
SmartBuf m_wbf1_font;
|
||||||
|
SmartBuf m_wbf2_font;
|
||||||
|
BannerWindow m_banner;
|
||||||
|
|
||||||
CMenu::CMenu(CVideo &vid) :
|
CMenu::CMenu(CVideo &vid) :
|
||||||
m_vid(vid)
|
m_vid(vid)
|
||||||
{
|
{
|
||||||
@ -472,7 +477,7 @@ void CMenu::cleanup(bool ios_reload)
|
|||||||
m_cf.stopCoverLoader();
|
m_cf.stopCoverLoader();
|
||||||
m_cf.clear();
|
m_cf.clear();
|
||||||
ClearGameSoundThreadStack();
|
ClearGameSoundThreadStack();
|
||||||
|
m_banner.DeleteBanner();
|
||||||
m_plugin.Cleanup();
|
m_plugin.Cleanup();
|
||||||
|
|
||||||
_stopSounds();
|
_stopSounds();
|
||||||
@ -1758,11 +1763,12 @@ void CMenu::_mainLoopCommon(bool withCF, bool blockReboot, bool adjusting)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_fa.draw();
|
m_fa.draw();
|
||||||
|
if(m_banner.GetSelectedGame())
|
||||||
|
m_banner.Draw();
|
||||||
|
|
||||||
m_btnMgr.draw();
|
m_btnMgr.draw();
|
||||||
ScanInput();
|
ScanInput();
|
||||||
|
|
||||||
m_vid.setup2DProjection();
|
|
||||||
m_vid.render();
|
m_vid.render();
|
||||||
if(!blockReboot)
|
if(!blockReboot)
|
||||||
{
|
{
|
||||||
@ -2324,12 +2330,10 @@ retry:
|
|||||||
u8 *u8_font_archive = ISFS_GetFile((u8 *) u8_font_filename, &size, 0);
|
u8 *u8_font_archive = ISFS_GetFile((u8 *) u8_font_filename, &size, 0);
|
||||||
//gprintf("Opened fontfile: %s: %d bytes\n", u8_font_filename, size);
|
//gprintf("Opened fontfile: %s: %d bytes\n", u8_font_filename, size);
|
||||||
|
|
||||||
if (u8_font_archive != NULL)
|
if(u8_font_archive != NULL)
|
||||||
{
|
{
|
||||||
const u8 *font_file = u8_get_file_by_index(u8_font_archive, 1, &size); // There is only one file in that app
|
const u8 *font_file = u8_get_file_by_index(u8_font_archive, 1, &size); // There is only one file in that app
|
||||||
|
|
||||||
//gprintf("Extracted font: %d\n", size);
|
//gprintf("Extracted font: %d\n", size);
|
||||||
|
|
||||||
m_base_font = smartMem2Alloc(size);
|
m_base_font = smartMem2Alloc(size);
|
||||||
memcpy(m_base_font.get(), font_file, size);
|
memcpy(m_base_font.get(), font_file, size);
|
||||||
if(!!m_base_font)
|
if(!!m_base_font)
|
||||||
@ -2338,6 +2342,26 @@ retry:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if(memcmp(cm[i].sha1, WFB_HASH, 20) == 0)
|
||||||
|
{
|
||||||
|
// Name found, load it and unpack it
|
||||||
|
char font_filename[32] ATTRIBUTE_ALIGN(32);
|
||||||
|
strcpy(font_filename, "/shared1/XXXXXXXX.app"); // Faster than sprintf
|
||||||
|
memcpy(font_filename+9, cm[i].filename, 8);
|
||||||
|
u8 *u8_font_archive = ISFS_GetFile((u8 *)font_filename, &size, 0);
|
||||||
|
if(u8_font_archive != NULL)
|
||||||
|
{
|
||||||
|
const u8 *font_file1 = u8_get_file(u8_font_archive, "wbf1.brfna", &size);
|
||||||
|
m_wbf1_font = smartMem2Alloc(size);
|
||||||
|
memcpy(m_wbf1_font.get(), font_file1, size);
|
||||||
|
|
||||||
|
const u8 *font_file2 = u8_get_file(u8_font_archive, "wbf2.brfna", &size);
|
||||||
|
m_wbf2_font = smartMem2Alloc(size);
|
||||||
|
memcpy(m_wbf2_font.get(), font_file2, size);
|
||||||
|
|
||||||
|
MEM2_free(u8_font_archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retry)
|
if (!retry)
|
||||||
@ -2353,6 +2377,9 @@ void CMenu::_cleanupDefaultFont()
|
|||||||
{
|
{
|
||||||
m_base_font.release();
|
m_base_font.release();
|
||||||
m_base_font_size = 0;
|
m_base_font_size = 0;
|
||||||
|
|
||||||
|
m_wbf1_font.release();
|
||||||
|
m_wbf2_font.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CMenu::_domainFromView()
|
const char *CMenu::_domainFromView()
|
||||||
|
@ -73,7 +73,6 @@ private:
|
|||||||
Config m_titles;
|
Config m_titles;
|
||||||
Config m_version;
|
Config m_version;
|
||||||
Plugin m_plugin;
|
Plugin m_plugin;
|
||||||
Channels m_channels;
|
|
||||||
vector<string> m_homebrewArgs;
|
vector<string> m_homebrewArgs;
|
||||||
SmartBuf m_base_font;
|
SmartBuf m_base_font;
|
||||||
u32 m_base_font_size;
|
u32 m_base_font_size;
|
||||||
@ -147,10 +146,6 @@ private:
|
|||||||
STexture m_gameBgLQ;
|
STexture m_gameBgLQ;
|
||||||
STexture m_mainBgLQ;
|
STexture m_mainBgLQ;
|
||||||
STexture m_categoryBg;
|
STexture m_categoryBg;
|
||||||
//
|
|
||||||
u32 m_errorLblMessage;
|
|
||||||
u32 m_errorLblIcon;
|
|
||||||
u32 m_errorLblUser[4];
|
|
||||||
//Main Coverflow
|
//Main Coverflow
|
||||||
u32 m_mainBtnConfig;
|
u32 m_mainBtnConfig;
|
||||||
u32 m_mainBtnInfo;
|
u32 m_mainBtnInfo;
|
||||||
@ -677,7 +672,7 @@ private:
|
|||||||
lwp_t m_gameSoundThread;
|
lwp_t m_gameSoundThread;
|
||||||
bool m_gamesound_changed;
|
bool m_gamesound_changed;
|
||||||
u8 m_bnrSndVol;
|
u8 m_bnrSndVol;
|
||||||
|
|
||||||
bool m_video_playing;
|
bool m_video_playing;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -16,6 +16,8 @@ static inline int loopNum(int i, int s)
|
|||||||
int currentChannelIndex = -1;
|
int currentChannelIndex = -1;
|
||||||
int amountOfChannels = -1;
|
int amountOfChannels = -1;
|
||||||
|
|
||||||
|
Channels m_channels;
|
||||||
|
|
||||||
const CMenu::SOption CMenu::_exitTo[6] = {
|
const CMenu::SOption CMenu::_exitTo[6] = {
|
||||||
{ "def", L"Default" },
|
{ "def", L"Default" },
|
||||||
{ "menu", L"System Menu" },
|
{ "menu", L"System Menu" },
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include "gecko.h"
|
#include "gecko.h"
|
||||||
|
|
||||||
extern const u8 error_png[];
|
extern const u8 error_png[];
|
||||||
|
u32 m_errorLblMessage;
|
||||||
|
u32 m_errorLblIcon;
|
||||||
|
u32 m_errorLblUser[4];
|
||||||
|
|
||||||
void CMenu::error(const wstringEx &msg)
|
void CMenu::error(const wstringEx &msg)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "wip.h"
|
#include "wip.h"
|
||||||
#include "channel_launcher.h"
|
#include "channel_launcher.h"
|
||||||
#include "devicemounter/sdhc.h"
|
#include "devicemounter/sdhc.h"
|
||||||
|
#include "BannerWindow.hpp"
|
||||||
|
|
||||||
#include <network.h>
|
#include <network.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -57,6 +58,8 @@ extern u32 sector_size;
|
|||||||
extern int mainIOS;
|
extern int mainIOS;
|
||||||
static u64 sm_title_id[8] ATTRIBUTE_ALIGN(32);
|
static u64 sm_title_id[8] ATTRIBUTE_ALIGN(32);
|
||||||
|
|
||||||
|
bool m_zoom_banner;
|
||||||
|
|
||||||
const string CMenu::_translations[23] = {
|
const string CMenu::_translations[23] = {
|
||||||
"Default",
|
"Default",
|
||||||
"Arab",
|
"Arab",
|
||||||
@ -359,17 +362,19 @@ void CMenu::_game(bool launch)
|
|||||||
m_gameSelected = true;
|
m_gameSelected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern BannerWindow m_banner;
|
||||||
|
string id(m_cf.getId());
|
||||||
s8 startGameSound = 1;
|
s8 startGameSound = 1;
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(startGameSound < 1)
|
if(startGameSound < 1)
|
||||||
startGameSound++;
|
startGameSound++;
|
||||||
|
|
||||||
string id(m_cf.getId());
|
|
||||||
u64 chantitle = m_cf.getChanTitle();
|
u64 chantitle = m_cf.getChanTitle();
|
||||||
|
|
||||||
if(startGameSound == -5)
|
if(startGameSound == -5)
|
||||||
{
|
{
|
||||||
|
id = m_cf.getId();
|
||||||
_playGameSound();
|
_playGameSound();
|
||||||
_showGame();
|
_showGame();
|
||||||
}
|
}
|
||||||
@ -392,6 +397,7 @@ void CMenu::_game(bool launch)
|
|||||||
m_gameSound.FreeMemory();
|
m_gameSound.FreeMemory();
|
||||||
CheckGameSoundThread();
|
CheckGameSoundThread();
|
||||||
ClearGameSoundThreadStack();
|
ClearGameSoundThreadStack();
|
||||||
|
m_banner.DeleteBanner();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(BTN_PLUS_PRESSED && m_GameTDBLoaded && (m_cf.getHdr()->type == TYPE_WII_GAME || m_cf.getHdr()->type == TYPE_GC_GAME || m_cf.getHdr()->type == TYPE_CHANNEL))
|
else if(BTN_PLUS_PRESSED && m_GameTDBLoaded && (m_cf.getHdr()->type == TYPE_WII_GAME || m_cf.getHdr()->type == TYPE_GC_GAME || m_cf.getHdr()->type == TYPE_CHANNEL))
|
||||||
@ -466,9 +472,19 @@ void CMenu::_game(bool launch)
|
|||||||
m_gcfg1.setBool("ADULTONLY", id, !m_gcfg1.getBool("ADULTONLY", id, false));
|
m_gcfg1.setBool("ADULTONLY", id, !m_gcfg1.getBool("ADULTONLY", id, false));
|
||||||
else if(m_btnMgr.selected(m_gameBtnBack))
|
else if(m_btnMgr.selected(m_gameBtnBack))
|
||||||
{
|
{
|
||||||
m_gameSound.Stop();
|
//m_gameSound.Stop();
|
||||||
CheckGameSoundThread();
|
//CheckGameSoundThread();
|
||||||
break;
|
//break;
|
||||||
|
if(m_zoom_banner)
|
||||||
|
{
|
||||||
|
m_banner.ZoomOut();
|
||||||
|
m_zoom_banner = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_banner.ZoomIn();
|
||||||
|
m_zoom_banner = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(m_btnMgr.selected(m_gameBtnSettings))
|
else if(m_btnMgr.selected(m_gameBtnSettings))
|
||||||
{
|
{
|
||||||
@ -1425,6 +1441,8 @@ void CMenu::_initGameMenu(CMenu::SThemeData &theme)
|
|||||||
_setHideAnim(m_gameBtnDelete, "GAME/DELETE_BTN", 0, 0, -1.5f, -1.5f);
|
_setHideAnim(m_gameBtnDelete, "GAME/DELETE_BTN", 0, 0, -1.5f, -1.5f);
|
||||||
_hideGame(true);
|
_hideGame(true);
|
||||||
_textGame();
|
_textGame();
|
||||||
|
|
||||||
|
m_zoom_banner = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMenu::_textGame(void)
|
void CMenu::_textGame(void)
|
||||||
@ -1476,7 +1494,12 @@ void CMenu::_gameSoundThread(CMenu *m)
|
|||||||
}
|
}
|
||||||
_extractBannerTitle(banner, GetLanguage(m->m_loc.getString(m->m_curLanguage, "gametdb_code", "EN").c_str()));
|
_extractBannerTitle(banner, GetLanguage(m->m_loc.getString(m->m_curLanguage, "gametdb_code", "EN").c_str()));
|
||||||
|
|
||||||
|
extern SmartBuf m_wbf1_font;
|
||||||
|
extern SmartBuf m_wbf2_font;
|
||||||
|
extern BannerWindow m_banner;
|
||||||
|
|
||||||
const u8 *soundBin = banner->GetFile((char *) "sound.bin", &sndSize);
|
const u8 *soundBin = banner->GetFile((char *) "sound.bin", &sndSize);
|
||||||
|
m_banner.LoadBanner(banner, &m->m_vid, m_wbf1_font.get(), m_wbf2_font.get());
|
||||||
delete banner;
|
delete banner;
|
||||||
|
|
||||||
if (soundBin == NULL || (((IMD5Header *)soundBin)->fcc != 'IMD5' && ((IMD5Header *)soundBin)->fcc != 'RIFF'))
|
if (soundBin == NULL || (((IMD5Header *)soundBin)->fcc != 'IMD5' && ((IMD5Header *)soundBin)->fcc != 'RIFF'))
|
||||||
|
@ -480,7 +480,7 @@ void GuiSound::UncompressSoundbin(const u8 * snd, u32 len, bool isallocated)
|
|||||||
if(isallocated)
|
if(isallocated)
|
||||||
{
|
{
|
||||||
void *p = (void *)snd;
|
void *p = (void *)snd;
|
||||||
MEM1_free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
allocated = true;
|
allocated = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user