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 */ /* reinitialize overscan area */
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0; 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.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
bitmap.viewport.changed = 1;
} }
break; break;
@ -371,7 +370,6 @@ void dispmenu ()
config.render = 0; config.render = 0;
} }
} }
bitmap.viewport.changed = 1;
break; break;
case 2: /*** tv mode ***/ case 2: /*** tv mode ***/
@ -381,20 +379,17 @@ void dispmenu ()
case 3: /*** bilinear filtering ***/ case 3: /*** bilinear filtering ***/
config.bilinear ^= 1; config.bilinear ^= 1;
bitmap.viewport.changed = 1;
break; break;
case 4: /*** NTSC filter ***/ case 4: /*** NTSC filter ***/
config.ntsc ++; config.ntsc ++;
if (config.ntsc > 3) config.ntsc = 0; if (config.ntsc > 3) config.ntsc = 0;
bitmap.viewport.changed = 1;
break; break;
case 5: /*** overscan emulation ***/ case 5: /*** overscan emulation ***/
config.overscan ^= 1; config.overscan ^= 1;
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0; 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.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
bitmap.viewport.changed = 1;
break; break;
case 6: /*** Center X ***/ case 6: /*** Center X ***/
@ -1134,13 +1129,6 @@ void MainMenu ()
{"System Reboot"} {"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) */ /* autosave (SRAM only) */
int temp = config.freeze_auto; int temp = config.freeze_auto;
config.freeze_auto = -1; config.freeze_auto = -1;
@ -1221,14 +1209,6 @@ void MainMenu ()
while (WPAD_ButtonsHeld(0)) WPAD_ScanPads(); while (WPAD_ButtonsHeld(0)) WPAD_ScanPads();
#endif #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 #ifndef HW_RVL
/*** Stop the DVD from causing clicks while playing ***/ /*** Stop the DVD from causing clicks while playing ***/
uselessinquiry (); uselessinquiry ();

View File

@ -187,14 +187,18 @@ int main (int argc, char *argv[])
MainMenu(); MainMenu();
ConfigRequested = 0; ConfigRequested = 0;
/* Reset frame sync */
frameticker = 0;
FrameCount = 0;
RenderedFrameCount = 0;
/* Start Audio & Video */
ogc_audio__start();
ogc_video__start();
/* Emulation Loop */ /* Emulation Loop */
while (1) 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) if (gc_pal < 0)
{ {
/* this code is NEVER executed */ /* this code is NEVER executed */
@ -210,6 +214,9 @@ int main (int argc, char *argv[])
/* frameskipping */ /* frameskipping */
frameticker--; frameticker--;
system_frame (1); system_frame (1);
/* update audio only */
ogc_audio__update();
} }
else else
{ {
@ -219,14 +226,14 @@ int main (int argc, char *argv[])
/* frame rendering */ /* frame rendering */
system_frame (0); system_frame (0);
RenderedFrameCount++; RenderedFrameCount++;
}
frameticker--;
}
/* update video & audio */ /* update video & audio */
ogc_audio__update(); ogc_audio__update();
ogc_video__update(); ogc_video__update();
}
frameticker--;
}
/* check rendered frames (FPS) */ /* check rendered frames (FPS) */
FrameCount++; FrameCount++;
@ -240,8 +247,9 @@ int main (int argc, char *argv[])
/* Check for Menu request */ /* Check for Menu request */
if (ConfigRequested) if (ConfigRequested)
{ {
/* stop Audio */ /* stop Audio & Video */
ogc_audio__stop(); ogc_audio__stop();
ogc_video__stop();
/* go to menu */ /* go to menu */
MainMenu (); MainMenu ();
@ -252,6 +260,9 @@ int main (int argc, char *argv[])
FrameCount = 0; FrameCount = 0;
RenderedFrameCount = 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 */ /* Current work soundbuffer */
int mixbuffer; 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) /* Current DMA length (required to be a factor of 32-bytes)
length is calculated regarding current emulation timings: 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) 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) void ogc_audio__start(void)
{ {
if (!IsPlaying)
{
dma_len = vdp_pal ? 3840 : 3200; dma_len = vdp_pal ? 3840 : 3200;
memset(soundbuffer[0], 0, dma_len); memset(soundbuffer[0], 0, dma_len);
AUDIO_InitDMA((u32) soundbuffer[0], dma_len); AUDIO_InitDMA((u32) soundbuffer[0], dma_len);
DCFlushRange(soundbuffer[0], dma_len); DCFlushRange(soundbuffer[0], dma_len);
AUDIO_StartDMA(); AUDIO_StartDMA();
IsPlaying = 1;
mixbuffer = 1; mixbuffer = 1;
}
} }
/*** /***
@ -121,5 +114,4 @@ void ogc_audio__start(void)
void ogc_audio__stop(void) void ogc_audio__stop(void)
{ {
AUDIO_StopDMA (); AUDIO_StopDMA ();
IsPlaying = 0;
} }

View File

@ -303,8 +303,14 @@ static camera cam = {
{0.0F, 0.0F, 0.0F} {0.0F, 0.0F, 0.0F}
}; };
/* rendering initialization */ void xfb_swap(u32 cnt)
/* should be called each time you change quad aspect ratio */ {
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
whichfb ^= 1;
}
/* Rendering Initialization */
static void draw_init(void) static void draw_init(void)
{ {
/* Clear all Vertex params */ /* Clear all Vertex params */
@ -329,7 +335,7 @@ static void draw_init(void)
GX_LoadPosMtxImm (view, GX_PNMTX0); GX_LoadPosMtxImm (view, GX_PNMTX0);
} }
/* vertex rendering */ /* Vertex Rendering */
static inline void draw_vert(u8 pos, f32 s, f32 t) static inline void draw_vert(u8 pos, f32 s, f32 t)
{ {
GX_Position1x8 (pos); GX_Position1x8 (pos);
@ -394,7 +400,7 @@ static void gxScale(GXRModeObj *rmode)
int temp = 0; int temp = 0;
int xscale, yscale, xshift, yshift; int xscale, yscale, xshift, yshift;
/* Aspect Ratio (depending on current configuration) */ /* aspect Ratio (depends on current configuration) */
if (config.aspect) if (config.aspect)
{ {
/* original aspect ratio */ /* original aspect ratio */
@ -441,14 +447,14 @@ static void gxScale(GXRModeObj *rmode)
yshift = config.yshift; yshift = config.yshift;
} }
/* Double resolution modes */ /* double resolution modes */
if (config.render) if (config.render)
{ {
yscale *= 2; yscale *= 2;
yshift *= 2; yshift *= 2;
} }
/* GX Scaler (by default, use EFB maximal width) */ /* GX scaler (by default, use EFB maximal width) */
rmode->fbWidth = 640; rmode->fbWidth = 640;
if (!config.bilinear && !config.ntsc) if (!config.bilinear && !config.ntsc)
{ {
@ -459,7 +465,7 @@ static void gxScale(GXRModeObj *rmode)
else if (width <= 640) rmode->fbWidth = width; else if (width <= 640) rmode->fbWidth = width;
} }
/* Horizontal Scaling (GX/VI) */ /* horizontal scaling (GX/VI) */
if (xscale > (rmode->fbWidth/2)) if (xscale > (rmode->fbWidth/2))
{ {
/* max width = 720 pixels */ /* max width = 720 pixels */
@ -494,48 +500,20 @@ static void gxScale(GXRModeObj *rmode)
GX_InvVtxCache (); GX_InvVtxCache ();
} }
/* Reinitialize Video */ /* Reset Video Mode */
void ogc_video__reset() static void gxReset(void)
{ {
Mtx p; Mtx p;
GXRModeObj *rmode; GXRModeObj *rmode;
/* 50Hz/60Hz mode */ /* select TV 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 */
if (config.render) rmode = tvmodes[gc_pal*3 + 2]; if (config.render) rmode = tvmodes[gc_pal*3 + 2];
else rmode = tvmodes[gc_pal*3 + interlaced]; else rmode = tvmodes[gc_pal*3 + interlaced];
/* Aspect ratio */ /* reset aspect ratio */
gxScale(rmode); gxScale(rmode);
/* Configure VI */ /* configure GX */
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 */
GX_SetViewport (0.0F, 0.0F, rmode->fbWidth, rmode->efbHeight, 0.0F, 1.0F); GX_SetViewport (0.0F, 0.0F, rmode->fbWidth, rmode->efbHeight, 0.0F, 1.0F);
GX_SetScissor (0, 0, rmode->fbWidth, rmode->efbHeight); GX_SetScissor (0, 0, rmode->fbWidth, rmode->efbHeight);
f32 yScale = GX_GetYScaleFactor(rmode->efbHeight, rmode->xfbHeight); f32 yScale = GX_GetYScaleFactor(rmode->efbHeight, rmode->xfbHeight);
@ -549,7 +527,62 @@ void ogc_video__reset()
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC); GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
GX_Flush (); 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) if (config.ntsc == 1)
{ {
sms_setup = sms_ntsc_composite; sms_setup = sms_ntsc_composite;
@ -571,6 +604,9 @@ void ogc_video__reset()
sms_ntsc_init( &sms_ntsc, &sms_setup ); sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup ); md_ntsc_init( &md_ntsc, &md_setup );
} }
/* apply changes on next video update */
bitmap.viewport.changed = 1;
} }
/* GX render update */ /* GX render update */
@ -593,8 +629,8 @@ void ogc_video__update()
vwidth = vwidth / 4; vwidth = vwidth / 4;
vheight = vheight / 4; vheight = vheight / 4;
/* image size has changed, reset GX */ /* reset Video mode */
ogc_video__reset(); gxReset();
/* reinitialize texture */ /* reinitialize texture */
GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
@ -619,14 +655,9 @@ void ogc_video__update()
draw_square (); draw_square ();
GX_DrawDone (); GX_DrawDone ();
/* switch external framebuffers then copy EFB to XFB */ /* copy EFB to current XFB */
whichfb ^= 1; GX_CopyDisp (xfb[odd_frame], GX_TRUE);
GX_CopyDisp (xfb[whichfb], GX_TRUE);
GX_Flush (); GX_Flush ();
/* set next XFB */
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
} }
/* Initialize VIDEO subsystem */ /* Initialize VIDEO subsystem */
@ -704,7 +735,7 @@ void ogc_video__init(void)
} }
#endif #endif
/* Configure VIDEO mode */ /* Configure VI */
VIDEO_Configure (vmode); VIDEO_Configure (vmode);
/* Configure the framebuffers (double-buffering) */ /* Configure the framebuffers (double-buffering) */

View File

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