mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-24 02:01:48 +01:00
changed VIDEO synchronization
This commit is contained in:
parent
4dbedcdc04
commit
3ee65ad74b
@ -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 ();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) */
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user