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); }
void setUp2D(void) { GX_InvVtxCache(); GX_InvalidateTexAll(); GX_SetNumTexGens(1); GX_SetChanCtrl(GX_COLOR1A1,GX_FALSE,GX_SRC_VTX,GX_SRC_VTX,GX_LIGHTNULL,GX_DF_NONE,GX_AF_NONE); GX_SetChanCtrl(GX_COLOR0A0,GX_TRUE,GX_SRC_VTX,GX_SRC_VTX,GX_LIGHTNULL,GX_DF_NONE,GX_AF_NONE); }
void glDisable(GLenum type){ switch(type) { case GL_DEPTH_TEST: depthtestenabled = GX_FALSE; break; case GL_LIGHTING: GX_SetNumChans(1); //keep this at one all time? GX_SetNumTevStages(1); if (tex2denabled){ GX_SetNumTexGens(1); //multitexturing so set to 1 for now GX_SetTevOp(GX_TEVSTAGE0,GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); } else { GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); GX_SetChanCtrl(GX_COLOR0A0,GX_DISABLE,GX_SRC_REG,GX_SRC_VTX,GX_LIGHTNULL,GX_DF_NONE,GX_AF_NONE); } break; case GL_TEXTURE_2D: tex2denabled = false; GX_SetNumTexGens(0); //texturing is of so no textures GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); break; case GL_LIGHT0: gxlightenabled[0]=false; break; case GL_LIGHT1: gxlightenabled[1]=false; break; case GL_LIGHT2: gxlightenabled[2]=false; break; case GL_LIGHT3: gxlightenabled[3]=false; break; case GL_LIGHT4: gxlightenabled[4]=false; break; case GL_LIGHT5: gxlightenabled[5]=false; break; case GL_LIGHT6: gxlightenabled[6]=false; break; case GL_LIGHT7: gxlightenabled[7]=false; break; case GL_CULL_FACE: gxcullfaceanabled=false; break; }; }
/**************************************************************************** * Restore GX to 2D mode drawing ***************************************************************************/ void ReSetup_GX(void) { // 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); }
void SetLight(Mtx view) { guVector lpos; GXLightObj lobj; lpos.x = 0; lpos.y = 0; lpos.z = 2.0f; guVecMultiply(view,&lpos,&lpos); GX_InitLightPos(&lobj,lpos.x,lpos.y,lpos.z); GX_InitLightColor(&lobj,lightColor[0]); GX_LoadLightObj(&lobj,GX_LIGHT0); // set number of rasterized color channels GX_SetNumChans(1); GX_SetChanCtrl(GX_COLOR0A0,GX_ENABLE,GX_SRC_VTX,GX_SRC_VTX,GX_LIGHT0,GX_DF_CLAMP,GX_AF_NONE); GX_SetChanAmbColor(GX_COLOR0A0,lightColor[1]); GX_SetChanMatColor(GX_COLOR0A0,lightColor[2]); }
static void glass_postpass (void *dummy) { GXLightObj lo0; guVector ldir; #include "glass-postpass.inc" GX_SetChanAmbColor (GX_ALPHA0, (GXColor) { 0, 0, 0, 0 }); GX_SetChanMatColor (GX_ALPHA0, (GXColor) { 0, 0, 0, 255 }); GX_SetChanCtrl (GX_ALPHA0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_NONE, GX_AF_SPEC); /* Light 0: use for both specular and diffuse lighting. */ guVecSub (&light0.tpos, &light0.tlookat, &ldir); guVecNormalize (&ldir); GX_InitSpecularDir (&lo0, -ldir.x, -ldir.y, -ldir.z); GX_InitLightShininess (&lo0, 128); GX_InitLightColor (&lo0, (GXColor) { 192, 192, 192, 255 }); GX_LoadLightObj (&lo0, GX_LIGHT0); }
void glEnable(GLenum type){ u8 gxlightmask = 0x00000000; u8 gxlightmaskspec = 0x00000000; int lightcounter = 0; int countlights =0; switch(type) { case GL_DEPTH_TEST: depthtestenabled = GX_TRUE; break; case GL_LIGHTING: //getting opengl lights to work on gx // //xg has only one light color (a diffuse one) //opengl lights have the following colors: diffuse, ambient and specular //also opengl has a global ambient color independend of a individual light //gx has 2 material colors: diffuse (mat) and ambient (can also be considered part of light?) //opengl material have the followning colors: diffuse, ambient, specular and emission //so we (may) have problem (or call it a challenge) //now how does opengl calculate light with all these colors //vertex color = material emission // + global ambient scaled by material ambient // + ambient, diffuse, specular contributions from light(s), properly attinuated // //let us take these apart. // //material emission is like a constant color. So we can just add this in a tev stage. The only problem is how to add a color to a specific stage?) // //global ambient scaled by material ambient //this is global ambient * material ambient so we can feed that result to an tev stage. // //Now comes the hard part as each color is used in the light calulation. And we only have once color in gx. //Maybe we are lucky as each colors term is added to each other and only then used in light calculation //So we might get away with just adding the 3 colors upfront and feed that as color to the light source //But first let see how these terms are calculated. // //Ambient Term = light ambient * material ambient = GXChanAmbColor ? //Diffuse Term = surface * (light diffuse * material diffuse) light diffues = light color | material diffuse = GXChanMatColor (let gx handle this) //Specular Term = normal.shininess * (light specular * material specular) (let gx handle this, but add lspec*mspec to GXChanMatColor) // //now we could use 3 light to emulate 1 opengl light but that would not be helpfull //so maybe there is an other way also gx material misses color components // //gx has max to channels //each can be setup differently so we can have on chanel for normal diffuse //and the other for specular. But we only have on light color so unless the specular color equals light color this it not usefull) //maybe some experiments with GXChanMatColor help with that? So light color to none and all color CHANMatColor? // //also we have multiple tev stages. //as we have used 2 channels we have to use 3 stages //stage 1 = emissive + global ambient scaled by material as constant color (maybe 2 stages?) //stage 2 = ambient + diffuse //stage 3 = specular // //So this might do the trick in theory. Now on to practice... //<h0lyRS> did you try setting specular to channel GX_COLOR1A1, and diffuse to GX_COLOR0A0, so you can blend them anyway you want? //this could add an extra color? //one way is adding the specular light, other way is multiplying //Setup lightmask with enabled lights (thanks h0lyRS) for (lightcounter =0; lightcounter < 4; lightcounter++){ if(gxlightenabled[lightcounter]){ //when light is enabled gxlightmask |= (GX_LIGHT0 << lightcounter); gxlightmaskspec |= (GX_LIGHT0 << (lightcounter+4) ); //countlights++; } }; // gxlightmask |= (GX_LIGHT0 << 0); // gxlightmaskspec |= (GX_LIGHT0 << 1); //Setup light system/channels GX_SetNumChans(2); //dependend on if there is a specular color/effect needed //channel 1 (ambient + diffuse) GX_SetChanCtrl(GX_COLOR0A0,GX_TRUE,GX_SRC_REG,GX_SRC_REG,gxlightmask,GX_DF_CLAMP,GX_AF_SPOT); //channel 2 (specular) GX_SetChanCtrl(GX_COLOR1A1,GX_ENABLE,GX_SRC_REG,GX_SRC_REG,gxlightmaskspec,GX_DF_CLAMP,GX_AF_SPEC); //Setup TEV-shader //Setup the number of tev stages needed int numtevstages = 0; if (tex2denabled){ numtevstages = 5; } else { numtevstages = 4; } GX_SetNumTevStages(numtevstages); //each extra color takes another stage? //stage 1 (global ambient light) //color GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); //shagkur method GX_SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //alpha GX_SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); //shagkur method GX_SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //tevorder GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); //only use color //end stage 1 //stage 2 (global ambient light) //color GX_SetTevColorIn(GX_TEVSTAGE1, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C1); //shagkur method GX_SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //alpha GX_SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_APREV, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A1); //shagkur method GX_SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //tevorder GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); //only use color //end stage 2 //stage 3 (ambient and diffuse light from material and lights) //color GX_SetTevColorIn(GX_TEVSTAGE2, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); GX_SetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //alpha GX_SetTevAlphaIn(GX_TEVSTAGE2, GX_CA_APREV, GX_CA_ZERO, GX_CA_ZERO, GX_CC_RASA); GX_SetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //tevorder GX_SetTevOrder(GX_TEVSTAGE2, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); //only use color // end stage 3 //stage 4 (specular light) // color - blend GX_SetTevColorOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //GX_SetTevColorIn(GX_TEVSTAGE3, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); // GX_SetTevColorIn(GX_TEVSTAGE3,GX_CC_ZERO,GX_CC_RASC,GX_CC_CPREV,GX_CC_ZERO); GX_SetTevColorIn(GX_TEVSTAGE3,GX_CC_ZERO,GX_CC_RASC,GX_CC_ONE,GX_CC_CPREV); // alpha - nop GX_SetTevAlphaOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); //GX_SetTevAlphaIn(GX_TEVSTAGE3, GX_CA_APREV, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); //shagkur method GX_SetTevAlphaIn(GX_TEVSTAGE3,GX_CA_ZERO,GX_CA_RASA,GX_CA_APREV,GX_CA_ZERO); GX_SetTevOrder(GX_TEVSTAGE3, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR1A1); // end stage 4 if (tex2denabled){ // stage 5 (textures) GX_SetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); //use texture GX_SetTevOp(GX_TEVSTAGE4, GX_MODULATE); //blend with previous stage // end stage 5 } break; case GL_TEXTURE_2D: tex2denabled = true; GX_SetNumTexGens(1); //multitexturing so set to 1 for now GX_SetTevOp(GX_TEVSTAGE0,GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); break; case GL_LIGHT0: gxlightenabled[0]=true; break; case GL_LIGHT1: gxlightenabled[1]=true; break; case GL_LIGHT2: gxlightenabled[2]=true; break; case GL_LIGHT3: gxlightenabled[3]=true; break; case GL_LIGHT4: gxlightenabled[4]=true; break; case GL_LIGHT5: gxlightenabled[5]=true; break; case GL_LIGHT6: gxlightenabled[6]=true; break; case GL_LIGHT7: gxlightenabled[7]=true; break; case GL_CULL_FACE: gxcullfaceanabled=true; break; }; }
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++ ) { // Devkitppc_r27 internal compiler error //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) }); u8 r = (u8) LIMIT(matHead->color_regs[i].r, 0, 0xFF); u8 g = (u8) LIMIT(matHead->color_regs[i].g, 0, 0xFF); u8 b = (u8) LIMIT(matHead->color_regs[i].b, 0, 0xFF); u8 a = (u8) LIMIT(matHead->color_regs[i].a, 0, 0xFF); GX_SetTevColor((u8) (i + 1), (GXColor){r,g,b,a}); } 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 gdl::Font::DrawText(const char *text, short x, short y, float scale, u_int col) { float tx; GXColor textCol; Mtx tempMatrix; if (vList == NULL) return; if (tList == NULL) return; if ((x == gdl::Centered) || (x == gdl::PCentered)) { tx = gdl::ScreenCenterX-((gdl::Font::CalcStrLen(text)*scale)/2)+(scale/2); } else { tx = x; } textCol.r = RED(col); textCol.g = GREEN(col); textCol.b = BLUE(col); textCol.a = ALPHA(col); GX_LoadTexObj(gdl::Font::charSheet.TexObj(), GX_TEXMAP0); GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_INDEX16); GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16); GX_SetArray(GX_VA_POS, gdl::Font::vList, 2*sizeof(s16)); GX_SetArray(GX_VA_TEX0, gdl::Font::tList, 2*sizeof(f32)); GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE); GX_SetChanMatColor(GX_COLOR0A0, textCol); guMtxCopy(gdl::wii::ModelMtx, tempMatrix); guMtxApplyTrans(tempMatrix, tempMatrix, tx, y, 0); guMtxApplyScale(tempMatrix, tempMatrix, scale, scale, 0); GX_LoadPosMtxImm(tempMatrix, GX_PNMTX0); for(int i=0; text[i]!=0x00; i++) { int tc=4*((u_char)text[i]); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position1x16(tc); GX_TexCoord1x16(tc); GX_Position1x16(tc+1); GX_TexCoord1x16(tc+1); GX_Position1x16(tc+2); GX_TexCoord1x16(tc+2); GX_Position1x16(tc+3); GX_TexCoord1x16(tc+3); GX_End(); guMtxApplyTrans(tempMatrix, tempMatrix, gdl::Font::charWidth[(u_char)text[i]], 0, 0); GX_LoadPosMtxImm(tempMatrix, GX_PNMTX0); } GX_LoadPosMtxImm(gdl::wii::ModelMtx, GX_PNMTX0); GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE); }
void gdl::FFont::DrawText(const char *text, short x, short y, float scale, u32 col) { // Draws text using the current font set by gdl_SetCurrentFont() float tx; int c,tc; Mtx TempMatrix; GXColor TempCol; if (vList == NULL) return; if ((x == gdl::Centered) || (x == gdl::PCentered)) { tx = gdl::ScreenCenterX - ((((cw+1)*strlen(text))*scale)/2)+(scale/2); } else { tx = x; } TempCol.r = RED(col); TempCol.g = GREEN(col); TempCol.b = BLUE(col); TempCol.a = ALPHA(col); GX_LoadTexObj(charTexObj, GX_TEXMAP0); GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_INDEX8); GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16); GX_SetArray(GX_VA_POS, vList, 2*sizeof(s16)); GX_SetArray(GX_VA_TEX0, tList, 2*sizeof(f32)); guMtxCopy(gdl::wii::ModelMtx, TempMatrix); guMtxApplyTrans(TempMatrix, TempMatrix, tx, y, 0); guMtxApplyScale(TempMatrix, TempMatrix, scale, scale, 0); GX_LoadPosMtxImm(TempMatrix, GX_PNMTX0); GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE); GX_SetChanMatColor(GX_COLOR0A0, TempCol); for(c=0; text[c] != 0x00; c++) { tc = 4*((u_char*)text)[c]; GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position1x8(0); GX_TexCoord1x16(tc); GX_Position1x8(1); GX_TexCoord1x16(tc+1); GX_Position1x8(2); GX_TexCoord1x16(tc+2); GX_Position1x8(3); GX_TexCoord1x16(tc+3); GX_End(); guMtxApplyTrans(TempMatrix, TempMatrix, cw+1, 0, 0); GX_LoadPosMtxImm(TempMatrix, GX_PNMTX0); } GX_LoadPosMtxImm(gdl::wii::ModelMtx, GX_PNMTX0); GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE); }