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 Alternate240p480i() { int frames = 0, seconds = 0, minutes = 0, hours = 0, done = 0, current = 0, res = 0, status = 0; timecode times[20]; u32 pressed, oldvmode = vmode; char buffer[20]; ImagePtr back; if(IsPAL) { if(vmode != VIDEO_288P) { SetVideoMode(VIDEO_288P); SetupGX(); } } else { if(vmode != VIDEO_240P) { SetVideoMode(VIDEO_240P); SetupGX(); } } back = LoadImage(WHITEIMG, 1); if(!back) return; back->r = 0x00; back->g = 0x00; back->b = 0x00; CalculateUV(0, 0, dW, dH, back); ChangeVideoEnabled = 0; while(!done && !EndProgram) { frames ++; if(IsPAL) { if(frames > 49) { frames = 0; seconds ++; } } else { if(frames > 59) { frames = 0; seconds ++; } } if(seconds > 59) { seconds = 0; minutes ++; } if(minutes > 59) { minutes = 0; hours ++; } if(hours > 99) hours = 0; StartScene(); DrawImage(back); DrawString(32, 8, 0, 0xff, 0, "Current Resolution:"); DrawString(140, 8, 0, 0xff, 0, res == 0 ? (IsPAL ? "288p" : "240p") : (IsPAL ? "576i" : "480i")); sprintf(buffer, "%02d:%02d:%02d:%02d", hours, minutes, seconds, frames); DrawString(32, 32, 0xff, 0xff, 0xff, "Elapsed Timer:"); DrawString(140, 32, 0xff, 0xff, 0xff, buffer); if(current) { int i = 0; for(i = 0; i < current; i++) { if(times[i].type == 0) { DrawString(32, 40+i*8, 0xff, 0xff, 0.0, "Switched to"); DrawString(32+12*5, 40+i*8, 0xff, 0xff, 0.0, times[i].res == 0 ? (IsPAL ? "288p" : "240p") : (IsPAL ? "576i" : "480i")); DrawString(32+16*5, 40+i*8, 0xff, 0xff, 0.0, " at:"); } else DrawString(32, 40+i*8, 0.0, 0xff, 0.0, "Viewed at:"); sprintf(buffer, "%02d:%02d:%02d:%02d", times[i].hours, times[i].minutes, times[i].seconds, times[i].frames); DrawString(140, 40+i*8, 0xff, 0xff, 0xff, buffer); if(times[i].type != 0 && i >= 1 && i <= 19) { u16 framesA = 0, framesB = 0, res = 0; timecode len; framesB = ConvertToFrames(×[i]); framesA = ConvertToFrames(×[i - 1]); res = framesB - framesA; ConvertFromFrames(&len, res); sprintf(buffer, "%02d:%02d:%02d:%02d", len.hours, len.minutes, len.seconds, len.frames); DrawString(200, 40+i*8, 0xff, 0.0, 0.0, buffer); } } } EndScene(); ControllerScan(); pressed = Controller_ButtonsDown(0); if ( pressed & PAD_BUTTON_START ) { DrawMenu = 1; HelpData = ALTERNATE; } if (pressed & PAD_BUTTON_B) done = 1; if (pressed & PAD_BUTTON_A) { if(current <= 19) current ++; else current = 1; times[current - 1].frames = frames; times[current - 1].minutes = minutes; times[current - 1].seconds = seconds; times[current - 1].hours = hours; status ++; if(status == 1) { times[current - 1].type = 0; res = !res; times[current - 1].res = res; if(!res) SetVideoMode(IsPAL ? VIDEO_288P : VIDEO_240P); else SetVideoMode(IsPAL ? VIDEO_576I_A264 : VIDEO_480I_A240); CalculateUV(0, 0, dW, dH, back); SetupGX(); } if(status == 2) { times[current - 1].type = 1; times[current - 1].res = res; status = 0; } } } ChangeVideoEnabled = 1; SetVideoMode(oldvmode); SetupGX(); FreeImage(&back); }