mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-12-18 07:11:50 +01:00
- working on new gui
- video patch 1
This commit is contained in:
parent
15d25fbe9d
commit
043e3ee61d
529
source/ngc/gui.cpp
Normal file
529
source/ngc/gui.cpp
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
#include <gccore.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wiiuse/wpad.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#include <pngu/pngu.h>
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
#include "video.h"
|
||||||
|
#include "snes9xGX.h"
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
|
struct sGui Gui;
|
||||||
|
|
||||||
|
GXTexObj texobj_BG, texobj_MENU;
|
||||||
|
u8 texdata_bg[640 * 480 * 4] ATTRIBUTE_ALIGN (32); // stores the blended menu backdrop
|
||||||
|
u8 texdata_menu[640 * 480 * 4] ATTRIBUTE_ALIGN (32); // stores the menu overlay
|
||||||
|
|
||||||
|
extern GXTexObj texobj;
|
||||||
|
extern int vwidth, vheight;
|
||||||
|
extern s16 square[];
|
||||||
|
extern Mtx view;
|
||||||
|
extern int whichfb;
|
||||||
|
extern unsigned int copynow;
|
||||||
|
extern int screenheight;
|
||||||
|
extern unsigned int *xfb[2];
|
||||||
|
extern GXRModeObj *vmode;
|
||||||
|
|
||||||
|
extern FT_Library ftlibrary;
|
||||||
|
extern FT_Face face;
|
||||||
|
extern FT_GlyphSlot slot;
|
||||||
|
extern FT_UInt glyph_index;
|
||||||
|
|
||||||
|
extern int WaitButtonAB ();
|
||||||
|
|
||||||
|
|
||||||
|
// MAIN
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_vert (u8 pos, u8 c, f32 s, f32 t)
|
||||||
|
{
|
||||||
|
GX_Position1x8 (pos);
|
||||||
|
GX_Color1x8 (c);
|
||||||
|
GX_TexCoord2f32 (s, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_square (Mtx v)
|
||||||
|
{
|
||||||
|
Mtx m; // model matrix.
|
||||||
|
Mtx mv; // modelview matrix.
|
||||||
|
|
||||||
|
guMtxIdentity (m);
|
||||||
|
guMtxTransApply (m, m, 0, 0, -100);
|
||||||
|
guMtxConcat (v, m, mv);
|
||||||
|
|
||||||
|
GX_LoadPosMtxImm (mv, GX_PNMTX0);
|
||||||
|
GX_Begin (GX_QUADS, GX_VTXFMT0, 4);
|
||||||
|
draw_vert (0, 0, 0.0, 0.0);
|
||||||
|
draw_vert (1, 0, 1.0, 0.0);
|
||||||
|
draw_vert (2, 0, 1.0, 1.0);
|
||||||
|
draw_vert (3, 0, 0.0, 1.0);
|
||||||
|
GX_End ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_alphasetup ()
|
||||||
|
{
|
||||||
|
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
|
||||||
|
GX_SetAlphaUpdate(GX_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* make BG
|
||||||
|
*
|
||||||
|
* Blend the last rendered emulator screen and the menu backdrop.
|
||||||
|
* Save this as a texture to be loaded later
|
||||||
|
****************************************************************************/
|
||||||
|
void
|
||||||
|
gui_makebg ()
|
||||||
|
{
|
||||||
|
IMGCTX ctx;
|
||||||
|
PNGUPROP imgProp;
|
||||||
|
|
||||||
|
/** Load menu backdrop (either from file or buffer) **/
|
||||||
|
|
||||||
|
ctx = PNGU_SelectImageFromDevice ("bg.png");
|
||||||
|
PNGU_GetImageProperties (ctx, &imgProp);
|
||||||
|
// can check image dimensions here
|
||||||
|
//texdata_bg = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 4);
|
||||||
|
GX_InitTexObj (&texobj_BG, &texdata_bg, 640, 480, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
|
//PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, &texdata_bg, 255);
|
||||||
|
PNGU_DecodeToRGBA8 (ctx, 640, 480, Gui.texmem, 0, 7);
|
||||||
|
Make_Texture_RGBA8 (&texdata_bg, Gui.texmem, 640, 480);
|
||||||
|
PNGU_ReleaseImageContext (ctx);
|
||||||
|
DCFlushRange (&texdata_bg, imgProp.imgWidth * imgProp.imgHeight * 4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
texdata_bg = memalign (32, 640 * 480 * 4);
|
||||||
|
#ifdef HW_RVL
|
||||||
|
// on wii copy from memory
|
||||||
|
memcpy (texdata_bg, (char *) backdrop, 640 * 480 * 2);
|
||||||
|
#else
|
||||||
|
// on gc copy from aram
|
||||||
|
ARAMFetch (texdata_bg, (char *) AR_BACKDROP, 640 * 480 * 2);
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** blend last rendered snes frame and menu backdrop **/
|
||||||
|
|
||||||
|
// draw 640x480 quads
|
||||||
|
int xscale, yscale, xshift, yshift;
|
||||||
|
xshift = yshift = 0;
|
||||||
|
xscale = 320;
|
||||||
|
yscale = 240;
|
||||||
|
square[6] = square[3] = xscale + xshift;
|
||||||
|
square[0] = square[9] = -xscale + xshift;
|
||||||
|
square[4] = square[1] = yscale + yshift;
|
||||||
|
square[7] = square[10] = -yscale + yshift;
|
||||||
|
|
||||||
|
// draw 2 quads
|
||||||
|
|
||||||
|
GX_InvalidateTexAll ();
|
||||||
|
|
||||||
|
// behind (last snes frame)
|
||||||
|
square[2] = square[5] = square[8] = square[11] = 0; // z value
|
||||||
|
GX_InvVtxCache ();
|
||||||
|
GX_LoadTexObj (&texobj, GX_TEXMAP0); // load last rendered snes frame
|
||||||
|
draw_square (view);
|
||||||
|
|
||||||
|
// in front (menu backdrop)
|
||||||
|
square[2] = square[5] = square[8] = square[11] = 1; // z value
|
||||||
|
GX_InvVtxCache ();
|
||||||
|
GX_LoadTexObj (&texobj_BG, GX_TEXMAP0);
|
||||||
|
draw_square (view);
|
||||||
|
|
||||||
|
GX_DrawDone ();
|
||||||
|
|
||||||
|
/* DEBUG -----------
|
||||||
|
// show the output
|
||||||
|
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||||
|
VIDEO_Flush ();
|
||||||
|
copynow = GX_TRUE;
|
||||||
|
#ifdef VIDEO_THREADING
|
||||||
|
// Return to caller, don't waste time waiting for vb
|
||||||
|
LWP_ResumeThread (vbthread);
|
||||||
|
#endif
|
||||||
|
WaitButtonAB();
|
||||||
|
*/
|
||||||
|
|
||||||
|
// load blended image from efb to a texture
|
||||||
|
GX_InitTexObj (&texobj_BG, &texdata_bg, 640, 480, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
|
GX_SetTexCopySrc ( 0,0,640,480 );
|
||||||
|
GX_SetTexCopyDst ( 640, 480, GX_TF_RGBA8, 0 );
|
||||||
|
GX_CopyTex (&texdata_bg, 0); // assuming that the efb is 640x480, which it should be
|
||||||
|
GX_PixModeSync (); // wait until copy has completed
|
||||||
|
DCFlushRange (&texdata_bg, 640 * 480 * 4);
|
||||||
|
|
||||||
|
|
||||||
|
square[2] = square[5] = square[8] = square[11] = 0; // reset z value
|
||||||
|
GX_InvVtxCache ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_clearscreen ()
|
||||||
|
{
|
||||||
|
whichfb ^= 1;
|
||||||
|
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
|
||||||
|
memset ( Gui.texmem, 0, sizeof(Gui.texmem) );
|
||||||
|
Gui.fontcolour = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_draw ()
|
||||||
|
{
|
||||||
|
gui_drawbox (0, 0, 640, 80, 255, 255, 255, 128); // topbar
|
||||||
|
gui_drawbox (0, 370, 640, 480, 255, 255, 255, 128); // bottombar
|
||||||
|
gui_setfontcolour (0,255,0,255);
|
||||||
|
// top bar text
|
||||||
|
setfontsize (32); // 32/24 depending on whether selected or not
|
||||||
|
gui_DrawText (-1, 113, (char *)"Hello World");
|
||||||
|
// main text
|
||||||
|
setfontsize (24);
|
||||||
|
gui_DrawText (-1, 113, (char *)"Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_savescreen ()
|
||||||
|
{
|
||||||
|
FILE* handle;
|
||||||
|
handle = fopen ("out.txt", "wb");
|
||||||
|
fwrite (Gui.texmem, 1, sizeof(Gui.texmem), handle);
|
||||||
|
fclose (handle);
|
||||||
|
|
||||||
|
printf("\nsaved screen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_showscreen ()
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Screen to Texture **/
|
||||||
|
|
||||||
|
GX_InitTexObj (&texobj_MENU, texdata_menu, 640, 480, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
|
Make_Texture_RGBA8 (texdata_menu, Gui.texmem, 640, 480);
|
||||||
|
DCFlushRange (&texdata_menu, 640 * 480 * 4);
|
||||||
|
|
||||||
|
GX_InvalidateTexAll ();
|
||||||
|
|
||||||
|
/** thats nice, but will it blend? **/
|
||||||
|
|
||||||
|
// draw 640x480 quads
|
||||||
|
int xscale, yscale, xshift, yshift;
|
||||||
|
xshift = yshift = 0;
|
||||||
|
xscale = 320;
|
||||||
|
yscale = 240;
|
||||||
|
square[6] = square[3] = xscale + xshift;
|
||||||
|
square[0] = square[9] = -xscale + xshift;
|
||||||
|
square[4] = square[1] = yscale + yshift;
|
||||||
|
square[7] = square[10] = -yscale + yshift;
|
||||||
|
|
||||||
|
// draw 2 quads
|
||||||
|
|
||||||
|
// backdrop
|
||||||
|
square[2] = square[5] = square[8] = square[11] = 0; // z value
|
||||||
|
GX_InvVtxCache ();
|
||||||
|
GX_LoadTexObj (&texobj_BG, GX_TEXMAP0);
|
||||||
|
draw_square (view);
|
||||||
|
|
||||||
|
// menu overlay
|
||||||
|
square[2] = square[5] = square[8] = square[11] = 1; // z value
|
||||||
|
GX_InvVtxCache ();
|
||||||
|
GX_LoadTexObj (&texobj_MENU, GX_TEXMAP0);
|
||||||
|
draw_square (view);
|
||||||
|
|
||||||
|
GX_DrawDone ();
|
||||||
|
|
||||||
|
/** Display **/
|
||||||
|
|
||||||
|
// show the output
|
||||||
|
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||||
|
VIDEO_Flush ();
|
||||||
|
copynow = GX_TRUE;
|
||||||
|
#ifdef VIDEO_THREADING
|
||||||
|
/* Return to caller, don't waste time waiting for vb */
|
||||||
|
LWP_ResumeThread (vbthread);
|
||||||
|
#endif
|
||||||
|
WaitButtonAB();
|
||||||
|
|
||||||
|
square[2] = square[5] = square[8] = square[11] = 0; // z value
|
||||||
|
GX_InvVtxCache ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Make Texture RGBA8
|
||||||
|
*
|
||||||
|
* input: pointer to RGBA data
|
||||||
|
* output: formatted texture data (GX_TF_RGBA8)
|
||||||
|
* code modified from quake wii (thanks :)
|
||||||
|
* todo: fix last few lines (?)
|
||||||
|
****************************************************************************/
|
||||||
|
void
|
||||||
|
Make_Texture_RGBA8 (void * dst_tex, void * src_data, int width, int height)
|
||||||
|
{
|
||||||
|
if ( (width % 4) || (height % 4) ) {
|
||||||
|
printf ("Error: make_texture_rgba8 width/height not multiple of 4");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i, x, y;
|
||||||
|
u8 *pos;
|
||||||
|
|
||||||
|
pos = (u8 *)dst_tex;
|
||||||
|
for (y = 0; y < height; y += 4) // process 4 lines at a time to make rows of tiles
|
||||||
|
{
|
||||||
|
u8* row1 = (u8 *) src_data;
|
||||||
|
u8* row2 = (u8 *) src_data;
|
||||||
|
u8* row3 = (u8 *) src_data;
|
||||||
|
u8* row4 = (u8 *) src_data;
|
||||||
|
row1 += width * 4 * (y + 0); // move 640 pixels x 4 bytes * line #
|
||||||
|
row2 += width * 4 * (y + 1);
|
||||||
|
row3 += width * 4 * (y + 2);
|
||||||
|
row4 += width * 4 * (y + 3);
|
||||||
|
|
||||||
|
for (x = 0; x < width; x += 4) // move across 4 pixels per tile
|
||||||
|
{
|
||||||
|
u8 AR[32];
|
||||||
|
u8 GB[32];
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) // save those 4 pixels of data in texture format
|
||||||
|
{
|
||||||
|
u8* ptr1 = &(row1[(x + i) * 4]); // start at beginning of a row
|
||||||
|
u8* ptr2 = &(row2[(x + i) * 4]); // move across (4 pixels per tile + pixel offset within tile) * 4 bytes per pixel
|
||||||
|
u8* ptr3 = &(row3[(x + i) * 4]);
|
||||||
|
u8* ptr4 = &(row4[(x + i) * 4]);
|
||||||
|
|
||||||
|
AR[(i * 2) + 0] = ptr1[3]; // fill columns of tile with rgba data
|
||||||
|
AR[(i * 2) + 1] = ptr1[0];
|
||||||
|
AR[(i * 2) + 8] = ptr2[3];
|
||||||
|
AR[(i * 2) + 9] = ptr2[0];
|
||||||
|
AR[(i * 2) + 16] = ptr3[3];
|
||||||
|
AR[(i * 2) + 17] = ptr3[0];
|
||||||
|
AR[(i * 2) + 24] = ptr4[3];
|
||||||
|
AR[(i * 2) + 25] = ptr4[0];
|
||||||
|
|
||||||
|
GB[(i * 2) + 0] = ptr1[1];
|
||||||
|
GB[(i * 2) + 1] = ptr1[2];
|
||||||
|
GB[(i * 2) + 8] = ptr2[1];
|
||||||
|
GB[(i * 2) + 9] = ptr2[2];
|
||||||
|
GB[(i * 2) + 16] = ptr3[1];
|
||||||
|
GB[(i * 2) + 17] = ptr3[2];
|
||||||
|
GB[(i * 2) + 24] = ptr4[1];
|
||||||
|
GB[(i * 2) + 25] = ptr4[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pos, AR, sizeof(AR)); // copy over to resulting texture
|
||||||
|
pos += sizeof(AR);
|
||||||
|
memcpy(pos, GB, sizeof(GB));
|
||||||
|
pos += sizeof(GB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_drawbox (int x1, int y1, int width, int height, int r, int g, int b, int a)
|
||||||
|
{
|
||||||
|
u32 colour = ((u8)r << 24) | ((u8)g << 16) | ((u8)b << 8) | (u8)a;
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
u32* memory = (u32*) Gui.texmem;
|
||||||
|
for (j = y1; j<height; j++) {
|
||||||
|
for (i = x1; i<width; i++) {
|
||||||
|
memory[(j*640) + i] = colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* DrawCharacter
|
||||||
|
* Draws a single character on the screen
|
||||||
|
****************************************************************************/
|
||||||
|
static void
|
||||||
|
gui_DrawCharacter (FT_Bitmap * bmp, FT_Int x, FT_Int y)
|
||||||
|
{
|
||||||
|
FT_Int i, j, p, q;
|
||||||
|
FT_Int x_max = x + bmp->width;
|
||||||
|
FT_Int y_max = y + bmp->rows;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
u32* memory = (u32*)Gui.texmem;
|
||||||
|
for (i = x, p = 0; i < x_max; i++, p++)
|
||||||
|
{
|
||||||
|
for (j = y, q = 0; j < y_max; j++, q++)
|
||||||
|
{
|
||||||
|
if (i < 0 || j < 0 || i >= 640 || j >= 480)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
c = bmp->buffer[q * bmp->width + p];
|
||||||
|
|
||||||
|
/*** Cool Anti-Aliasing doesn't work too well at hires on GC ***/
|
||||||
|
if (c > 128)
|
||||||
|
memory[(j * 640) + i] = Gui.fontcolour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* DrawText
|
||||||
|
*
|
||||||
|
* Place the font bitmap on the screen
|
||||||
|
****************************************************************************/
|
||||||
|
void
|
||||||
|
gui_DrawText (int x, int y, char *text)
|
||||||
|
{
|
||||||
|
int px, n;
|
||||||
|
int i;
|
||||||
|
int err;
|
||||||
|
int value, count;
|
||||||
|
|
||||||
|
n = strlen (text);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*** x == -1, auto centre ***/
|
||||||
|
if (x == -1)
|
||||||
|
{
|
||||||
|
value = 0;
|
||||||
|
px = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = 1;
|
||||||
|
px = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (count = value; count < 2; count++)
|
||||||
|
{
|
||||||
|
/*** Draw the string ***/
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
err = FT_Load_Char (face, text[i], FT_LOAD_RENDER);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
printf ("Error %c %d\n", text[i], err);
|
||||||
|
continue; /*** Skip unprintable characters ***/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
gui_DrawCharacter (&slot->bitmap, px + slot->bitmap_left, y - slot->bitmap_top);
|
||||||
|
|
||||||
|
px += slot->advance.x >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
px = (640 - px) >> 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* setfontcolour
|
||||||
|
*
|
||||||
|
* Uses RGB triple values.
|
||||||
|
****************************************************************************/
|
||||||
|
void
|
||||||
|
gui_setfontcolour (int r, int g, int b, int a)
|
||||||
|
{
|
||||||
|
Gui.fontcolour = ((u8)r << 24) | ((u8)g << 16) | ((u8)b << 8) | (u8)a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* DrawLine
|
||||||
|
*
|
||||||
|
* Quick'n'Dirty Bresenham line drawing routine.
|
||||||
|
****************************************************************************/
|
||||||
|
#define SIGN(x) ((x<0)?-1:((x>0)?1:0))
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_DrawLine (int x1, int y1, int x2, int y2, int r, int g, int b, int a)
|
||||||
|
{
|
||||||
|
u32 colour;
|
||||||
|
int i, dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py;
|
||||||
|
int sp;
|
||||||
|
|
||||||
|
u32* memory = (u32*)Gui.texmem;
|
||||||
|
|
||||||
|
colour = ((u8)r << 24) | ((u8)g << 16) | ((u8)b << 8) | (u8)a;
|
||||||
|
|
||||||
|
dx = x2 - x1; /*** Horizontal distance ***/
|
||||||
|
dy = y2 - y1; /*** Vertical distance ***/
|
||||||
|
|
||||||
|
dxabs = abs (dx);
|
||||||
|
dyabs = abs (dy);
|
||||||
|
sdx = SIGN (dx);
|
||||||
|
sdy = SIGN (dy);
|
||||||
|
x = dyabs >> 1;
|
||||||
|
y = dxabs >> 1;
|
||||||
|
px = x1;
|
||||||
|
py = y1;
|
||||||
|
|
||||||
|
sp = (py * 640) + px;
|
||||||
|
|
||||||
|
/*** Plot this pixel ***/
|
||||||
|
memory[sp] = colour;
|
||||||
|
|
||||||
|
if (dxabs >= dyabs) /*** Mostly horizontal ***/
|
||||||
|
{
|
||||||
|
for (i = 0; i < dxabs; i++)
|
||||||
|
{
|
||||||
|
y += dyabs;
|
||||||
|
if (y >= dxabs)
|
||||||
|
{
|
||||||
|
y -= dxabs;
|
||||||
|
py += sdy;
|
||||||
|
}
|
||||||
|
|
||||||
|
px += sdx;
|
||||||
|
sp = (py * 640) + px;
|
||||||
|
memory[sp] = colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < dyabs; i++)
|
||||||
|
{
|
||||||
|
x += dxabs;
|
||||||
|
if (x >= dyabs)
|
||||||
|
{
|
||||||
|
x -= dyabs;
|
||||||
|
px += sdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
py += sdy;
|
||||||
|
sp = (py * 640) + px;
|
||||||
|
memory[sp] = colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
/** draw menu, etc **/
|
||||||
|
// - draw topbar, bottombar
|
||||||
|
// - draw icons
|
||||||
|
// - draw bar text
|
||||||
|
|
||||||
|
// draw main text
|
||||||
|
|
||||||
|
/** make textures **/
|
||||||
|
// - load background texture
|
||||||
|
// - draw onto quad
|
||||||
|
// - make foreground texture
|
||||||
|
// - draw onto quad
|
||||||
|
|
||||||
|
/** render image **/
|
||||||
|
|
||||||
|
/** update framebuffer **/
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
// EOF
|
36
source/ngc/gui.h
Normal file
36
source/ngc/gui.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __GUI_H__
|
||||||
|
#define __GUI_H__
|
||||||
|
|
||||||
|
#include <gccore.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct sGui {
|
||||||
|
u8 texmem[640 * 480 * 4] ATTRIBUTE_ALIGN (32); // rgba8 - working draw area
|
||||||
|
int currmenu;
|
||||||
|
int prevmenu;
|
||||||
|
u32 fontcolour;
|
||||||
|
int screenheight;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct sGui Gui;
|
||||||
|
|
||||||
|
// Prototypes
|
||||||
|
void gui_alphasetup ();
|
||||||
|
void gui_makebg ();
|
||||||
|
void Make_Texture_RGBA8 (void * dst_tex, void * src_data, int width, int height);
|
||||||
|
void gui_drawbox (int x1, int y1, int width, int height, int r, int g, int b, int a);
|
||||||
|
void gui_DrawText (int x, int y, char *text);
|
||||||
|
void gui_setfontcolour (int r, int g, int b, int a);
|
||||||
|
void gui_DrawLine (int x1, int y1, int x2, int y2, int r, int g, int b, int a);
|
||||||
|
void gui_clearscreen ();
|
||||||
|
void gui_draw ();
|
||||||
|
void gui_showscreen ();
|
||||||
|
|
||||||
|
void gui_savescreen ();
|
||||||
|
|
||||||
|
// external functions
|
||||||
|
extern void setfontsize (int pixelsize);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
1132
source/ngc/pngu.c
Normal file
1132
source/ngc/pngu.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -202,6 +202,8 @@ extern "C" {
|
|||||||
#include "fileop.h"
|
#include "fileop.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
unsigned long ARAM_ROMSIZE = 0;
|
unsigned long ARAM_ROMSIZE = 0;
|
||||||
int ConfigRequested = 0;
|
int ConfigRequested = 0;
|
||||||
extern int FrameTimer;
|
extern int FrameTimer;
|
||||||
@ -288,6 +290,13 @@ emulate ()
|
|||||||
NGCFreezeGame ( GCSettings.SaveMethod, SILENT );
|
NGCFreezeGame ( GCSettings.SaveMethod, SILENT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GUI Stuff
|
||||||
|
gui_makebg ();
|
||||||
|
gui_clearscreen();
|
||||||
|
gui_draw ();
|
||||||
|
gui_showscreen ();
|
||||||
|
//gui_savescreen ();
|
||||||
|
|
||||||
mainmenu (3); // go to game menu
|
mainmenu (3); // go to game menu
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "aram.h"
|
#include "aram.h"
|
||||||
#include "snes9xGX.h"
|
#include "snes9xGX.h"
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
/*** Snes9x GFX Buffer ***/
|
/*** Snes9x GFX Buffer ***/
|
||||||
static unsigned char snes9xgfx[1024 * 512 * 2];
|
static unsigned char snes9xgfx[1024 * 512 * 2];
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ unsigned int copynow = GX_FALSE;
|
|||||||
static unsigned char gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
static unsigned char gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
||||||
static unsigned char texturemem[TEX_WIDTH * (TEX_HEIGHT + 8)] ATTRIBUTE_ALIGN (32);
|
static unsigned char texturemem[TEX_WIDTH * (TEX_HEIGHT + 8)] ATTRIBUTE_ALIGN (32);
|
||||||
GXTexObj texobj;
|
GXTexObj texobj;
|
||||||
static Mtx view;
|
Mtx view;
|
||||||
int vwidth, vheight, oldvwidth, oldvheight;
|
int vwidth, vheight, oldvwidth, oldvheight;
|
||||||
|
|
||||||
u32 FrameTimer = 0;
|
u32 FrameTimer = 0;
|
||||||
@ -170,8 +172,8 @@ GXRModeObj TV_224p =
|
|||||||
256, // fbWidth
|
256, // fbWidth
|
||||||
224, // efbHeight
|
224, // efbHeight
|
||||||
224, // xfbHeight
|
224, // xfbHeight
|
||||||
(VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
|
(VI_MAX_WIDTH_NTSC - 640)/2, // viXOrigin
|
||||||
(VI_MAX_HEIGHT_NTSC - 480)/2 + 8, // viYOrigin // +8 if we want to maintain rendered pixel aspect ratio (not 4:3)
|
(VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
|
||||||
640, // viWidth
|
640, // viWidth
|
||||||
480, // viHeight
|
480, // viHeight
|
||||||
VI_XFBMODE_SF, // xFBmode
|
VI_XFBMODE_SF, // xFBmode
|
||||||
@ -301,8 +303,6 @@ copy_to_xfb (u32 arg)
|
|||||||
|
|
||||||
if (copynow == GX_TRUE)
|
if (copynow == GX_TRUE)
|
||||||
{
|
{
|
||||||
//GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
||||||
//GX_SetColorUpdate (GX_TRUE);
|
|
||||||
GX_CopyDisp (xfb[whichfb], GX_TRUE);
|
GX_CopyDisp (xfb[whichfb], GX_TRUE);
|
||||||
GX_Flush ();
|
GX_Flush ();
|
||||||
copynow = GX_FALSE;
|
copynow = GX_FALSE;
|
||||||
@ -341,14 +341,6 @@ draw_init ()
|
|||||||
memset (&view, 0, sizeof (Mtx));
|
memset (&view, 0, sizeof (Mtx));
|
||||||
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
||||||
GX_LoadPosMtxImm (view, GX_PNMTX0);
|
GX_LoadPosMtxImm (view, GX_PNMTX0);
|
||||||
|
|
||||||
GX_InvalidateTexAll ();
|
|
||||||
GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
||||||
|
|
||||||
/* original video mode: force filtering OFF */
|
|
||||||
if (!GCSettings.render)
|
|
||||||
GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -413,6 +405,8 @@ StartGX ()
|
|||||||
GX_SetDispCopyGamma (GX_GM_1_0);
|
GX_SetDispCopyGamma (GX_GM_1_0);
|
||||||
GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
|
GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||||
GX_SetColorUpdate (GX_TRUE);
|
GX_SetColorUpdate (GX_TRUE);
|
||||||
|
|
||||||
|
gui_alphasetup ();
|
||||||
|
|
||||||
// guPerspective (p, 60, 1.33F, 10.0F, 1000.0F);
|
// guPerspective (p, 60, 1.33F, 10.0F, 1000.0F);
|
||||||
// GX_LoadProjectionMtx (p, GX_PERSPECTIVE);
|
// GX_LoadProjectionMtx (p, GX_PERSPECTIVE);
|
||||||
@ -533,6 +527,12 @@ InitGCVideo ()
|
|||||||
vmode_60hz = 1;
|
vmode_60hz = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for progressive scan
|
||||||
|
if (vmode->viTVMode == VI_TVMODE_NTSC_PROG) {
|
||||||
|
TV_239p.viTVMode = TV_478i.viTVMode = TV_224p.viTVMode = TV_448i.viTVMode = VI_TVMODE_NTSC_PROG;
|
||||||
|
TV_239p.xfbMode = TV_478i.xfbMode = TV_224p.xfbMode = TV_448i.xfbMode = VI_XFBMODE_SF;
|
||||||
|
}
|
||||||
|
|
||||||
VIDEO_Configure (vmode);
|
VIDEO_Configure (vmode);
|
||||||
|
|
||||||
@ -588,7 +588,10 @@ ResetVideo_Emu ()
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<4; i++) {
|
for (i=0; i<4; i++) {
|
||||||
if (tvmodes[i]->efbHeight == vheight) break;
|
if (tvmodes[i]->efbHeight == vheight) {
|
||||||
|
tvmodes[i]->fbWidth = vwidth; // update width - some games are 512x224 (super pang)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rmode = tvmodes[i];
|
rmode = tvmodes[i];
|
||||||
}
|
}
|
||||||
@ -620,11 +623,16 @@ ResetVideo_Emu ()
|
|||||||
guOrtho(p, rmode->efbHeight/2, -(rmode->efbHeight/2), -(rmode->fbWidth/2), rmode->fbWidth/2, 10, 1000); // matrix, t, b, l, r, n, f
|
guOrtho(p, rmode->efbHeight/2, -(rmode->efbHeight/2), -(rmode->fbWidth/2), rmode->fbWidth/2, 10, 1000); // matrix, t, b, l, r, n, f
|
||||||
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
|
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
|
||||||
|
|
||||||
|
// clear snes9x render screen
|
||||||
|
memset (snes9xgfx, 0, 1024 * 512 * 2);
|
||||||
|
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
char* msg = (char*) malloc(256*sizeof(char));
|
char* msg = (char*) malloc(256*sizeof(char));
|
||||||
sprintf (msg, (char*)"Interlaced: %i, vwidth: %d, vheight: %d, fb_W: %u, efb_H: %u", IPPU.Interlace, vwidth, vheight, rmode->fbWidth, rmode->efbHeight);
|
sprintf (msg, (char*)"Interlaced: %i, vwidth: %d, vheight: %d, fb_W: %u, efb_H: %u", IPPU.Interlace, vwidth, vheight, rmode->fbWidth, rmode->efbHeight);
|
||||||
S9xMessage (0, 0, msg);
|
S9xMessage (0, 0, msg);
|
||||||
free(msg);
|
free(msg);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,7 +740,7 @@ update_video (int width, int height)
|
|||||||
|
|
||||||
whichfb ^= 1;
|
whichfb ^= 1;
|
||||||
|
|
||||||
if ((oldvheight != vheight) || (oldvwidth != vwidth) // if rendered width/height changes
|
if ((oldvheight != vheight) || (oldvwidth != vwidth) // if rendered width/height changes
|
||||||
|| (CheckVideo && (IPPU.RenderedFramesCount != prevRenderedFrameCount)) // or if we get back from the menu, and have rendered at least 1 frame
|
|| (CheckVideo && (IPPU.RenderedFramesCount != prevRenderedFrameCount)) // or if we get back from the menu, and have rendered at least 1 frame
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -765,12 +773,21 @@ update_video (int width, int height)
|
|||||||
draw_init ();
|
draw_init ();
|
||||||
|
|
||||||
GX_InvVtxCache ();
|
GX_InvVtxCache ();
|
||||||
|
GX_InvalidateTexAll ();
|
||||||
|
|
||||||
|
GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
|
|
||||||
|
/* original video mode: force filtering OFF */
|
||||||
|
if (!GCSettings.render)
|
||||||
|
GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1);
|
||||||
|
|
||||||
|
/*
|
||||||
// DEBUG
|
// DEBUG
|
||||||
char* msg = (char*) malloc(256*sizeof(char));
|
char* msg = (char*) malloc(256*sizeof(char));
|
||||||
sprintf (msg, (char*)"xscale: %d, yscale: %d", xscale, yscale);
|
sprintf (msg, (char*)"xscale: %d, yscale: %d", xscale, yscale);
|
||||||
S9xMessage (0, 0, msg);
|
S9xMessage (0, 0, msg);
|
||||||
free(msg);
|
free(msg);
|
||||||
|
*/
|
||||||
|
|
||||||
//GX_SetViewport (0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1);
|
//GX_SetViewport (0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user