mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-24 18:21:50 +01:00
GUI: added TEV color channel support (transparency, colored font), added basic menu effects (fadein/out)
This commit is contained in:
parent
f96ba2ceaf
commit
148391d681
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 ***/
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user