changed VIDEO synchronization

This commit is contained in:
ekeeke31 2009-01-09 17:11:42 +00:00
parent 4dbedcdc04
commit 3ee65ad74b
5 changed files with 127 additions and 112 deletions

View File

@ -266,7 +266,6 @@ void miscmenu ()
/* reinitialize overscan area */
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0;
bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
bitmap.viewport.changed = 1;
}
break;
@ -278,7 +277,7 @@ void miscmenu ()
config.bios_enabled ^= 1;
if (genromsize || (config.bios_enabled == 3))
{
system_init ();
system_init ();
audio_init(48000);
system_reset ();
}
@ -371,7 +370,6 @@ void dispmenu ()
config.render = 0;
}
}
bitmap.viewport.changed = 1;
break;
case 2: /*** tv mode ***/
@ -381,20 +379,17 @@ void dispmenu ()
case 3: /*** bilinear filtering ***/
config.bilinear ^= 1;
bitmap.viewport.changed = 1;
break;
case 4: /*** NTSC filter ***/
config.ntsc ++;
if (config.ntsc > 3) config.ntsc = 0;
bitmap.viewport.changed = 1;
break;
case 5: /*** overscan emulation ***/
config.overscan ^= 1;
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0;
bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
bitmap.viewport.changed = 1;
break;
case 6: /*** Center X ***/
@ -1116,7 +1111,7 @@ void showrominfo ()
****************************************************************************/
void MainMenu ()
{
menu = 0;
menu = 0;
int ret;
int quit = 0;
uint32 crccheck;
@ -1134,13 +1129,6 @@ void MainMenu ()
{"System Reboot"}
};
/* Switch to menu default rendering mode (60hz or 50hz, but always 480 lines) */
VIDEO_Configure (vmode);
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
VIDEO_WaitVSync();
/* autosave (SRAM only) */
int temp = config.freeze_auto;
config.freeze_auto = -1;
@ -1221,14 +1209,6 @@ void MainMenu ()
while (WPAD_ButtonsHeld(0)) WPAD_ScanPads();
#endif
/*** Reinitialize GX ***/
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
VIDEO_WaitVSync();
ogc_video__reset();
odd_frame = 1;
#ifndef HW_RVL
/*** Stop the DVD from causing clicks while playing ***/
uselessinquiry ();

View File

@ -175,26 +175,30 @@ int main (int argc, char *argv[])
/* Initialize Virtual Machine */
init_machine ();
/* load any injected rom */
if (genromsize)
{
ARAMFetch((char *)cart_rom, (void *)0x8000, genromsize);
reloadrom ();
}
/* Show Menu */
MainMenu();
ConfigRequested = 0;
/* Reset frame sync */
frameticker = 0;
FrameCount = 0;
RenderedFrameCount = 0;
/* Start Audio & Video */
ogc_audio__start();
ogc_video__start();
/* Emulation Loop */
while (1)
{
ogc_audio__start();
/* this is an ugly hack to prevent VIDEO desync */
if (interlaced & !config.render) odd_frame = VIDEO_GetNextField()^1;
if (gc_pal < 0)
{
/* this code is NEVER executed */
@ -207,27 +211,30 @@ int main (int argc, char *argv[])
{
if (frameticker > 1)
{
/* frameskipping */
frameticker--;
system_frame (1);
}
else
{
/* frame sync */
/* frameskipping */
frameticker--;
system_frame (1);
/* update audio only */
ogc_audio__update();
}
else
{
/* frame sync */
while (!frameticker) usleep(1);
/* frame rendering */
system_frame (0);
RenderedFrameCount++;
}
/* frame rendering */
system_frame (0);
RenderedFrameCount++;
/* update video & audio */
ogc_audio__update();
ogc_video__update();
}
frameticker--;
}
/* update video & audio */
ogc_audio__update();
ogc_video__update();
/* check rendered frames (FPS) */
FrameCount++;
if (FrameCount == vdp_rate)
@ -240,8 +247,9 @@ int main (int argc, char *argv[])
/* Check for Menu request */
if (ConfigRequested)
{
/* stop Audio */
/* stop Audio & Video */
ogc_audio__stop();
ogc_video__stop();
/* go to menu */
MainMenu ();
@ -252,6 +260,9 @@ int main (int argc, char *argv[])
FrameCount = 0;
RenderedFrameCount = 0;
/* restart Audio & Video */
ogc_audio__start();
ogc_video__start();
}
}

View File

@ -35,9 +35,6 @@ u8 soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
/* Current work soundbuffer */
int mixbuffer;
/* Current DMA status (1: DMA in progress, 0: DMA stopped) */
static int IsPlaying = 0;
/* Current DMA length (required to be a factor of 32-bytes)
length is calculated regarding current emulation timings:
PAL timings : 50 frames/sec, 48000 samples/sec = 960 samples per frame = 3840 bytes (16 bits stereo samples)
@ -99,16 +96,12 @@ void ogc_audio__update(void)
***/
void ogc_audio__start(void)
{
if (!IsPlaying)
{
dma_len = vdp_pal ? 3840 : 3200;
memset(soundbuffer[0], 0, dma_len);
AUDIO_InitDMA((u32) soundbuffer[0], dma_len);
DCFlushRange(soundbuffer[0], dma_len);
AUDIO_StartDMA();
IsPlaying = 1;
mixbuffer = 1;
}
dma_len = vdp_pal ? 3840 : 3200;
memset(soundbuffer[0], 0, dma_len);
AUDIO_InitDMA((u32) soundbuffer[0], dma_len);
DCFlushRange(soundbuffer[0], dma_len);
AUDIO_StartDMA();
mixbuffer = 1;
}
/***
@ -121,5 +114,4 @@ void ogc_audio__start(void)
void ogc_audio__stop(void)
{
AUDIO_StopDMA ();
IsPlaying = 0;
}

View File

@ -303,8 +303,14 @@ static camera cam = {
{0.0F, 0.0F, 0.0F}
};
/* rendering initialization */
/* should be called each time you change quad aspect ratio */
void xfb_swap(u32 cnt)
{
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
whichfb ^= 1;
}
/* Rendering Initialization */
static void draw_init(void)
{
/* Clear all Vertex params */
@ -329,7 +335,7 @@ static void draw_init(void)
GX_LoadPosMtxImm (view, GX_PNMTX0);
}
/* vertex rendering */
/* Vertex Rendering */
static inline void draw_vert(u8 pos, f32 s, f32 t)
{
GX_Position1x8 (pos);
@ -394,7 +400,7 @@ static void gxScale(GXRModeObj *rmode)
int temp = 0;
int xscale, yscale, xshift, yshift;
/* Aspect Ratio (depending on current configuration) */
/* aspect Ratio (depends on current configuration) */
if (config.aspect)
{
/* original aspect ratio */
@ -441,14 +447,14 @@ static void gxScale(GXRModeObj *rmode)
yshift = config.yshift;
}
/* Double resolution modes */
/* double resolution modes */
if (config.render)
{
yscale *= 2;
yshift *= 2;
}
/* GX Scaler (by default, use EFB maximal width) */
/* GX scaler (by default, use EFB maximal width) */
rmode->fbWidth = 640;
if (!config.bilinear && !config.ntsc)
{
@ -459,7 +465,7 @@ static void gxScale(GXRModeObj *rmode)
else if (width <= 640) rmode->fbWidth = width;
}
/* Horizontal Scaling (GX/VI) */
/* horizontal scaling (GX/VI) */
if (xscale > (rmode->fbWidth/2))
{
/* max width = 720 pixels */
@ -494,48 +500,20 @@ static void gxScale(GXRModeObj *rmode)
GX_InvVtxCache ();
}
/* Reinitialize Video */
void ogc_video__reset()
/* Reset Video Mode */
static void gxReset(void)
{
Mtx p;
GXRModeObj *rmode;
/* 50Hz/60Hz mode */
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
else gc_pal = 0;
/* progressive mode */
if (config.render == 2)
{
/* 480p */
tvmodes[2]->viTVMode = VI_TVMODE_NTSC_PROG;
tvmodes[2]->xfbMode = VI_XFBMODE_SF;
}
else if (config.render == 1)
{
/* 480i */
tvmodes[2]->viTVMode = tvmodes[0]->viTVMode & ~3;
tvmodes[2]->xfbMode = VI_XFBMODE_DF;
}
/* Set current TV mode */
/* select TV mode */
if (config.render) rmode = tvmodes[gc_pal*3 + 2];
else rmode = tvmodes[gc_pal*3 + interlaced];
/* Aspect ratio */
/* reset aspect ratio */
gxScale(rmode);
/* Configure VI */
VIDEO_Configure (rmode);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
/* reset frame counter (unless it's interlaced mode change) */
if (!interlaced) frameticker = 0;
/* Configure GX */
/* configure GX */
GX_SetViewport (0.0F, 0.0F, rmode->fbWidth, rmode->efbHeight, 0.0F, 1.0F);
GX_SetScissor (0, 0, rmode->fbWidth, rmode->efbHeight);
f32 yScale = GX_GetYScaleFactor(rmode->efbHeight, rmode->xfbHeight);
@ -549,7 +527,62 @@ void ogc_video__reset()
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
GX_Flush ();
/* Software NTSC filter */
/* configure VI */
VIDEO_Configure (rmode);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
else while (VIDEO_GetNextField() != odd_frame) VIDEO_WaitVSync();
/* resynchronize field & restore VSYNC handler */
whichfb = odd_frame;
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_SetPreRetraceCallback(xfb_swap);
VIDEO_Flush();
VIDEO_WaitVSync();
}
/* Set Menu Video mode */
void ogc_video__stop(void)
{
/* clear screen */
VIDEO_Configure (vmode);
VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
/* disable VSYNC handler */
VIDEO_SetPreRetraceCallback(NULL);
VIDEO_Flush();
VIDEO_WaitVSync();
VIDEO_WaitVSync();
}
/* Update Video settings */
void ogc_video__start()
{
/* clear screen */
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
/* 50Hz/60Hz mode */
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
else gc_pal = 0;
/* interlaced/progressive mode */
if (config.render == 2)
{
tvmodes[2]->viTVMode = VI_TVMODE_NTSC_PROG;
tvmodes[2]->xfbMode = VI_XFBMODE_SF;
}
else if (config.render == 1)
{
tvmodes[2]->viTVMode = tvmodes[0]->viTVMode & ~3;
tvmodes[2]->xfbMode = VI_XFBMODE_DF;
}
/* software NTSC filters */
if (config.ntsc == 1)
{
sms_setup = sms_ntsc_composite;
@ -571,6 +604,9 @@ void ogc_video__reset()
sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup );
}
/* apply changes on next video update */
bitmap.viewport.changed = 1;
}
/* GX render update */
@ -593,8 +629,8 @@ void ogc_video__update()
vwidth = vwidth / 4;
vheight = vheight / 4;
/* image size has changed, reset GX */
ogc_video__reset();
/* reset Video mode */
gxReset();
/* reinitialize texture */
GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
@ -614,19 +650,14 @@ void ogc_video__update()
/* update texture cache */
DCFlushRange (texturemem, TEX_SIZE);
GX_InvalidateTexAll ();
/* render textured quad */
draw_square ();
GX_DrawDone ();
/* switch external framebuffers then copy EFB to XFB */
whichfb ^= 1;
GX_CopyDisp (xfb[whichfb], GX_TRUE);
/* copy EFB to current XFB */
GX_CopyDisp (xfb[odd_frame], GX_TRUE);
GX_Flush ();
/* set next XFB */
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
}
/* Initialize VIDEO subsystem */
@ -704,7 +735,7 @@ void ogc_video__init(void)
}
#endif
/* Configure VIDEO mode */
/* Configure VI */
VIDEO_Configure (vmode);
/* Configure the framebuffers (double-buffering) */

View File

@ -25,8 +25,9 @@
#define _GC_VIDEO_H_
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__reset();
extern int gc_pal;
extern unsigned int *xfb[2];