[Gamecube/Wii]

.added configurable FPS display & toggleable fast-forward key combo (HOME +
MINUS with Wii controllers or R TRIGGER + START with Gamecube controller)
.minor code cleanup & optimizations
This commit is contained in:
EkeEke 2013-12-08 17:23:45 +01:00
parent 67fedfa2f8
commit 9d37d1ff87
13 changed files with 222 additions and 263 deletions

View File

@ -132,7 +132,7 @@ void config_default(void)
config.gg_extra = 0; config.gg_extra = 0;
config.ntsc = 0; config.ntsc = 0;
config.vsync = 1; /* AUTO */ config.vsync = 1; /* AUTO */
config.bilinear = 1; config.bilinear = 0;
config.vfilter = 1; config.vfilter = 1;
if (VIDEO_HaveComponentCable()) if (VIDEO_HaveComponentCable())
@ -171,6 +171,7 @@ void config_default(void)
/* on-screen options */ /* on-screen options */
config.cd_leds = 0; config.cd_leds = 0;
config.fps = 0;
/* menu options */ /* menu options */
config.autoload = 0; config.autoload = 0;

View File

@ -40,7 +40,7 @@
#ifndef _CONFIG_H_ #ifndef _CONFIG_H_
#define _CONFIG_H_ #define _CONFIG_H_
#define CONFIG_VERSION "GENPLUS-GX 1.7.4" #define CONFIG_VERSION "GENPLUS-GX 1.7.5"
/**************************************************************************** /****************************************************************************
* Config Option * Config Option
@ -106,6 +106,7 @@ typedef struct
uint8 l_device; uint8 l_device;
uint8 bg_overlay; uint8 bg_overlay;
uint8 cd_leds; uint8 cd_leds;
uint8 fps;
int16 screen_w; int16 screen_w;
float bgm_volume; float bgm_volume;
float sfx_volume; float sfx_volume;

View File

@ -3,7 +3,7 @@
* *
* IPL font engine (using GX rendering) * IPL font engine (using GX rendering)
* *
* Copyright Eke-Eke (2009-2010) * Copyright Eke-Eke (2009-2013)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -50,14 +50,11 @@ typedef struct _yay0header {
unsigned int chunks_offset ATTRIBUTE_PACKED; unsigned int chunks_offset ATTRIBUTE_PACKED;
} yay0header; } yay0header;
u8 font_size[256];
int fheight;
static u8 *fontImage; static u8 *fontImage;
static u8 *fontTexture; static u8 *fontTexture;
static void *ipl_fontarea; static void *ipl_fontarea;
static sys_fontheader *fontHeader; static sys_fontheader *fontHeader;
static u8 font_size[256];
#ifndef HW_RVL #ifndef HW_RVL
@ -220,7 +217,10 @@ static void DrawChar(unsigned char c, int xpos, int ypos, int size, GXColor colo
GX_InvalidateTexAll(); GX_InvalidateTexAll();
/* adjust texture width */ /* adjust texture width */
s32 width = (fontHeader->cell_width * size) / fontHeader->cell_height; s32 width = (fontHeader->cell_width * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth);
/* adjust texture height */
size = (size * vmode->efbHeight) / 480;
/* GX rendering */ /* GX rendering */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
@ -282,9 +282,6 @@ int FONT_Init(void)
font_size[i] = ((u8*)fontHeader)[fontHeader->width_table + c]; font_size[i] = ((u8*)fontHeader)[fontHeader->width_table + c];
} }
/* font height */
fheight = fontHeader->cell_height;
/* initialize texture data */ /* initialize texture data */
fontTexture = memalign(32, fontHeader->cell_width * fontHeader->cell_height / 2); fontTexture = memalign(32, fontHeader->cell_width * fontHeader->cell_height / 2);
if (!fontTexture) if (!fontTexture)
@ -306,23 +303,28 @@ void FONT_Shutdown(void)
int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color) int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color)
{ {
int w, ox;
x -= (vmode->fbWidth / 2); x -= (vmode->fbWidth / 2);
y -= (vmode->efbHeight / 2); y -= (vmode->efbHeight / 2);
int w, ox = x;
while (*string && (*string != '\n')) ox = x;
while (*string)
{ {
w = (font_size[(u8)*string] * size) / fheight; if (*string == '\n')
{
x = ox;
y += size;
}
else
{
w = (font_size[(u8)*string] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth);
if ((x + w) > (ox + max_width)) return strlen(string); if ((x + w) > (ox + max_width)) return strlen(string);
DrawChar(*string, x, y, size,color); DrawChar(*string, x, y, size,color);
x += w; x += w;
string++;
} }
if (*string == '\n')
{
string++; string++;
return FONT_write(string, size, ox + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), max_width, color);
} }
return 0; return 0;
@ -330,21 +332,23 @@ int FONT_write(char *string, int size, int x, int y, int max_width, GXColor colo
int FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color) int FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color)
{ {
int i=0; int x;
int i = 0;
int w = 0; int w = 0;
while (string[i] && (string[i] != '\n')) while (string[i] && (string[i] != '\n'))
{ {
w += (font_size[(u8)string[i++]] * size) / fheight; w += (font_size[(u8)string[i++]] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth);
} }
if ((x1 + w) > x2) w = x2 - x1; if ((x1 + w) > x2) w = x2 - x1;
int x = x1 + (x2 - x1 - w - vmode->fbWidth) / 2; x = x1 + (x2 - x1 - w - vmode->fbWidth) / 2;
y -= (vmode->efbHeight / 2);
x2 -= (vmode->fbWidth / 2); x2 -= (vmode->fbWidth / 2);
y -= (vmode->efbHeight / 2);
while (*string && (*string != '\n')) while (*string && (*string != '\n'))
{ {
w = (font_size[(u8)*string] * size) / fheight; w = (font_size[(u8)*string] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth);
if ((x + w) > x2) return strlen(string); if ((x + w) > x2) return strlen(string);
DrawChar(*string, x, y, size,color); DrawChar(*string, x, y, size,color);
x += w; x += w;
@ -356,33 +360,41 @@ int FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor colo
string++; string++;
return FONT_writeCenter(string, size, x1, x2 + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), color); return FONT_writeCenter(string, size, x1, x2 + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), color);
} }
return 0; return 0;
} }
int FONT_alignRight(char *string, int size, int x, int y, GXColor color) int FONT_alignRight(char *string, int size, int x, int y, GXColor color)
{ {
int i; int ox;
int i = 0;
int w = 0; int w = 0;
while (string[i] && (string[i] != '\n'))
{
w += (font_size[(u8)string[i++]] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth);
}
x -= (vmode->fbWidth / 2); x -= (vmode->fbWidth / 2);
y -= (vmode->efbHeight / 2); y -= (vmode->efbHeight / 2);
int ox = x; ox = x;
x -= w;
for (i=0; i<strlen(string); i++) while (*string && (*string != '\n'))
{ {
w += (font_size[(u8)string[i]] * size) / fheight; w = (font_size[(u8)*string] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth);
}
x = ox - w;
while (*string)
{
w = (font_size[(u8)*string] * size) / fheight;
if ((x + w) > ox) return strlen(string); if ((x + w) > ox) return strlen(string);
DrawChar(*string, x, y, size,color); DrawChar(*string, x, y, size,color);
x += w; x += w;
string++; string++;
} }
if (*string == '\n')
{
string++;
return FONT_alignRight(string, size, ox + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), color);
}
return 0; return 0;
} }

View File

@ -3,7 +3,7 @@
* *
* IPL font engine (using GX rendering) * IPL font engine (using GX rendering)
* *
* Copyright Eke-Eke (2009-2010) * Copyright Eke-Eke (2009-2013)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:

View File

@ -393,18 +393,19 @@ static gui_item items_video[11] =
}; };
/* Menu options */ /* Menu options */
static gui_item items_prefs[10] = static gui_item items_prefs[11] =
{ {
{NULL,NULL,"Auto ROM Load: OFF", "Enable/Disable automatic ROM loading on startup", 56,132,276,48}, {NULL,NULL,"Auto ROM Load: OFF", "Enable/disable automatic ROM loading on startup", 56,132,276,48},
{NULL,NULL,"Auto Cheats: OFF", "Enable/Disable automatic cheats activation", 56,132,276,48}, {NULL,NULL,"Auto Cheats: OFF", "Enable/disable automatic cheats activation", 56,132,276,48},
{NULL,NULL,"Auto Saves: OFF", "Enable/Disable automatic saves", 56,132,276,48}, {NULL,NULL,"Auto Saves: OFF", "Enable/disable automatic saves", 56,132,276,48},
{NULL,NULL,"ROM Load Device: SD", "Configure default device for ROM files", 56,132,276,48}, {NULL,NULL,"ROM Load Device: SD", "Configure default device for ROM files", 56,132,276,48},
{NULL,NULL,"Saves Device: FAT", "Configure default device for Save files", 56,132,276,48}, {NULL,NULL,"Saves Device: FAT", "Configure default device for Save files", 56,132,276,48},
{NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 56,132,276,48}, {NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 56,132,276,48},
{NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 56,132,276,48}, {NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 56,132,276,48},
{NULL,NULL,"BG Overlay: ON", "Enable/disable background overlay", 56,132,276,48}, {NULL,NULL,"BG Overlay: ON", "Enable/disable background overlay", 56,132,276,48},
{NULL,NULL,"Screen Width: 658", "Adjust menu screen width in pixels", 56,132,276,48}, {NULL,NULL,"Screen Width: 658", "Adjust menu screen width in pixels", 56,132,276,48},
{NULL,NULL,"Show CD Leds: OFF", "Enable/Disable CD leds display", 56,132,276,48}, {NULL,NULL,"Show CD Leds: OFF", "Enable/disable CD leds display", 56,132,276,48},
{NULL,NULL,"Show FPS: OFF", "Enable/disable FPS counter", 56,132,276,48},
}; };
/* Save Manager */ /* Save Manager */
@ -613,7 +614,7 @@ static gui_menu menu_prefs =
{ {
"Menu Settings", "Menu Settings",
0,0, 0,0,
10,4,6,0, 11,4,6,0,
items_prefs, items_prefs,
buttons_list, buttons_list,
bg_list, bg_list,
@ -681,6 +682,7 @@ static void prefmenu ()
sprintf (items[7].text, "BG Overlay: %s", config.bg_overlay ? "ON":"OFF"); sprintf (items[7].text, "BG Overlay: %s", config.bg_overlay ? "ON":"OFF");
sprintf (items[8].text, "Screen Width: %d", config.screen_w); sprintf (items[8].text, "Screen Width: %d", config.screen_w);
sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF"); sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF");
sprintf (items[10].text, "Show FPS: %s", config.fps ? "ON":"OFF");
GUI_InitMenu(m); GUI_InitMenu(m);
GUI_SlideMenuTitle(m,strlen("Menu ")); GUI_SlideMenuTitle(m,strlen("Menu "));
@ -770,6 +772,11 @@ static void prefmenu ()
sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF"); sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF");
break; break;
case 10: /*** FPS counter ***/
config.fps ^= 1;
sprintf (items[10].text, "Show FPS: %s", config.fps ? "ON":"OFF");
break;
case -1: case -1:
quit = 1; quit = 1;
break; break;

View File

@ -59,7 +59,8 @@ static u8 *Bg_music_ogg = NULL;
static u32 Bg_music_ogg_size = 0; static u32 Bg_music_ogg_size = 0;
/* Frame Sync */ /* Frame Sync */
static u8 audio_sync; u32 audioSync;
static u32 audioWait;
/***************************************************************************************/ /***************************************************************************************/
/* Audio engine */ /* Audio engine */
@ -68,17 +69,7 @@ static u8 audio_sync;
/* Audio DMA callback */ /* Audio DMA callback */
static void ai_callback(void) static void ai_callback(void)
{ {
#ifdef LOG_TIMING audioWait = 0;
u64 current = gettime();
if (prevtime)
{
delta_time[frame_cnt] = diff_nsec(prevtime, current);
frame_cnt = (frame_cnt + 1) % LOGSIZE;
}
prevtime = current;
#endif
audio_sync = 0;
} }
/* AUDIO engine initialization */ /* AUDIO engine initialization */
@ -105,6 +96,9 @@ void gx_audio_Init(void)
} }
fclose(f); fclose(f);
} }
/* emulation is synchronized with audio hardware by default */
audioSync = 1;
} }
/* AUDIO engine shutdown */ /* AUDIO engine shutdown */
@ -128,7 +122,7 @@ void gx_audio_Shutdown(void)
***/ ***/
int gx_audio_Update(void) int gx_audio_Update(void)
{ {
if (!audio_sync) if (!audioWait)
{ {
/* Current available soundbuffer */ /* Current available soundbuffer */
s16 *sb = (s16 *)(soundbuffer[mixbuffer]); s16 *sb = (s16 *)(soundbuffer[mixbuffer]);
@ -136,22 +130,11 @@ int gx_audio_Update(void)
/* Retrieve audio samples (size must be multiple of 32 bytes) */ /* Retrieve audio samples (size must be multiple of 32 bytes) */
int size = audio_update(sb) * 4; int size = audio_update(sb) * 4;
#ifdef LOG_TIMING
if (prevtime && (frame_cnt < LOGSIZE - 1))
{
delta_samp[frame_cnt + 1] = size;
}
else
{
delta_samp[0] = size;
}
#endif
/* Update DMA settings */ /* Update DMA settings */
DCFlushRange((void *)sb, size); DCFlushRange((void *)sb, size);
AUDIO_InitDMA((u32) sb, size); AUDIO_InitDMA((u32) sb, size);
mixbuffer = (mixbuffer + 1) % SOUND_BUFFER_NUM; mixbuffer = (mixbuffer + 1) % SOUND_BUFFER_NUM;
audio_sync = 1; audioWait = audioSync;
/* Start Audio DMA */ /* Start Audio DMA */
/* this is called once to kick-off DMA from external memory to audio interface */ /* this is called once to kick-off DMA from external memory to audio interface */
@ -171,7 +154,7 @@ int gx_audio_Update(void)
return SYNC_AUDIO; return SYNC_AUDIO;
} }
return NO_SYNC; return SYNC_WAIT;
} }
/*** /***
@ -197,10 +180,10 @@ void gx_audio_Start(void)
AUDIO_RegisterDMACallback(ai_callback); AUDIO_RegisterDMACallback(ai_callback);
/* reset emulation audio processing */ /* reset emulation audio processing */
memset(soundbuffer, 0, 3 * SOUND_BUFFER_LEN); memset(soundbuffer, 0, sizeof(soundbuffer));
audioStarted = 0; audioStarted = 0;
mixbuffer = 0; mixbuffer = 0;
audio_sync = 0; audioWait = 0;
} }
/*** /***

View File

@ -41,6 +41,7 @@
#define _GC_AUDIO_H_ #define _GC_AUDIO_H_
extern u32 audioStarted; extern u32 audioStarted;
extern u32 audioSync;
extern void gx_audio_Init(void); extern void gx_audio_Init(void);
extern void gx_audio_Shutdown(void); extern void gx_audio_Shutdown(void);

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX input support * Genesis Plus GX input support
* *
* Copyright Eke-Eke (2007-2012) * Copyright Eke-Eke (2007-2013)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -218,6 +218,14 @@ static void pad_update(s8 chan, u8 i)
/* Retrieve current key mapping */ /* Retrieve current key mapping */
u16 *pad_keymap = config.pad_keymap[chan]; u16 *pad_keymap = config.pad_keymap[chan];
/* Default fast-forward key combo */
if ((p & PAD_TRIGGER_R) && (PAD_ButtonsDown(0) & PAD_BUTTON_START))
{
audioSync ^= 1;
videoSync = audioSync & config.vsync & !(gc_pal ^ vdp_pal);
return;
}
/* User configurable menu combo */ /* User configurable menu combo */
if ((p & pad_keymap[KEY_MENU]) == pad_keymap[KEY_MENU]) if ((p & pad_keymap[KEY_MENU]) == pad_keymap[KEY_MENU])
{ {
@ -1474,10 +1482,18 @@ void gx_input_UpdateEmu(void)
/* Update Wii controllers status */ /* Update Wii controllers status */
WPAD_ScanPads(); WPAD_ScanPads();
/* Hard-coded menu key */ /* Default Wii controller menu keys */
u32 p = WPAD_ButtonsHeld(0); if (WPAD_ButtonsDown(0) & (WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME))
if ((p & WPAD_BUTTON_HOME) || (p & WPAD_CLASSIC_BUTTON_HOME))
{ {
/* Default fast-forward key combo */
if (WPAD_ButtonsHeld(0) & (WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS))
{
audioSync ^= 1;
videoSync = audioSync & config.vsync & !(gc_pal ^ vdp_pal);
return;
}
/* Return to emulator settings */
ConfigRequested = 1; ConfigRequested = 1;
return; return;
} }

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX input support * Genesis Plus GX input support
* *
* Copyright Eke-Eke (2007-2012) * Copyright Eke-Eke (2007-2013)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:

View File

@ -43,6 +43,7 @@
#include "sms_ntsc.h" #include "sms_ntsc.h"
#include "gx_input.h" #include "gx_input.h"
#include <ogc/lwp_watchdog.h>
#include <png.h> #include <png.h>
#define TEX_WIDTH 720 #define TEX_WIDTH 720
@ -82,7 +83,7 @@ md_ntsc_t *md_ntsc;
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32); static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
/*** GX Textures ***/ /*** GX Textures ***/
static u32 vwidth,vheight; static u32 vwidth, vheight;
static gx_texture *crosshair[2]; static gx_texture *crosshair[2];
static gx_texture *cd_leds[2][2]; static gx_texture *cd_leds[2][2];
@ -91,7 +92,14 @@ static u32 *xfb[2];
static u32 whichfb = 0; static u32 whichfb = 0;
/*** Frame Sync ***/ /*** Frame Sync ***/
static u8 video_sync; u32 videoSync;
static u32 videoWait;
static u32 frameCount;
static u64 starttime;
/*** OSD ***/
static u32 osd;
static char msg[16];
/***************************************************************************************/ /***************************************************************************************/
/* Emulation video modes */ /* Emulation video modes */
@ -371,17 +379,7 @@ static u8 d_list[32] ATTRIBUTE_ALIGN(32) =
/* VSYNC callback */ /* VSYNC callback */
static void vi_callback(u32 cnt) static void vi_callback(u32 cnt)
{ {
#ifdef LOG_TIMING videoWait = 0;
u64 current = gettime();
if (prevtime)
{
delta_time[frame_cnt] = diff_nsec(prevtime, current);
frame_cnt = (frame_cnt + 1) % LOGSIZE;
}
prevtime = current;
#endif
video_sync = 0;
} }
/* Initialize GX */ /* Initialize GX */
@ -672,9 +670,6 @@ static void gxDrawCrosshair(gx_texture *texture, int x, int y)
x = (((x + bitmap.viewport.x) * xwidth) / vwidth) + square[9] - w/2; x = (((x + bitmap.viewport.x) * xwidth) / vwidth) + square[9] - w/2;
y = (((y + bitmap.viewport.y) * ywidth) / vheight) + square[10] - h/2; y = (((y + bitmap.viewport.y) * ywidth) / vheight) + square[10] - h/2;
/* reset GX rendering */
gxResetRendering(1);
/* load texture object */ /* load texture object */
GXTexObj texObj; GXTexObj texObj;
GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
@ -697,19 +692,6 @@ static void gxDrawCrosshair(gx_texture *texture, int x, int y)
GX_Color4u8(0xff,0xff,0xff,0xff); GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(0.0, 0.0); GX_TexCoord2f32(0.0, 0.0);
GX_End(); GX_End();
/* 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);
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();
} }
static void gxDrawCdLeds(gx_texture *texture_l, gx_texture *texture_r) static void gxDrawCdLeds(gx_texture *texture_l, gx_texture *texture_r)
@ -730,9 +712,6 @@ static void gxDrawCdLeds(gx_texture *texture_l, gx_texture *texture_r)
int xr = (((bitmap.viewport.x + bitmap.viewport.w) * xwidth) / vwidth) + square[9] - 8 - w; 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 y = (((bitmap.viewport.y + bitmap.viewport.h - 4) * ywidth) / vheight) + square[10] - h;
/* reset GX rendering */
gxResetRendering(1);
/* load left screen texture */ /* load left screen texture */
GXTexObj texObj; GXTexObj texObj;
GX_InitTexObj(&texObj, texture_l->data, texture_l->width, texture_l->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObj(&texObj, texture_l->data, texture_l->width, texture_l->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
@ -777,19 +756,18 @@ static void gxDrawCdLeds(gx_texture *texture_l, gx_texture *texture_r)
GX_Color4u8(0xff,0xff,0xff,0xff); GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(0.0, 0.0); GX_TexCoord2f32(0.0, 0.0);
GX_End(); GX_End();
}
/* restore GX rendering */ static void gxDrawOnScreenText(char *msg)
gxResetRendering(0); {
GXRModeObj *temp = vmode;
int y = (40 * rmode->efbHeight) / 480;
int x = (bitmap.viewport.x > 0) ? (24 + bitmap.viewport.x) : 24;
x = (x * rmode->fbWidth) / rmode->viWidth;
/* restore texture object */ vmode = rmode;
GXTexObj texobj; FONT_write(msg, 20, x, y, rmode->fbWidth, (GXColor)WHITE);
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); vmode = temp;
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();
} }
void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color) void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color)
@ -1515,6 +1493,11 @@ void gx_video_Start(void)
/* VSYNC callback */ /* VSYNC callback */
VIDEO_SetPostRetraceCallback(vi_callback); VIDEO_SetPostRetraceCallback(vi_callback);
VIDEO_Flush(); VIDEO_Flush();
videoSync = audioSync;
}
else
{
videoSync = 0;
} }
/* Enable progressive or interlaced video mode */ /* Enable progressive or interlaced video mode */
@ -1583,6 +1566,12 @@ void gx_video_Start(void)
} }
} }
/* on-screen display enable flag */
osd = config.fps;
/* clear any on-screen text */
memset(msg, 0, sizeof(msg));
/* lightgun textures */ /* lightgun textures */
int i, player = 0; int i, player = 0;
for (i=0; i<MAX_DEVICES; i++) for (i=0; i<MAX_DEVICES; i++)
@ -1599,6 +1588,7 @@ void gx_video_Start(void)
if (config.gun_cursor[0]) if (config.gun_cursor[0])
{ {
crosshair[0] = gxTextureOpenPNG(Crosshair_p1_png,0); crosshair[0] = gxTextureOpenPNG(Crosshair_p1_png,0);
osd = 1;
} }
} }
else else
@ -1607,6 +1597,7 @@ void gx_video_Start(void)
if (config.gun_cursor[1]) if (config.gun_cursor[1])
{ {
crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png,0); crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png,0);
osd = 1;
} }
} }
} }
@ -1629,6 +1620,7 @@ void gx_video_Start(void)
cd_leds[0][1] = gxTextureOpenPNG(CD_access_on_png,0); cd_leds[0][1] = gxTextureOpenPNG(CD_access_on_png,0);
cd_leds[1][0] = gxTextureOpenPNG(CD_ready_off_png,0); cd_leds[1][0] = gxTextureOpenPNG(CD_ready_off_png,0);
cd_leds[1][1] = gxTextureOpenPNG(CD_ready_on_png,0); cd_leds[1][1] = gxTextureOpenPNG(CD_ready_on_png,0);
osd = 1;
} }
} }
@ -1636,16 +1628,20 @@ void gx_video_Start(void)
gxResetRendering(0); gxResetRendering(0);
/* resynchronize emulation with VSYNC */ /* resynchronize emulation with VSYNC */
video_sync = 0;
VIDEO_WaitVSync(); VIDEO_WaitVSync();
/* restart frame sync */
videoWait = 0;
frameCount = 0;
starttime = gettime();
} }
/* GX render update */ /* GX render update */
int gx_video_Update(void) int gx_video_Update(u32 done)
{ {
if (video_sync) return NO_SYNC; if (videoWait || done) return SYNC_WAIT;
video_sync = config.vsync && (gc_pal == vdp_pal); videoWait = videoSync;
/* check if display has changed during frame */ /* check if display has changed during frame */
if (bitmap.viewport.changed & 1) if (bitmap.viewport.changed & 1)
@ -1711,6 +1707,12 @@ int gx_video_Update(void)
/* render textured quad */ /* render textured quad */
GX_CallDispList(d_list, 32); GX_CallDispList(d_list, 32);
/* on-screen display */
if (osd)
{
/* reset GX rendering */
gxResetRendering(1);
/* lightgun # 1 screen mark */ /* lightgun # 1 screen mark */
if (crosshair[0]) if (crosshair[0])
{ {
@ -1745,6 +1747,39 @@ int gx_video_Update(void)
gxDrawCdLeds(cd_leds[1][(mode >> 1) & 1], cd_leds[0][mode & 1]); gxDrawCdLeds(cd_leds[1][(mode >> 1) & 1], cd_leds[0][mode & 1]);
} }
/* FPS counter */
if (config.fps)
{
u32 delta = diff_usec(starttime, gettime());
frameCount++;
if (delta > 1000000)
{
sprintf(msg,"%3.2f FPS", (float)frameCount * 1000000.0 / (float)delta);
frameCount = 0;
starttime = gettime();
}
/* disable EFB alpha blending for text background */
GX_SetBlendMode(GX_BM_NONE,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR);
GX_Flush();
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);
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();
}
/* swap XFB */ /* swap XFB */
whichfb ^= 1; whichfb ^= 1;

View File

@ -77,6 +77,7 @@ typedef struct
extern GXRModeObj *vmode; extern GXRModeObj *vmode;
extern u8 *texturemem; extern u8 *texturemem;
extern u32 gc_pal; extern u32 gc_pal;
extern u32 videoSync;
/* GX rendering */ /* GX rendering */
extern void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color); extern void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color);
@ -99,6 +100,6 @@ extern void gx_video_Init(void);
extern void gx_video_Shutdown(void); extern void gx_video_Shutdown(void);
extern void gx_video_Start(void); extern void gx_video_Start(void);
extern void gx_video_Stop(void); extern void gx_video_Stop(void);
extern int gx_video_Update(void); extern int gx_video_Update(u32 done);
#endif #endif

105
gx/main.c
View File

@ -64,14 +64,6 @@ u32 Shutdown = 0;
u32 ConfigRequested = 1; u32 ConfigRequested = 1;
char osd_version[32]; char osd_version[32];
#ifdef LOG_TIMING
u64 prevtime;
u32 frame_cnt;
u32 delta_time[LOGSIZE];
u32 delta_samp[LOGSIZE];
#endif
#ifdef HW_RVL #ifdef HW_RVL
/**************************************************************************** /****************************************************************************
* Power Button callbacks * Power Button callbacks
@ -151,7 +143,7 @@ static void init_machine(void)
static void run_emulation(void) static void run_emulation(void)
{ {
int sync; u32 sync;
/* main emulation loop */ /* main emulation loop */
while (1) while (1)
@ -166,11 +158,11 @@ static void run_emulation(void)
system_frame_scd(0); system_frame_scd(0);
/* audio/video sync */ /* audio/video sync */
sync = NO_SYNC; sync = SYNC_WAIT;
while (sync != (SYNC_VIDEO | SYNC_AUDIO)) while (sync != (SYNC_VIDEO | SYNC_AUDIO))
{ {
/* update video */ /* update video */
sync |= gx_video_Update(); sync |= gx_video_Update(sync & SYNC_VIDEO);
/* update audio */ /* update audio */
sync |= gx_audio_Update(); sync |= gx_audio_Update();
@ -200,11 +192,11 @@ static void run_emulation(void)
system_frame_gen(0); system_frame_gen(0);
/* audio/video sync */ /* audio/video sync */
sync = NO_SYNC; sync = SYNC_WAIT;
while (sync != (SYNC_VIDEO | SYNC_AUDIO)) while (sync != (SYNC_VIDEO | SYNC_AUDIO))
{ {
/* update video */ /* update video */
sync |= gx_video_Update(); sync |= gx_video_Update(sync & SYNC_VIDEO);
/* update audio */ /* update audio */
sync |= gx_audio_Update(); sync |= gx_audio_Update();
@ -234,11 +226,11 @@ static void run_emulation(void)
system_frame_sms(0); system_frame_sms(0);
/* audio/video sync */ /* audio/video sync */
sync = NO_SYNC; sync = SYNC_WAIT;
while (sync != (SYNC_VIDEO | SYNC_AUDIO)) while (sync != (SYNC_VIDEO | SYNC_AUDIO))
{ {
/* update video */ /* update video */
sync |= gx_video_Update(); sync |= gx_video_Update(sync & SYNC_VIDEO);
/* update audio */ /* update audio */
sync |= gx_audio_Update(); sync |= gx_audio_Update();
@ -264,94 +256,13 @@ static void run_emulation(void)
gx_audio_Stop(); gx_audio_Stop();
gx_video_Stop(); gx_video_Stop();
#ifdef LOG_TIMING
if (system_hw)
{
FILE *f;
char filename[64];
memset(filename, 0, 64);
strcpy(filename,"timings-");
if (!config.vsync || (config.tv_mode == !vdp_pal))
{
strcat(filename,"no_");
}
else
{
if (gc_pal)
{
strcat(filename,"50hz_");
}
else
{
strcat(filename,"60hz_");
}
}
strcat(filename,"vsync-");
if (vdp_pal)
{
strcat(filename,"pal-");
}
else
{
strcat(filename,"ntsc-");
}
if (config.render == 2)
{
strcat(filename,"prog.txt");
}
else
{
if (!config.render && !interlaced)
{
strcat(filename,"no_");
}
strcat(filename,"int.txt");
}
f = fopen(filename,"a");
if (f != NULL)
{
int i;
u32 min,max;
double total = 0;
double nsamples = 0;
if (delta_time[LOGSIZE - 1] != 0)
{
frame_cnt = LOGSIZE;
}
min = max = delta_time[0];
for (i=0; i<frame_cnt; i++)
{
fprintf(f,"%d ns - %d samples (%5.8f samples/sec)\n", delta_time[i], delta_samp[i], 1000000000.0*(double)delta_samp[i]/(double)delta_time[i]/4.0);
total += delta_time[i];
nsamples += delta_samp[i] / 4.0;
if (min > delta_time[i]) min = delta_time[i];
if (max < delta_time[i]) max = delta_time[i];
}
fprintf(f,"\n");
fprintf(f,"min = %d ns\n", min);
fprintf(f,"max = %d ns\n", max);
fprintf(f,"avg = %8.5f ns (%5.8f samples/sec, %5.8f samples/frame)\n\n\n", total/(double)i, nsamples/total*1000000000.0, nsamples/(double)i);
fclose(f);
}
}
memset(delta_time,0,LOGSIZE);
memset(delta_samp,0,LOGSIZE);
frame_cnt = prevtime = 0;
#endif
/* show menu */ /* show menu */
ConfigRequested = 0; ConfigRequested = 0;
mainmenu(); mainmenu();
/* restart video & audio */ /* restart video & audio */
gx_video_Start();
gx_audio_Start(); gx_audio_Start();
gx_video_Start();
} }
} }

View File

@ -68,9 +68,9 @@
/*************************************************/ /*************************************************/
#define VERSION "Genesis Plus GX 1.7.4" #define VERSION "Genesis Plus GX 1.7.5"
#define NO_SYNC 0 #define SYNC_WAIT 0
#define SYNC_VIDEO 1 #define SYNC_VIDEO 1
#define SYNC_AUDIO 2 #define SYNC_AUDIO 2
@ -83,13 +83,4 @@ extern u32 Shutdown;
extern u32 ConfigRequested; extern u32 ConfigRequested;
extern char osd_version[32]; extern char osd_version[32];
#ifdef LOG_TIMING
#include <ogc/lwp_watchdog.h>
#define LOGSIZE 2000
extern u64 prevtime;
extern u32 frame_cnt;
extern u32 delta_time[LOGSIZE];
extern u32 delta_samp[LOGSIZE];
#endif
#endif /* _OSD_H_ */ #endif /* _OSD_H_ */