mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-02-26 16:13:37 +01:00
[Gamecube/Wii]
- drastically reduced memory usage (free remaining memory can now be checked under "exit" options) - improved GX video rendering (fixes screen tearing when VSYNC is disabled)
This commit is contained in:
parent
10e5a924df
commit
e7754fd7cb
@ -3,7 +3,7 @@
|
||||
*
|
||||
* ROM File Browser
|
||||
*
|
||||
* Copyright Eke-Eke (2009-2013)
|
||||
* Copyright Eke-Eke (2009-2014)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -290,25 +290,13 @@ int FileSelector(int type)
|
||||
/* Hide all cartridge labels */
|
||||
for (i=0; i<FILETYPE_MAX; i++)
|
||||
{
|
||||
bg_filesel[9+i].data = NULL;
|
||||
bg_filesel[9+i].state &= ~IMAGE_VISIBLE;
|
||||
}
|
||||
|
||||
/* Cartridge type */
|
||||
if (type < 0)
|
||||
/* Select cartridge type */
|
||||
if (type >= 0)
|
||||
{
|
||||
/* Recent game list -> select all cartridge type */
|
||||
for (i=0; i<FILETYPE_MAX; i++)
|
||||
{
|
||||
bg_filesel[9+i].data = Cart_png[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear all cartridges type */
|
||||
for (i=0; i<FILETYPE_MAX; i++)
|
||||
{
|
||||
bg_filesel[9+i].data = NULL;
|
||||
}
|
||||
|
||||
/* Select cartridge type */
|
||||
bg_filesel[9 + type].data = Cart_png[type];
|
||||
@ -324,7 +312,7 @@ int FileSelector(int type)
|
||||
/* ROM file snapshot/database */
|
||||
if (old != selection)
|
||||
{
|
||||
/* close any existing texture first */
|
||||
/* close any screenshot texture first */
|
||||
gxTextureClose(&bg_filesel[8].texture);
|
||||
bg_filesel[8].state &= ~IMAGE_VISIBLE;
|
||||
|
||||
@ -336,20 +324,26 @@ int FileSelector(int type)
|
||||
/* recent game list -> variable game types */
|
||||
if (type < 0)
|
||||
{
|
||||
/* hide all cartridge labels */
|
||||
for (i=0; i<FILETYPE_MAX; i++)
|
||||
{
|
||||
bg_filesel[9+i].state &= ~IMAGE_VISIBLE;
|
||||
}
|
||||
|
||||
/* detect cartridge type */
|
||||
/* check if game type has changed */
|
||||
type = history.entries[selection].filetype;
|
||||
if (!(bg_filesel[9 + type].state & IMAGE_VISIBLE))
|
||||
{
|
||||
/* hide all cartridge labels */
|
||||
for (i=0; i<FILETYPE_MAX; i++)
|
||||
{
|
||||
gxTextureClose(&bg_filesel[9 + i].texture);
|
||||
bg_filesel[9 + i].state &= ~IMAGE_VISIBLE;
|
||||
}
|
||||
|
||||
/* show selected cartridge label */
|
||||
bg_filesel[9 + type].state |= IMAGE_VISIBLE;
|
||||
/* open cartridge label texture */
|
||||
bg_filesel[9 + type].texture = gxTextureOpenPNG(Cart_png[type],0);
|
||||
|
||||
/* default screenshot file path */
|
||||
sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename);
|
||||
/* show selected cartridge label */
|
||||
bg_filesel[9 + type].state |= IMAGE_VISIBLE;
|
||||
|
||||
/* default screenshot file path */
|
||||
sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename);
|
||||
}
|
||||
|
||||
/* restore recent type flag */
|
||||
type = -1;
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* ROM File Browser
|
||||
*
|
||||
* Copyright Eke-Eke (2009-2013)
|
||||
* Copyright Eke-Eke (2009-2014)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
13
gx/gui/gui.c
13
gx/gui/gui.c
@ -3,7 +3,7 @@
|
||||
*
|
||||
* generic GUI Engine (using GX rendering)
|
||||
*
|
||||
* Copyright Eke-Eke (2009-2010)
|
||||
* Copyright Eke-Eke (2009-2014)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -1018,7 +1018,7 @@ void GUI_TextWindow(gui_menu *parent, char *title, char items[][64], u8 nb_items
|
||||
}
|
||||
|
||||
/* Option Window (returns selected item) */
|
||||
int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items)
|
||||
int GUI_OptionWindow(gui_menu *parent, char *title, char *infos, char *items[], u8 nb_items)
|
||||
{
|
||||
int i, ret, quit = 0;
|
||||
int old, selected = 0;
|
||||
@ -1075,6 +1075,9 @@ int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items)
|
||||
FONT_writeCenter(items[i],18,xpos,xpos+w,ypos+i*(20 + h)+(h + 18)/2- yoffset,(GXColor)DARK_GREY);
|
||||
}
|
||||
|
||||
/* draw infos */
|
||||
FONT_writeCenter(infos,16,xwindow,xwindow+window->width,ywindow+window->height-16-yoffset,(GXColor)WHITE);
|
||||
|
||||
/* update display */
|
||||
gxSetScreen();
|
||||
|
||||
@ -1095,6 +1098,9 @@ int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items)
|
||||
/* draw title */
|
||||
FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20,(GXColor)WHITE);
|
||||
|
||||
/* draw infos */
|
||||
FONT_writeCenter(infos,16,xwindow,xwindow+window->width,ywindow+window->height-16,(GXColor)WHITE);
|
||||
|
||||
/* draw buttons + text */
|
||||
for (i=0; i<nb_items; i++)
|
||||
{
|
||||
@ -1208,6 +1214,9 @@ int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items)
|
||||
/* draw title */
|
||||
FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20-yoffset,(GXColor)WHITE);
|
||||
|
||||
/* draw infos */
|
||||
FONT_writeCenter(infos,16,xwindow,xwindow+window->width,ywindow+window->height-16-yoffset,(GXColor)WHITE);
|
||||
|
||||
/* draw buttons + text */
|
||||
for (i=0; i<nb_items; i++)
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* generic GUI Engine (using GX rendering)
|
||||
*
|
||||
* Copyright Eke-Eke (2009-2010)
|
||||
* Copyright Eke-Eke (2009-2014)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -231,7 +231,7 @@ extern void GUI_SlideMenuTitle(gui_menu *m, int title_offset);
|
||||
extern int GUI_UpdateMenu(gui_menu *menu);
|
||||
extern int GUI_RunMenu(gui_menu *menu);
|
||||
extern void GUI_TextWindow(gui_menu *parent, char *title, char items[][64], u8 nb_items, u8 fontsize);
|
||||
extern int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items);
|
||||
extern int GUI_OptionWindow(gui_menu *parent, char *title, char *infos, char *items[], u8 nb_items);
|
||||
extern void GUI_OptionBox(gui_menu *parent, optioncallback cb, char *title, void *option, float step, float min, float max, u8 type);
|
||||
extern void GUI_OptionBox2(gui_menu *parent, char *text_1, char *text_2, s16 *option_1, s16 *option_2, s16 step, s16 min, s16 max);
|
||||
extern void GUI_MsgBoxOpen(char *title, char *msg, bool throbber);
|
||||
|
@ -799,8 +799,6 @@ static void prefmenu ()
|
||||
dvd[6] = 0;
|
||||
dvd[7] = 1;
|
||||
while (dvd[7] & 1);
|
||||
dvd[0] = 0x14;
|
||||
dvd[1] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -854,7 +852,7 @@ static void soundmenu ()
|
||||
int16 lp_range = (config.lp_range * 100 + 0xffff) / 0x10000;
|
||||
sprintf (items[7].text, "Filtering: LOW-PASS");
|
||||
sprintf (items[8].text, "Low-Pass Rate: %d %%", lp_range);
|
||||
strcpy (items[9].comment, "Adjust Low Pass filter");
|
||||
strcpy (items[8].comment, "Adjust Low Pass filter");
|
||||
m->max_items = 9;
|
||||
}
|
||||
else
|
||||
@ -3139,7 +3137,6 @@ static int loadgamemenu ()
|
||||
static void showrominfo (void)
|
||||
{
|
||||
char items[15][64];
|
||||
char msg[32];
|
||||
|
||||
/* fill ROM infos */
|
||||
sprintf (items[0], "Console Type: %s", rominfo.consoletype);
|
||||
@ -3219,28 +3216,7 @@ static void showrominfo (void)
|
||||
else if (region_code == REGION_JAPAN_PAL)
|
||||
sprintf (items[14], "Region Code: %s (JPN-PAL)", rominfo.country);
|
||||
|
||||
#ifdef USE_BENCHMARK
|
||||
/* ROM benchmark */
|
||||
if (!config.ntsc)
|
||||
{
|
||||
int frames = 0;
|
||||
u64 start = gettime();
|
||||
do
|
||||
{
|
||||
system_frame(0);
|
||||
audio_update();
|
||||
}
|
||||
while (++frames < 300);
|
||||
u64 end = gettime();
|
||||
sprintf(msg,"ROM Header Info (%d fps)", (300 * 1000000) / diff_usec(start,end));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
strcpy(msg,"ROM Header Info");
|
||||
}
|
||||
|
||||
GUI_TextWindow(&menu_main, msg, items, 15, 15);
|
||||
GUI_TextWindow(&menu_main, "ROM Header Info", items, 15, 15);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@ -3307,6 +3283,8 @@ static void showcredits(void)
|
||||
|
||||
static void exitmenu(void)
|
||||
{
|
||||
char title[64];
|
||||
char infos[64];
|
||||
char *items[3] =
|
||||
{
|
||||
"View Credits",
|
||||
@ -3318,11 +3296,23 @@ static void exitmenu(void)
|
||||
"Return to Loader",
|
||||
};
|
||||
|
||||
#ifdef HW_RVL
|
||||
extern u8 __Arena2Lo[];
|
||||
sprintf(title, "%s (IOS %d)", VERSION, IOS_GetVersion());
|
||||
if ((u32)SYS_GetArena2Lo() > (u32)__Arena2Lo)
|
||||
sprintf(infos, "%d bytes free (MEM2)", (u32)SYS_GetArena2Size());
|
||||
else
|
||||
sprintf(infos, "%d bytes free (MEM1)", (u32)SYS_GetArena1Size());
|
||||
#else
|
||||
sprintf(title, "%s (GCN)", VERSION);
|
||||
sprintf(infos, "%d bytes free", (u32)SYS_GetArenaSize());
|
||||
#endif
|
||||
|
||||
/* check if loader stub exists */
|
||||
int maxitems = reload ? 3 : 2;
|
||||
|
||||
/* display option window */
|
||||
switch (GUI_OptionWindow(&menu_main, osd_version, items, maxitems))
|
||||
switch (GUI_OptionWindow(&menu_main, title, infos, items, maxitems))
|
||||
{
|
||||
case 0: /* credits */
|
||||
GUI_DeleteMenu(&menu_main);
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX audio support
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006)
|
||||
* Copyright Eke-Eke (2007-2014), based on original work from Softdev (2006)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -122,39 +122,41 @@ void gx_audio_Shutdown(void)
|
||||
***/
|
||||
int gx_audio_Update(void)
|
||||
{
|
||||
if (!audioWait)
|
||||
if (audioWait && audioStarted)
|
||||
{
|
||||
/* Current available soundbuffer */
|
||||
s16 *sb = (s16 *)(soundbuffer[mixbuffer]);
|
||||
|
||||
/* Retrieve audio samples (size must be multiple of 32 bytes) */
|
||||
int size = audio_update(sb) * 4;
|
||||
|
||||
/* Update DMA settings */
|
||||
DCFlushRange((void *)sb, size);
|
||||
AUDIO_InitDMA((u32) sb, size);
|
||||
mixbuffer = (mixbuffer + 1) % SOUND_BUFFER_NUM;
|
||||
audioWait = audioSync;
|
||||
|
||||
/* Start Audio DMA */
|
||||
/* this is called once to kick-off DMA from external memory to audio interface */
|
||||
/* DMA operation is automatically restarted when all samples have been sent. */
|
||||
/* If DMA settings are not updated at that time, previous sound buffer will be used. */
|
||||
/* Therefore we need to make sure frame emulation is completed before current DMA is */
|
||||
/* completed, by synchronizing frame emulation with DMA start and also by syncing it */
|
||||
/* with Video Interrupt and outputing a suitable number of samples per frame. */
|
||||
if (!audioStarted)
|
||||
{
|
||||
/* restart audio DMA */
|
||||
AUDIO_StopDMA();
|
||||
AUDIO_StartDMA();
|
||||
audioStarted = 1;
|
||||
}
|
||||
|
||||
return SYNC_AUDIO;
|
||||
return SYNC_WAIT;
|
||||
}
|
||||
|
||||
return SYNC_WAIT;
|
||||
/* Current available soundbuffer */
|
||||
s16 *sb = (s16 *)(soundbuffer[mixbuffer]);
|
||||
|
||||
/* Retrieve audio samples (size must be multiple of 32 bytes) */
|
||||
int size = audio_update(sb) * 4;
|
||||
|
||||
/* Update DMA settings */
|
||||
DCFlushRange((void *)sb, size);
|
||||
AUDIO_InitDMA((u32) sb, size);
|
||||
|
||||
mixbuffer = (mixbuffer + 1) % SOUND_BUFFER_NUM;
|
||||
|
||||
audioWait = audioSync;
|
||||
|
||||
/* Start Audio DMA */
|
||||
/* this is called once to kick-off DMA from external memory to audio interface */
|
||||
/* DMA operation is automatically restarted when all samples have been sent. */
|
||||
/* If DMA settings are not updated at that time, previous sound buffer will be used. */
|
||||
/* Therefore we need to make sure frame emulation is completed before current DMA is */
|
||||
/* completed, by synchronizing frame emulation with DMA start and also by syncing it */
|
||||
/* with Video Interrupt and outputing a suitable number of samples per frame. */
|
||||
if (!audioStarted)
|
||||
{
|
||||
/* restart audio DMA */
|
||||
AUDIO_StopDMA();
|
||||
AUDIO_StartDMA();
|
||||
audioStarted = 1;
|
||||
}
|
||||
|
||||
return SYNC_AUDIO;
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX audio support
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006)
|
||||
* Copyright Eke-Eke (2007-2014), based on original work from Softdev (2006)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
232
gx/gx_video.c
232
gx/gx_video.c
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX video & rendering support
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006)
|
||||
* Copyright Eke-Eke (2007-2014), based on original work from Softdev (2006)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -46,13 +46,6 @@
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
#include <png.h>
|
||||
|
||||
#define TEX_WIDTH 720
|
||||
#define TEX_HEIGHT 576
|
||||
#define TEX_SIZE (TEX_WIDTH * TEX_HEIGHT * 2)
|
||||
#define DEFAULT_FIFO_SIZE 256 * 1024
|
||||
#define HASPECT 320
|
||||
#define VASPECT 240
|
||||
|
||||
/* libpng wrapper */
|
||||
typedef struct
|
||||
{
|
||||
@ -67,10 +60,8 @@ extern const u8 CD_access_on_png[];
|
||||
extern const u8 CD_ready_off_png[];
|
||||
extern const u8 CD_ready_on_png[];
|
||||
|
||||
/*** VI ***/
|
||||
GXRModeObj *vmode; /* Default Video Mode */
|
||||
u8 *texturemem; /* Texture Data */
|
||||
u8 *screenshot; /* Texture Data */
|
||||
/*** VI Mode ***/
|
||||
GXRModeObj *vmode;
|
||||
|
||||
/*** 50/60hz flag ***/
|
||||
u32 gc_pal;
|
||||
@ -80,7 +71,7 @@ sms_ntsc_t *sms_ntsc;
|
||||
md_ntsc_t *md_ntsc;
|
||||
|
||||
/*** GX FIFO ***/
|
||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
||||
static u8 gp_fifo[GX_FIFO_MINSIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
/*** GX Textures ***/
|
||||
static u32 vwidth, vheight;
|
||||
@ -88,8 +79,8 @@ static gx_texture *crosshair[2];
|
||||
static gx_texture *cd_leds[2][2];
|
||||
|
||||
/*** Framebuffers ***/
|
||||
static u32 *xfb[2];
|
||||
static u32 whichfb = 0;
|
||||
static u32 *xfb;
|
||||
static u32 drawDone;
|
||||
|
||||
/*** Frame Sync ***/
|
||||
u32 videoSync;
|
||||
@ -341,23 +332,10 @@ typedef struct tagcamera
|
||||
guVector view;
|
||||
} camera;
|
||||
|
||||
/*** Square Matrix
|
||||
This structure controls the size of the image on the screen.
|
||||
Think of the output as a -80 x 80 by -60 x 60 graph.
|
||||
***/
|
||||
static s16 square[] ATTRIBUTE_ALIGN (32) =
|
||||
{
|
||||
/*
|
||||
* X, Y, Z
|
||||
* Values set are for roughly 4:3 aspect
|
||||
*/
|
||||
-HASPECT, VASPECT, 0, // 0
|
||||
HASPECT, VASPECT, 0, // 1
|
||||
HASPECT, -VASPECT, 0, // 2
|
||||
-HASPECT, -VASPECT, 0, // 3
|
||||
};
|
||||
static s16 square[8] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
static camera cam = {
|
||||
static camera cam =
|
||||
{
|
||||
{0.0F, 0.0F, -100.0F},
|
||||
{0.0F, -1.0F, 0.0F},
|
||||
{0.0F, 0.0F, 0.0F}
|
||||
@ -379,17 +357,36 @@ static u8 d_list[32] ATTRIBUTE_ALIGN(32) =
|
||||
/* VSYNC callback */
|
||||
static void vi_callback(u32 cnt)
|
||||
{
|
||||
/* clear VSYNC flag */
|
||||
videoWait = 0;
|
||||
|
||||
/* check if EFB rendering is finished */
|
||||
if (drawDone)
|
||||
{
|
||||
/* clear GX draw end flag */
|
||||
drawDone = 0;
|
||||
|
||||
/* copy EFB to XFB */
|
||||
GX_CopyDisp(xfb, GX_FALSE);
|
||||
GX_Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/* GX draw callback */
|
||||
static void gx_callback(void)
|
||||
{
|
||||
/* set GX draw end flag */
|
||||
drawDone = 1;
|
||||
}
|
||||
|
||||
/* Initialize GX */
|
||||
static void gxStart(void)
|
||||
{
|
||||
/*** Clear out FIFO area ***/
|
||||
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
|
||||
memset(&gp_fifo, 0, sizeof(gp_fifo));
|
||||
|
||||
/*** GX default ***/
|
||||
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
|
||||
GX_Init(&gp_fifo, sizeof(gp_fifo));
|
||||
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||
GX_SetCullMode(GX_CULL_NONE);
|
||||
GX_SetClipMode(GX_CLIP_DISABLE);
|
||||
@ -404,6 +401,9 @@ static void gxStart(void)
|
||||
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
||||
GX_LoadPosMtxImm(view, GX_PNMTX0);
|
||||
GX_Flush();
|
||||
|
||||
/* GX rendering callback */
|
||||
GX_SetDrawDoneCallback(gx_callback);
|
||||
}
|
||||
|
||||
/* Reset GX rendering */
|
||||
@ -434,11 +434,11 @@ static void gxResetRendering(u8 type)
|
||||
{
|
||||
/* uses array positionning, no alpha blending, no color channel (video emulation) */
|
||||
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_POS, GX_POS_XY, GX_S16, 0);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
|
||||
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||
GX_SetArray(GX_VA_POS, square, 3 * sizeof (s16));
|
||||
GX_SetArray(GX_VA_POS, square, 2 * sizeof (s16));
|
||||
/*
|
||||
Color.out = Color.texture
|
||||
Alpha.out = Alpha.texture
|
||||
@ -645,10 +645,10 @@ static void gxResetScaler(u32 width)
|
||||
}
|
||||
|
||||
/* Set GX scaler (Vertex Position matrix) */
|
||||
square[6] = square[3] = xshift + xscale;
|
||||
square[0] = square[9] = xshift - xscale;
|
||||
square[4] = square[1] = yshift + yscale;
|
||||
square[7] = square[10] = yshift - yscale;
|
||||
square[0] = square[6] = xshift - xscale;
|
||||
square[2] = square[4] = xshift + xscale;
|
||||
square[1] = square[3] = yshift + yscale;
|
||||
square[5] = square[7] = yshift - yscale;
|
||||
DCFlushRange(square, 32);
|
||||
GX_InvVtxCache();
|
||||
}
|
||||
@ -663,12 +663,12 @@ static void gxDrawCrosshair(gx_texture *texture, int x, int y)
|
||||
if (config.aspect & 2) w = (w * 3) / 4;
|
||||
|
||||
/* EFB scale & shift */
|
||||
int xwidth = square[3] - square[9];
|
||||
int ywidth = square[4] - square[10];
|
||||
int xwidth = square[2] - square[6];
|
||||
int ywidth = square[3] - square[7];
|
||||
|
||||
/* adjust texture coordinates to EFB */
|
||||
x = (((x + bitmap.viewport.x) * xwidth) / vwidth) + square[9] - w/2;
|
||||
y = (((y + bitmap.viewport.y) * ywidth) / vheight) + square[10] - h/2;
|
||||
x = (((x + bitmap.viewport.x) * xwidth) / vwidth) + square[6] - w/2;
|
||||
y = (((y + bitmap.viewport.y) * ywidth) / vheight) + square[7] - h/2;
|
||||
|
||||
/* load texture object */
|
||||
GXTexObj texObj;
|
||||
@ -704,13 +704,13 @@ static void gxDrawCdLeds(gx_texture *texture_l, gx_texture *texture_r)
|
||||
if (config.aspect & 2) w = (w * 3) / 4;
|
||||
|
||||
/* EFB scale & shift */
|
||||
int xwidth = square[3] - square[9];
|
||||
int ywidth = square[4] - square[10];
|
||||
int xwidth = square[2] - square[6];
|
||||
int ywidth = square[3] - square[7];
|
||||
|
||||
/* adjust texture coordinates to EFB */
|
||||
int xl = ((bitmap.viewport.x * xwidth) / vwidth) + square[9] + 8;
|
||||
int xr = (((bitmap.viewport.x + bitmap.viewport.w) * xwidth) / vwidth) + square[9] - 8 - w;
|
||||
int y = (((bitmap.viewport.y + bitmap.viewport.h - 4) * ywidth) / vheight) + square[10] - h;
|
||||
int xl = ((bitmap.viewport.x * xwidth) / vwidth) + square[6] + 8;
|
||||
int xr = (((bitmap.viewport.x + bitmap.viewport.w) * xwidth) / vwidth) + square[6] - 8 - w;
|
||||
int y = (((bitmap.viewport.y + bitmap.viewport.h - 4) * ywidth) / vheight) + square[7] - h;
|
||||
|
||||
/* load left screen texture */
|
||||
GXTexObj texObj;
|
||||
@ -929,7 +929,7 @@ void gxDrawScreenshot(u8 alpha)
|
||||
|
||||
/* get current game screen texture */
|
||||
GXTexObj texobj;
|
||||
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GX_InitTexObj(&texobj, bitmap.data, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
@ -978,7 +978,7 @@ void gxCopyScreenshot(gx_texture *texture)
|
||||
{
|
||||
/* retrieve gamescreen texture */
|
||||
GXTexObj texobj;
|
||||
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GX_InitTexObj(&texobj, bitmap.data, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
@ -1011,10 +1011,6 @@ void gxCopyScreenshot(gx_texture *texture)
|
||||
GX_End();
|
||||
|
||||
/* copy EFB to texture */
|
||||
texture->format = GX_TF_RGBA8;
|
||||
texture->width = 320;
|
||||
texture->height = bitmap.viewport.h;
|
||||
texture->data = screenshot;
|
||||
GX_SetTexCopySrc(0, 0, texture->width * 2, texture->height * 2);
|
||||
GX_SetTexCopyDst(texture->width, texture->height, texture->format, GX_TRUE);
|
||||
GX_DrawDone();
|
||||
@ -1036,35 +1032,39 @@ void gxSaveScreenshot(char *filename)
|
||||
{
|
||||
/* capture screenshot into a texture */
|
||||
gx_texture texture;
|
||||
gxCopyScreenshot(&texture);
|
||||
texture.format = GX_TF_RGBA8;
|
||||
texture.width = 320;
|
||||
texture.height = bitmap.viewport.h;
|
||||
texture.data = memalign(32, texture.width*texture.height*4);
|
||||
|
||||
/* open PNG file */
|
||||
FILE *f = fopen(filename,"wb");
|
||||
if (f)
|
||||
if (texture.data)
|
||||
{
|
||||
/* encode screenshot into PNG file */
|
||||
gxTextureWritePNG(&texture,f);
|
||||
fclose(f);
|
||||
gxCopyScreenshot(&texture);
|
||||
|
||||
/* open PNG file */
|
||||
FILE *f = fopen(filename,"wb");
|
||||
if (f)
|
||||
{
|
||||
/* encode screenshot into PNG file */
|
||||
gxTextureWritePNG(&texture,f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
free(texture.data);
|
||||
}
|
||||
}
|
||||
|
||||
void gxSetScreen(void)
|
||||
{
|
||||
GX_DrawDone();
|
||||
GX_CopyDisp(xfb[whichfb], GX_FALSE);
|
||||
VIDEO_WaitVSync();
|
||||
GX_CopyDisp(xfb, GX_FALSE);
|
||||
GX_Flush();
|
||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||
VIDEO_Flush ();
|
||||
VIDEO_WaitVSync ();
|
||||
gx_input_UpdateMenu();
|
||||
}
|
||||
|
||||
void gxClearScreen(GXColor color)
|
||||
{
|
||||
whichfb ^= 1;
|
||||
GX_SetCopyClear(color,0x00ffffff);
|
||||
GX_CopyDisp(xfb[whichfb], GX_TRUE);
|
||||
GX_Flush();
|
||||
gxDrawRectangle(0, 0, vmode->fbWidth, vmode->efbHeight, 255, color);
|
||||
}
|
||||
|
||||
/***************************************************************************************/
|
||||
@ -1424,8 +1424,18 @@ void gxTextureClose(gx_texture **p_texture)
|
||||
/* Emulation mode -> Menu mode */
|
||||
void gx_video_Stop(void)
|
||||
{
|
||||
/* wait for next VBLANK */
|
||||
VIDEO_WaitVSync ();
|
||||
/* disable VSYNC callback */
|
||||
VIDEO_SetPostRetraceCallback(NULL);
|
||||
|
||||
/* wait for next even field */
|
||||
/* this prevents screen artefacts when switching between interlaced & non-interlaced modes */
|
||||
do VIDEO_WaitVSync();
|
||||
while (!VIDEO_GetNextField());
|
||||
|
||||
|
||||
/* adjust TV width */
|
||||
vmode->viWidth = config.screen_w;
|
||||
vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2;
|
||||
|
||||
/* unallocate NTSC filters */
|
||||
if (sms_ntsc) free(sms_ntsc);
|
||||
@ -1451,19 +1461,17 @@ void gx_video_Stop(void)
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
gxDrawScreenshot(0xff);
|
||||
|
||||
/* default VI settings */
|
||||
VIDEO_SetPostRetraceCallback(NULL);
|
||||
#ifdef HW_RVL
|
||||
/* default VI settings */
|
||||
VIDEO_SetTrapFilter(1);
|
||||
VIDEO_SetGamma(VI_GM_1_0);
|
||||
#endif
|
||||
|
||||
/* adjust TV width */
|
||||
vmode->viWidth = config.screen_w;
|
||||
vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2;
|
||||
/* reset default TV mode */
|
||||
VIDEO_Configure(vmode);
|
||||
VIDEO_Flush();
|
||||
|
||||
/* wait for VSYNC */
|
||||
/* display next frame */
|
||||
gxSetScreen();
|
||||
}
|
||||
|
||||
@ -1490,9 +1498,6 @@ void gx_video_Start(void)
|
||||
/* When VSYNC is set to AUTO & console TV mode matches emulated video mode, emulation is synchronized with video hardware as well */
|
||||
if (config.vsync && (gc_pal == vdp_pal))
|
||||
{
|
||||
/* VSYNC callback */
|
||||
VIDEO_SetPostRetraceCallback(vi_callback);
|
||||
VIDEO_Flush();
|
||||
videoSync = audioSync;
|
||||
}
|
||||
else
|
||||
@ -1628,7 +1633,11 @@ void gx_video_Start(void)
|
||||
gxResetRendering(0);
|
||||
|
||||
/* resynchronize emulation with VSYNC */
|
||||
VIDEO_WaitVSync();
|
||||
do VIDEO_WaitVSync();
|
||||
while (!VIDEO_GetNextField());
|
||||
|
||||
/* VSYNC callback */
|
||||
VIDEO_SetPostRetraceCallback(vi_callback);
|
||||
|
||||
/* restart frame sync */
|
||||
videoWait = 0;
|
||||
@ -1667,7 +1676,7 @@ int gx_video_Update(u32 done)
|
||||
|
||||
/* initialize texture object */
|
||||
GXTexObj texobj;
|
||||
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GX_InitTexObj(&texobj, bitmap.data, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
|
||||
/* configure texture filtering */
|
||||
if (!config.bilinear)
|
||||
@ -1696,14 +1705,18 @@ int gx_video_Update(u32 done)
|
||||
|
||||
/* update VI mode */
|
||||
VIDEO_Configure(rmode);
|
||||
VIDEO_Flush();
|
||||
}
|
||||
|
||||
/* texture is now directly mapped by the line renderer */
|
||||
|
||||
/* force texture cache update */
|
||||
DCFlushRange(texturemem, TEX_SIZE);
|
||||
DCFlushRange(bitmap.data, vwidth*vheight*2);
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
/* disable EFB copy until rendering is done */
|
||||
drawDone = 0;
|
||||
|
||||
/* render textured quad */
|
||||
GX_CallDispList(d_list, 32);
|
||||
|
||||
@ -1766,31 +1779,22 @@ int gx_video_Update(u32 done)
|
||||
gxDrawOnScreenText(msg);
|
||||
}
|
||||
|
||||
/* restore GX rendering */
|
||||
gxResetRendering(0);
|
||||
|
||||
/* restore texture object */
|
||||
GXTexObj texobj;
|
||||
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GX_InitTexObj(&texobj, bitmap.data, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
if (!config.bilinear)
|
||||
{
|
||||
GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,0.0,10.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1);
|
||||
}
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
/* restore GX rendering */
|
||||
gxResetRendering(0);
|
||||
}
|
||||
|
||||
/* swap XFB */
|
||||
whichfb ^= 1;
|
||||
|
||||
/* copy EFB to XFB */
|
||||
GX_DrawDone();
|
||||
GX_CopyDisp(xfb[whichfb], GX_TRUE);
|
||||
GX_Flush();
|
||||
|
||||
/* XFB is ready to be displayed */
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
/* GX draw interrupt will be triggered when EFB rendering is finished */
|
||||
GX_SetDrawDone();
|
||||
|
||||
if (bitmap.viewport.changed & 1)
|
||||
{
|
||||
@ -1847,21 +1851,19 @@ void gx_video_Init(void)
|
||||
}
|
||||
|
||||
/* Configure VI */
|
||||
VIDEO_Configure (vmode);
|
||||
VIDEO_Configure(vmode);
|
||||
|
||||
/* Configure the framebuffers (double-buffering) */
|
||||
xfb[0] = (u32 *) MEM_K0_TO_K1((u32 *) SYS_AllocateFramebuffer(&TV50hz_576i));
|
||||
xfb[1] = (u32 *) MEM_K0_TO_K1((u32 *) SYS_AllocateFramebuffer(&TV50hz_576i));
|
||||
/* Allocate framebuffer */
|
||||
xfb = (u32 *) MEM_K0_TO_K1((u32 *) SYS_AllocateFramebuffer(&TV50hz_576i));
|
||||
|
||||
/* Define a console */
|
||||
console_init(xfb[0], 20, 64, 640, 574, 574 * 2);
|
||||
console_init(xfb, 20, 64, 640, 574, 574 * 2);
|
||||
|
||||
/* Clear framebuffers to black */
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
|
||||
/* Clear framebuffer to black */
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb, COLOR_BLACK);
|
||||
|
||||
/* Set the framebuffer to be displayed at next VBlank */
|
||||
VIDEO_SetNextFramebuffer(xfb[0]);
|
||||
VIDEO_SetNextFramebuffer(xfb);
|
||||
|
||||
/* Enable Video Interface */
|
||||
VIDEO_SetBlack(FALSE);
|
||||
@ -1878,20 +1880,14 @@ void gx_video_Init(void)
|
||||
gxResetRendering(1);
|
||||
gxResetMode(vmode, GX_TRUE);
|
||||
|
||||
/* initialize FONT */
|
||||
/* Initialize FONT */
|
||||
FONT_Init();
|
||||
|
||||
/* Initialize textures */
|
||||
texturemem = memalign(32, TEX_SIZE);
|
||||
screenshot = memalign(32, HASPECT*VASPECT*4);
|
||||
}
|
||||
|
||||
void gx_video_Shutdown(void)
|
||||
{
|
||||
if (texturemem) free(texturemem);
|
||||
if (screenshot) free(screenshot);
|
||||
FONT_Shutdown();
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb, COLOR_BLACK);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
@ -1922,7 +1918,7 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
|
||||
/* tiles are stored continuously in texture memory */
|
||||
in_width = SMS_NTSC_OUT_WIDTH(in_width) / 4;
|
||||
int offset = ((in_width * 32) * (vline / 4)) + ((vline & 3) * 8);
|
||||
sms_ntsc_out_t* __restrict__ line_out = (sms_ntsc_out_t*)(texturemem + offset);
|
||||
sms_ntsc_out_t* __restrict__ line_out = (sms_ntsc_out_t*)(bitmap.data + offset);
|
||||
offset = 0;
|
||||
|
||||
int n;
|
||||
@ -1992,7 +1988,7 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
|
||||
/* tiles are stored continuously in texture memory */
|
||||
in_width = MD_NTSC_OUT_WIDTH(in_width) >> 2;
|
||||
int offset = ((in_width << 5) * (vline >> 2)) + ((vline & 3) * 8);
|
||||
md_ntsc_out_t* __restrict__ line_out = (md_ntsc_out_t*)(texturemem + offset);
|
||||
md_ntsc_out_t* __restrict__ line_out = (md_ntsc_out_t*)(bitmap.data + offset);
|
||||
|
||||
int n;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX video support
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006)
|
||||
* Copyright Eke-Eke (2007-2014), based on original work from Softdev (2006)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -53,7 +53,7 @@
|
||||
/* Tiles are stored continuously in texture memory */
|
||||
#define CUSTOM_BLITTER(line, width, table, in) \
|
||||
width >>= 2; \
|
||||
u16 *out = (u16 *) (texturemem + (((width << 5) * (line >> 2)) + ((line & 3) << 3))); \
|
||||
u16 *out = (u16 *) (bitmap.data + (((width << 5) * (line >> 2)) + ((line & 3) << 3))); \
|
||||
do \
|
||||
{ \
|
||||
*out++ = table[*in++]; \
|
||||
@ -75,7 +75,6 @@ typedef struct
|
||||
|
||||
/* Global variables */
|
||||
extern GXRModeObj *vmode;
|
||||
extern u8 *texturemem;
|
||||
extern u32 gc_pal;
|
||||
extern u32 videoSync;
|
||||
|
||||
|
26
gx/main.c
26
gx/main.c
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006)
|
||||
* Copyright Eke-Eke (2007-2014), based on original work from Softdev (2006)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -46,13 +46,13 @@
|
||||
#include "file_load.h"
|
||||
#include "filesel.h"
|
||||
#include "cheats.h"
|
||||
#include "md_ntsc.h"
|
||||
|
||||
#include <fat.h>
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <iso9660.h>
|
||||
#include <ogc/usbmouse.h>
|
||||
|
||||
extern bool sdio_Deinitialize();
|
||||
extern void USBStorage_Deinitialize();
|
||||
#endif
|
||||
@ -62,7 +62,6 @@ extern void USBStorage_Deinitialize();
|
||||
|
||||
u32 Shutdown = 0;
|
||||
u32 ConfigRequested = 1;
|
||||
char osd_version[32];
|
||||
|
||||
#ifdef HW_RVL
|
||||
/****************************************************************************
|
||||
@ -80,7 +79,6 @@ static void Reload_cb(void)
|
||||
Shutdown = 1;
|
||||
ConfigRequested = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -131,14 +129,16 @@ static void init_machine(void)
|
||||
|
||||
/* allocate global work bitmap */
|
||||
memset(&bitmap, 0, sizeof (bitmap));
|
||||
bitmap.width = 720;
|
||||
bitmap.width = MD_NTSC_OUT_WIDTH(320 + 2 * 14);
|
||||
bitmap.height = 576;
|
||||
bitmap.pitch = bitmap.width * 2;
|
||||
bitmap.viewport.w = 256;
|
||||
bitmap.viewport.h = 224;
|
||||
bitmap.viewport.x = 0;
|
||||
bitmap.viewport.y = 0;
|
||||
bitmap.data = texturemem;
|
||||
bitmap.data = memalign(32, bitmap.pitch * bitmap.height);
|
||||
|
||||
if (!bitmap.data)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to allocate memory");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void run_emulation(void)
|
||||
@ -358,6 +358,7 @@ void shutdown(void)
|
||||
/* shutdown audio & video engines */
|
||||
gx_audio_Shutdown();
|
||||
gx_video_Shutdown();
|
||||
if (bitmap.data) free(bitmap.data);
|
||||
|
||||
#ifdef HW_RVL
|
||||
/* unmount all devices */
|
||||
@ -400,10 +401,6 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(osd_version, "%s (IOS %d)", VERSION, IOS_GetVersion());
|
||||
#else
|
||||
sprintf(osd_version, "%s (GCN)", VERSION);
|
||||
#endif
|
||||
|
||||
/* initialize video engine */
|
||||
@ -592,7 +589,6 @@ int main (int argc, char *argv[])
|
||||
|
||||
/* by default, shutdown system when POWER buttons are pressed */
|
||||
SYS_SetPowerCallback(PowerOff_cb);
|
||||
|
||||
}
|
||||
#else
|
||||
/* autodetect SDLoad stub */
|
||||
|
Loading…
x
Reference in New Issue
Block a user