mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-25 18:51:49 +01:00
fixed original interlaced mode desync (hack)
This commit is contained in:
parent
cb7149fb6b
commit
4dbedcdc04
@ -26,7 +26,7 @@ INCLUDES := source source/m68k source/z80 source/sound source/sound/SRC source/n
|
|||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
CFLAGS = -O3 -g -mrvl -Wall $(MACHDEP) -Wno-strict-aliasing $(INCLUDE) -DWORDS_BIGENDIAN -DNGC="1" -DHW_RVL
|
CFLAGS = -O3 -mrvl -Wall $(MACHDEP) -Wno-strict-aliasing $(INCLUDE) -DWORDS_BIGENDIAN -DNGC="1" -DHW_RVL
|
||||||
CXXFLAGS = $(CFLAGS)
|
CXXFLAGS = $(CFLAGS)
|
||||||
|
|
||||||
LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||||
|
@ -89,7 +89,7 @@ void eeprom_init()
|
|||||||
sram.custom = 0;
|
sram.custom = 0;
|
||||||
|
|
||||||
/* look into game database */
|
/* look into game database */
|
||||||
while ((i<24) && (!sram.custom))
|
while ((i<25) && (!sram.custom))
|
||||||
{
|
{
|
||||||
if (strstr(rominfo.product,database[i].game_id) != NULL)
|
if (strstr(rominfo.product,database[i].game_id) != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1136,8 +1136,7 @@ void MainMenu ()
|
|||||||
|
|
||||||
/* Switch to menu default rendering mode (60hz or 50hz, but always 480 lines) */
|
/* Switch to menu default rendering mode (60hz or 50hz, but always 480 lines) */
|
||||||
VIDEO_Configure (vmode);
|
VIDEO_Configure (vmode);
|
||||||
VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
|
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
|
||||||
VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
|
|
||||||
VIDEO_Flush();
|
VIDEO_Flush();
|
||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
@ -1222,11 +1221,11 @@ void MainMenu ()
|
|||||||
while (WPAD_ButtonsHeld(0)) WPAD_ScanPads();
|
while (WPAD_ButtonsHeld(0)) WPAD_ScanPads();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** Reinitialize VIDEO ***/
|
/*** Reinitialize GX ***/
|
||||||
VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
|
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
|
||||||
VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
|
|
||||||
VIDEO_Flush();
|
VIDEO_Flush();
|
||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
|
VIDEO_WaitVSync();
|
||||||
ogc_video__reset();
|
ogc_video__reset();
|
||||||
odd_frame = 1;
|
odd_frame = 1;
|
||||||
|
|
||||||
|
@ -125,16 +125,16 @@ bool fat_enabled = 0;
|
|||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
long long now, prev;
|
|
||||||
int RenderedFrameCount = 0;
|
|
||||||
int FrameCount = 0;
|
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
/* initialize Wii DVD interface first */
|
/* initialize Wii DVD interface first */
|
||||||
DI_Close();
|
DI_Close();
|
||||||
DI_Init();
|
DI_Init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
long long now, prev;
|
||||||
|
int RenderedFrameCount = 0;
|
||||||
|
int FrameCount = 0;
|
||||||
|
|
||||||
/* initialize OGC subsystems */
|
/* initialize OGC subsystems */
|
||||||
ogc_video__init();
|
ogc_video__init();
|
||||||
ogc_input__init();
|
ogc_input__init();
|
||||||
@ -173,7 +173,7 @@ int main (int argc, char *argv[])
|
|||||||
set_history_defaults();
|
set_history_defaults();
|
||||||
history_load();
|
history_load();
|
||||||
|
|
||||||
/* initialize VM */
|
/* Initialize Virtual Machine */
|
||||||
init_machine ();
|
init_machine ();
|
||||||
|
|
||||||
/* load any injected rom */
|
/* load any injected rom */
|
||||||
@ -183,30 +183,17 @@ int main (int argc, char *argv[])
|
|||||||
reloadrom ();
|
reloadrom ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* show Menu first */
|
/* Show Menu */
|
||||||
ConfigRequested = 1;
|
|
||||||
|
|
||||||
/* main emulation loop */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Check for Menu request */
|
|
||||||
if (ConfigRequested)
|
|
||||||
{
|
|
||||||
/* stop Audio */
|
|
||||||
ogc_audio__stop();
|
|
||||||
|
|
||||||
/* go to Menu */
|
|
||||||
MainMenu();
|
MainMenu();
|
||||||
ConfigRequested = 0;
|
ConfigRequested = 0;
|
||||||
|
|
||||||
/* reset frame sync */
|
/* Emulation Loop */
|
||||||
frameticker = 0;
|
while (1)
|
||||||
FrameCount = 0;
|
{
|
||||||
RenderedFrameCount = 0;
|
|
||||||
|
|
||||||
/* restart sound loop */
|
|
||||||
ogc_audio__start();
|
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)
|
||||||
{
|
{
|
||||||
@ -220,31 +207,28 @@ int main (int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
if (frameticker > 1)
|
if (frameticker > 1)
|
||||||
{
|
{
|
||||||
/* skip one frame */
|
/* frameskipping */
|
||||||
frameticker--;
|
frameticker--;
|
||||||
system_frame (1);
|
system_frame (1);
|
||||||
|
|
||||||
/* update audio only */
|
|
||||||
ogc_audio__update();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* frame sync */
|
/* frame sync */
|
||||||
while (frameticker < 1) usleep(1);
|
while (!frameticker) usleep(1);
|
||||||
|
|
||||||
/* render one frame */
|
/* frame rendering */
|
||||||
system_frame (0);
|
system_frame (0);
|
||||||
RenderedFrameCount++;
|
RenderedFrameCount++;
|
||||||
|
|
||||||
/* update audio & video */
|
|
||||||
ogc_audio__update();
|
|
||||||
ogc_video__update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frameticker--;
|
frameticker--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check rendered frame count (FPS) */
|
/* update video & audio */
|
||||||
|
ogc_audio__update();
|
||||||
|
ogc_video__update();
|
||||||
|
|
||||||
|
/* check rendered frames (FPS) */
|
||||||
FrameCount++;
|
FrameCount++;
|
||||||
if (FrameCount == vdp_rate)
|
if (FrameCount == vdp_rate)
|
||||||
{
|
{
|
||||||
@ -252,6 +236,23 @@ int main (int argc, char *argv[])
|
|||||||
RenderedFrameCount = 0;
|
RenderedFrameCount = 0;
|
||||||
FrameCount = 0;
|
FrameCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for Menu request */
|
||||||
|
if (ConfigRequested)
|
||||||
|
{
|
||||||
|
/* stop Audio */
|
||||||
|
ogc_audio__stop();
|
||||||
|
|
||||||
|
/* go to menu */
|
||||||
|
MainMenu ();
|
||||||
|
ConfigRequested = 0;
|
||||||
|
|
||||||
|
/* reset frame sync */
|
||||||
|
frameticker = 0;
|
||||||
|
FrameCount = 0;
|
||||||
|
RenderedFrameCount = 0;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -35,8 +35,8 @@ u8 soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
|
|||||||
/* Current work soundbuffer */
|
/* Current work soundbuffer */
|
||||||
int mixbuffer;
|
int mixbuffer;
|
||||||
|
|
||||||
/* Status of Audio playback */
|
/* Current DMA status (1: DMA in progress, 0: DMA stopped) */
|
||||||
static int AudioStarted = 0;
|
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:
|
||||||
@ -98,14 +98,18 @@ void ogc_audio__update(void)
|
|||||||
DMA parameters can be updated using successive calls to AUDIO_InitDMA (see above)
|
DMA parameters can be updated using successive calls to AUDIO_InitDMA (see above)
|
||||||
***/
|
***/
|
||||||
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);
|
||||||
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();
|
||||||
AudioStarted = 1;
|
IsPlaying = 1;
|
||||||
mixbuffer = 1;
|
mixbuffer = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
ogc_audio__stop
|
ogc_audio__stop
|
||||||
@ -115,11 +119,7 @@ void ogc_audio__start(void)
|
|||||||
DMA need to be restarted when going back to the game (see above)
|
DMA need to be restarted when going back to the game (see above)
|
||||||
***/
|
***/
|
||||||
void ogc_audio__stop(void)
|
void ogc_audio__stop(void)
|
||||||
{
|
|
||||||
if (AudioStarted)
|
|
||||||
{
|
{
|
||||||
AUDIO_StopDMA ();
|
AUDIO_StopDMA ();
|
||||||
AudioStarted = 0;
|
IsPlaying = 0;
|
||||||
memset(soundbuffer, 0, 2 * 3840);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ u8 *texturemem; /*** Texture Data ***/
|
|||||||
|
|
||||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
||||||
static GXTexObj texobj;
|
static GXTexObj texobj;
|
||||||
static u8 do_copy = GX_FALSE;
|
|
||||||
static Mtx view;
|
static Mtx view;
|
||||||
static u32 vwidth, vheight;
|
static u32 vwidth, vheight;
|
||||||
|
|
||||||
@ -491,7 +490,6 @@ static void gxScale(GXRModeObj *rmode)
|
|||||||
square[4] = square[1] = yscale + yshift;
|
square[4] = square[1] = yscale + yshift;
|
||||||
square[7] = square[10] = -yscale + yshift;
|
square[7] = square[10] = -yscale + yshift;
|
||||||
|
|
||||||
/* flush data from cache */
|
|
||||||
DCFlushRange (square, 32);
|
DCFlushRange (square, 32);
|
||||||
GX_InvVtxCache ();
|
GX_InvVtxCache ();
|
||||||
}
|
}
|
||||||
@ -621,38 +619,15 @@ void ogc_video__update()
|
|||||||
draw_square ();
|
draw_square ();
|
||||||
GX_DrawDone ();
|
GX_DrawDone ();
|
||||||
|
|
||||||
/* postpound XFB update */
|
/* switch external framebuffers then copy EFB to XFB */
|
||||||
do_copy = GX_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pre-Retrace handler
|
|
||||||
synchronize XFB switch with VSYNC
|
|
||||||
*/
|
|
||||||
void xfb_switch(u32 cnt)
|
|
||||||
{
|
|
||||||
if (!ConfigRequested)
|
|
||||||
{
|
|
||||||
/* switch external framebuffers */
|
|
||||||
whichfb ^= 1;
|
whichfb ^= 1;
|
||||||
|
GX_CopyDisp (xfb[whichfb], GX_TRUE);
|
||||||
|
GX_Flush ();
|
||||||
|
|
||||||
/* set next XFB */
|
/* set next XFB */
|
||||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||||
VIDEO_Flush ();
|
VIDEO_Flush ();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Post-Retrace handler
|
|
||||||
synchronize XFB copy with VSYNC */
|
|
||||||
void xfb_copy(u32 cnt)
|
|
||||||
{
|
|
||||||
if (do_copy)
|
|
||||||
{
|
|
||||||
/* copy EFB to XFB */
|
|
||||||
GX_CopyDisp (xfb[whichfb], GX_TRUE);
|
|
||||||
GX_Flush ();
|
|
||||||
do_copy = GX_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize VIDEO subsystem */
|
/* Initialize VIDEO subsystem */
|
||||||
void ogc_video__init(void)
|
void ogc_video__init(void)
|
||||||
@ -746,10 +721,6 @@ void ogc_video__init(void)
|
|||||||
/* Set the framebuffer to be displayed at next VBlank */
|
/* Set the framebuffer to be displayed at next VBlank */
|
||||||
VIDEO_SetNextFramebuffer (xfb[0]);
|
VIDEO_SetNextFramebuffer (xfb[0]);
|
||||||
|
|
||||||
/* Set Vertical Interrupt callbacks for VIDEO synchronization */
|
|
||||||
VIDEO_SetPreRetraceCallback(xfb_switch);
|
|
||||||
VIDEO_SetPostRetraceCallback(xfb_copy);
|
|
||||||
|
|
||||||
/* Enable Video Interface */
|
/* Enable Video Interface */
|
||||||
VIDEO_SetBlack (FALSE);
|
VIDEO_SetBlack (FALSE);
|
||||||
|
|
||||||
|
@ -91,8 +91,8 @@ int system_frame (int do_skip)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int aim_m68k = 0;
|
uint32 aim_m68k = 0;
|
||||||
int aim_z80 = 0;
|
uint32 aim_z80 = 0;
|
||||||
|
|
||||||
/* reset cycles counts */
|
/* reset cycles counts */
|
||||||
count_m68k = 0;
|
count_m68k = 0;
|
||||||
|
16
source/vdp.c
16
source/vdp.c
@ -74,11 +74,12 @@ int32 fifo_write_cnt; /* VDP writes fifo count */
|
|||||||
uint32 fifo_lastwrite; /* last VDP write cycle */
|
uint32 fifo_lastwrite; /* last VDP write cycle */
|
||||||
uint8 fifo_latency; /* VDP write cycles latency */
|
uint8 fifo_latency; /* VDP write cycles latency */
|
||||||
uint8 odd_frame; /* 1: odd field, 0: even field */
|
uint8 odd_frame; /* 1: odd field, 0: even field */
|
||||||
uint8 interlaced; /* 1: Interlace mode 1 or 2 */
|
|
||||||
uint8 im2_flag; /* 1= Interlace mode 2 is being used */
|
uint8 im2_flag; /* 1= Interlace mode 2 is being used */
|
||||||
uint8 vdp_pal; /* 0: NTSC, 1: PAL */
|
uint8 interlaced; /* 1: Interlaced mode 1 or 2 */
|
||||||
uint8 vdp_rate; /* NTSC: 60hz, PAL: 50hz */
|
uint8 vdp_pal = 0; /* 1: PAL , 0: NTSC (default) */
|
||||||
uint16 lines_per_frame; /* NTSC: 262 lines, PAL: 313 lines */
|
uint8 vdp_rate; /* PAL: 50hz, NTSC: 60hz */
|
||||||
|
uint16 lines_per_frame; /* PAL: 313 lines, NTSC: 262 lines */
|
||||||
|
|
||||||
|
|
||||||
/* Tables that define the playfield layout */
|
/* Tables that define the playfield layout */
|
||||||
static const uint8 shift_table[] = { 6, 7, 0, 8 };
|
static const uint8 shift_table[] = { 6, 7, 0, 8 };
|
||||||
@ -136,7 +137,7 @@ static inline void data_write(unsigned int data);
|
|||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void vdp_init(void)
|
void vdp_init(void)
|
||||||
{
|
{
|
||||||
/* DMA timings */
|
/* reinitialize DMA timings table */
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<4; i++)
|
for (i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
@ -201,6 +202,7 @@ void vdp_reset(void)
|
|||||||
|
|
||||||
im2_flag = 0;
|
im2_flag = 0;
|
||||||
interlaced = 0;
|
interlaced = 0;
|
||||||
|
odd_frame = 0;
|
||||||
|
|
||||||
fifo_write_cnt = 0;
|
fifo_write_cnt = 0;
|
||||||
|
|
||||||
@ -229,10 +231,6 @@ void vdp_reset(void)
|
|||||||
window_clip(1,0);
|
window_clip(1,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non-interlaced display */
|
|
||||||
odd_frame = 0;
|
|
||||||
interlaced = 0;
|
|
||||||
|
|
||||||
/* default latency */
|
/* default latency */
|
||||||
fifo_latency = 27;
|
fifo_latency = 27;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user