mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-12-25 11:21:55 +01:00
706e18c6c0
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
592 lines
15 KiB
C++
592 lines
15 KiB
C++
/*
|
|
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);
|
|
}
|