GUI: added TEV color channel support (transparency, colored font), added basic menu effects (fadein/out)

This commit is contained in:
ekeeke31 2009-04-01 07:37:54 +00:00
parent f96ba2ceaf
commit 148391d681
5 changed files with 177 additions and 38 deletions

View File

@ -87,7 +87,7 @@ int FONT_Init(void)
return 0;
}
static void DrawChar(unsigned char c, int xpos, int ypos, int size)
static void DrawChar(unsigned char c, int xpos, int ypos, int size, GXColor color)
{
s32 width;
@ -108,12 +108,16 @@ static void DrawChar(unsigned char c, int xpos, int ypos, int size)
/* GX rendering */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(xpos, ypos - size);
GX_Color4u8(color.r, color.g, color.b, 0xff);
GX_TexCoord2f32(0.0, 0.0);
GX_Position2s16(xpos + width, ypos - size);
GX_Color4u8(color.r, color.g, color.b, 0xff);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(xpos + width, ypos);
GX_Color4u8(color.r, color.g, color.b, 0xff);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(xpos, ypos);
GX_Color4u8(color.r, color.g, color.b, 0xff);
GX_TexCoord2f32(0.0, 1.0);
GX_End ();
GX_DrawDone();
@ -125,7 +129,7 @@ void write_font(int x, int y, char *string)
int ox = x;
while (*string && (x < (ox + back_framewidth)))
{
DrawChar(*string, x -(vmode->fbWidth/2), y-(vmode->efbHeight/2),fontHeader->cell_height);
DrawChar(*string, x -(vmode->fbWidth/2), y-(vmode->efbHeight/2),fontHeader->cell_height,(GXColor)WHITE);
x += font_size[(u8)*string];
string++;
}
@ -159,7 +163,7 @@ void FONT_alignLeft(char *string, int size, int x, int y)
while (*string)
{
DrawChar(*string, x, y, size);
DrawChar(*string, x, y, size,(GXColor)WHITE);
x += (font_size[(u8)*string++] * size) / fheight;
}
}
@ -177,7 +181,7 @@ void FONT_alignRight(char *string, int size, int x, int y)
while (*string)
{
DrawChar(*string, x, y, size);
DrawChar(*string, x, y, size,(GXColor)WHITE);
x += (font_size[(u8)*string++] * size) / fheight;
}
}
@ -195,7 +199,7 @@ void FONT_writeCenter(char *string, int size, int x1, int x2, int y)
while (*string)
{
DrawChar(*string, x1, y, size);
DrawChar(*string, x1, y, size,(GXColor)WHITE);
x1 += (font_size[(u8)*string++] * size) / fheight;
}
}
@ -453,12 +457,16 @@ void DrawTexture(png_texture *texture, int x, int y, int w, int h)
/* Draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();

View File

@ -25,8 +25,8 @@
#ifndef _FONT_H
#define _FONT_H
#define BLACK {0,0,0,255}
#define WHITE {255,255,255,255}
#define BLACK {0,0,0,0xff}
#define WHITE {0xff,0xff,0xff,0xff}
typedef struct
{

View File

@ -663,6 +663,11 @@ static void menu_draw(gui_menu *menu)
/* clear EFB */
ClearScreen ((GXColor)BLACK);
if ((menu == &menu_main) && genromsize)
{
ogc_video_caption(128);
}
/* draw background image */
image = menu->background;
if (image) DrawTexture(image->texture,image->x,image->y,image->w,image->h);
@ -742,6 +747,93 @@ static void menu_draw(gui_menu *menu)
SetScreen ();
}
static void menu_fade(gui_menu *menu, u8 speed, u8 out)
{
int offset;
int yfinal[3];
gui_image *image[3];
menu_initialize(menu);
offset = 0;
yfinal[0] = 0;
yfinal[1] = 0;
yfinal[2] = 0;
/* logo (top or bottom) */
image[2] = menu->logo;
/* Top banner */
image[0] = menu->frames[0];
if (image[0])
{
/* intial offset */
offset = image[0]->y + image[0]->h;
/* final ypos */
yfinal[0] = out ? (-image[0]->h) : (image[0]->y);
if (image[2] && !image[1]) yfinal[2] = out ? (image[2]->y - offset) : image[2]->y;
}
/* Bottom banner */
image[1] = menu->frames[1];
if (image[1])
{
if ((480 + image[1]->h - image[1]->y) > offset)
{
/* intial offset */
offset = 480 - image[1]->y;
/* final ypos */
yfinal[1] = out ? 480 : (image[1]->y);
if (image[2] && !image[0]) yfinal[2] = out ? (image[2]->y + offset) : image[2]->y;
}
}
/* alpha step */
u16 alpha = out ? 128 : 255;
int alpha_step = out ? (128/offset) : -(128/offset);
/* loop until final position is reeached */
while (offset > 0)
{
/* clear EFB */
ClearScreen ((GXColor)BLACK);
if ((menu == &menu_main) && genromsize)
{
ogc_video_caption(alpha);
}
/* draw top banner + logo */
if (image[out])
{
DrawTexture(image[out]->texture,image[out]->x,yfinal[out]-offset,image[out]->w,image[out]->h);
if (image[2] && !image[out^1]) DrawTexture(image[2]->texture,image[2]->x,yfinal[2]-offset,image[2]->w,image[2]->h);
}
/* draw bottom banner + logo */
if (image[out^1])
{
DrawTexture(image[out^1]->texture,image[out^1]->x,yfinal[out^1]+offset,image[out^1]->w,image[out^1]->h);
if (image[2] && !image[out]) DrawTexture(image[2]->texture,image[2]->x,image[2]->y+offset,image[2]->w,image[2]->h);
}
/* update offset */
offset -= speed;
/* update alpha */
alpha += alpha_step;
if (alpha > 255) alpha = 255;
/* copy EFB to XFB */
SetScreen ();
}
if (!out) menu_draw(menu);
menu_delete(menu);
}
static int menu_callback(gui_menu *menu)
{
u16 p;
@ -2030,6 +2122,9 @@ void MainMenu (u32 fps)
VIDEO_SetPostRetraceCallback(menu_updateInputs);
/* basic fade-in effect */
menu_fade(m,10,0);
while (quit == 0)
{
/* crccheck = crc32 (0, &sram.sram[0], 0x10000);
@ -2045,7 +2140,12 @@ void MainMenu (u32 fps)
{
case -1: /*** Button B ***/
case 0: /*** Play Game ***/
if (genromsize) quit = 1;
if (genromsize)
{
/* basic fade-out effect */
menu_fade(m,10,1);
quit = 1;
}
break;
case 1: /*** Load ROM Menu ***/

View File

@ -338,13 +338,8 @@ static void gxStart(void)
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_SetCullMode(GX_CULL_NONE);
GX_SetDispCopyGamma(GX_GM_1_0);
GX_SetBlendMode(GX_BM_BLEND,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR);
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL);
GX_SetNumTexGens(1);
GX_SetNumChans(0);
/* Modelview */
Mtx view;
@ -358,31 +353,49 @@ static void gxStart(void)
memset (texturemem, 0, TEX_SIZE);
}
/* Reset GX vertex attributes */
static void gxResetVtx(bool isMenu)
/* Reset GX rendering */
static void gxResetRendering(bool isMenu)
{
GX_ClearVtxDesc();
/* Set Position Params (quad aspect ratio) */
if (isMenu)
{
/* menu uses direct position */
/* GX menu (uses direct positionning, alpha blending & color channel) */
GX_SetBlendMode(GX_BM_BLEND,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxDesc (GX_VA_CLR0, GX_DIRECT);
/*
Color.out = Color.rasterized*Color.texture
Alpha.out = Alpha.rasterized*Alpha.texture
*/
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_SetNumTexGens(1);
GX_SetNumChans(1);
}
else
{
/* emulation uses an indexed array for easy control on aspect ratio */
/* video emulation (uses array positionning, no alpha blending, no color channel) */
GX_SetBlendMode(GX_BM_NONE,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetArray(GX_VA_POS, square, 3 * sizeof (s16));
/*
Color.out = Color.texture
Alpha.out = Alpha.texture
*/
GX_SetTevOp (GX_TEVSTAGE0, GX_REPLACE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL);
GX_SetNumTexGens(1);
GX_SetNumChans(0);
}
/* Set Tex Coord Params */
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_Flush();
}
@ -551,7 +564,7 @@ void ogc_video__stop(void)
VIDEO_WaitVSync();
/* reset GX */
gxResetVtx(GX_TRUE);
gxResetRendering(GX_TRUE);
gxResetView(vmode);
}
@ -609,21 +622,42 @@ void ogc_video__start(void)
/* apply changes on next video update */
bitmap.viewport.changed = 1;
/* reset GX */
gxResetVtx(GX_FALSE);
/* reset GX rendering */
gxResetRendering(GX_FALSE);
}
static GXTexObj texobj;
static u32 vwidth,vheight;
void ogc_video_caption(void)
void ogc_video_caption(u8 alpha)
{
gxResetVtx(0);
GXTexObj texobj;
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_LoadTexObj(&texobj, GX_TEXMAP0);
GX_InvalidateTexAll();
draw_square();
/* reset Scaler (display screenshot in background) */
s32 x = config.overscan ? -352 : -320;
s32 y = config.overscan ? -240 : -224;
s32 w = config.overscan ? 704 : 640;
s32 h = config.overscan ? 480 : 448;
/* Draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
gxResetVtx(1);
}
/* GX render update */
@ -635,8 +669,8 @@ void ogc_video__update(void)
bitmap.viewport.changed = 0;
/* update texture size */
u32 vwidth = bitmap.viewport.w + 2 * bitmap.viewport.x;
u32 vheight = bitmap.viewport.h + 2 * bitmap.viewport.y;
vwidth = bitmap.viewport.w + 2 * bitmap.viewport.x;
vheight = bitmap.viewport.h + 2 * bitmap.viewport.y;
/* special cases */
if (config.render && interlaced) vheight = vheight << 1;
@ -647,6 +681,7 @@ void ogc_video__update(void)
vheight = (vheight >> 2) << 2;
/* initialize texture object */
GXTexObj texobj;
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
/* configure texture filtering */
@ -736,12 +771,8 @@ void ogc_video__init(void)
TV60hz_480i.viTVMode = VI_TVMODE_EURGB60_INT;
config.tv_mode = 1;
/* display should be centered vertically (borders) */
/* use harwdare vertical scaling to fill screen */
vmode = &TVPal574IntDfScale;
vmode->xfbHeight = 480;
vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - 480)/2;
vmode->viHeight = 480;
break;
case VI_NTSC: /* 480 lines (NTSC 60hz) */
@ -797,7 +828,7 @@ void ogc_video__init(void)
/* Initialize GX */
gxStart();
gxResetVtx(GX_TRUE);
gxResetRendering(GX_TRUE);
gxResetView(vmode);
/* Initialize Font */

View File

@ -34,7 +34,7 @@ extern void ogc_video__init(void);
extern void ogc_video__start(void);
extern void ogc_video__stop(void);
extern void ogc_video__update(void);
extern void ogc_video_caption(void);
extern void ogc_video_caption(u8 alpha);
extern void gxResetCamera(f32 angle);