From 0d58ff65e0bfe388d7dc37243e480f1069cb8486 Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Fri, 14 Aug 2009 13:54:15 +0000 Subject: [PATCH] fixed sound issues in PAL mode when HQ YM2612 is enabled (modified FIR resampler ratio) fixed video glitches in games that switch video horizontal width. fixed BIOS infinite loop on hard reset --- source/cart_hw/datel.c | 2 +- source/gx/gui/menu.c | 11 ++++++----- source/gx/gx_audio.c | 3 ++- source/gx/gx_video.c | 25 ++++++++++++++++--------- source/render.c | 4 ++-- source/sound/sound.c | 6 +++++- source/sound/ym2612.c | 5 ++++- source/system.c | 19 ++----------------- source/vdp.c | 30 ++++++++++++------------------ 9 files changed, 50 insertions(+), 55 deletions(-) diff --git a/source/cart_hw/datel.c b/source/cart_hw/datel.c index d26af01..8edd9bc 100644 --- a/source/cart_hw/datel.c +++ b/source/cart_hw/datel.c @@ -294,4 +294,4 @@ static void ar_write_regs(uint32 address, uint32 data) static void ar_write_regs_pro2(uint32 address, uint32 data) { /* TODO */ -} \ No newline at end of file +} diff --git a/source/gx/gui/menu.c b/source/gx/gui/menu.c index 1ad2550..c0604b0 100644 --- a/source/gx/gui/menu.c +++ b/source/gx/gui/menu.c @@ -2209,14 +2209,14 @@ void MainMenu (void) case 2: /*** Options */ GUI_DeleteMenu(m); - optionmenu (); + optionmenu(); GUI_InitMenu(m); break; case 3: /*** Memory Manager ***/ if (!cart.romsize) break; GUI_DeleteMenu(m); - quit = filemenu (); + quit = filemenu(); if (quit) break; GUI_InitMenu(m); break; @@ -2225,9 +2225,10 @@ void MainMenu (void) if (!cart.romsize) break; GUI_DrawMenuFX(m,10,1); GUI_DeleteMenu(m); - gxClearScreen ((GXColor)BLACK); + gxClearScreen((GXColor)BLACK); gxSetScreen(); - system_reset (); + system_init(); + system_reset(); quit = 1; break; @@ -2246,7 +2247,7 @@ void MainMenu (void) case 8: /*** ROM Information ***/ if (!cart.romsize) break; GUI_DeleteMenu(m); - showrominfo (); + showrominfo(); GUI_InitMenu(m); break; } diff --git a/source/gx/gx_audio.c b/source/gx/gx_audio.c index 67a9733..75b5d28 100644 --- a/source/gx/gx_audio.c +++ b/source/gx/gx_audio.c @@ -110,7 +110,8 @@ void gx_audio_Update(void) u32 size = dma_len; /* VIDEO interrupt synchronization: we approximate next DMA length (see below) */ - /* VSYNC period is 16715 us which is approx. 802.32 samples */ + /* In 50Hz mode, VSYNC period is 19967 usec which is approx 958.42 samples */ + /* In 60Hz mode, VSYNC period is 16715 usec which is approx. 802.32 samples */ /* DMA length should be a multiple of 32 bytes so we use either 800 or 808 samples */ if (dma_sync) { diff --git a/source/gx/gx_video.c b/source/gx/gx_video.c index e0932ae..ea680db 100644 --- a/source/gx/gx_video.c +++ b/source/gx/gx_video.c @@ -460,13 +460,13 @@ static void gxResetScale(u32 width, u32 height) if (config.overscan) { /* borders are emulated */ - xscale = 358 - gc_pal; + xscale = 358 + ((reg[12] & 1)*2) - gc_pal; yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120); } else { /* borders are simulated (black) */ - xscale = 328 - gc_pal; + xscale = 325 + ((reg[12] & 1)*2) - gc_pal; yscale = bitmap.viewport.h / 2; if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 240 / 288; else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 240; @@ -484,7 +484,7 @@ static void gxResetScale(u32 width, u32 height) if (config.overscan) { /* borders are emulated */ - xscale = 348; + xscale = 352; yscale = (gc_pal && !config.render) ? (vdp_pal ? (268*144 / bitmap.viewport.h):143) : (vdp_pal ? (224*144 / bitmap.viewport.h):120); } else @@ -1334,7 +1334,7 @@ void gx_video_Start(void) crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png,0); /* apply changes on next video update */ - bitmap.viewport.changed |= 1; + bitmap.viewport.changed = 1; /* reset GX rendering */ gxResetRendering(0); @@ -1343,12 +1343,19 @@ void gx_video_Start(void) /* GX render update */ void gx_video_Update(void) { + int update = bitmap.viewport.changed; + /* check if display has changed */ - if (bitmap.viewport.changed & 1) + if (update) { /* update texture size */ - vwidth = bitmap.viewport.w + 2 * bitmap.viewport.x; - vheight = bitmap.viewport.h + 2 * bitmap.viewport.y; + int old_vwidth = vwidth; + vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x); + vheight = bitmap.viewport.h + (2 * bitmap.viewport.y); + + /* if width has been changed, do no render this frame */ + /* this fixes texture glitches when changing width middle-frame */ + if (vwidth != old_vwidth) return; /* special cases */ if (config.render && interlaced) vheight = vheight << 1; @@ -1397,9 +1404,9 @@ void gx_video_Update(void) whichfb ^= 1; /* reconfigure VI */ - if (bitmap.viewport.changed & 1) + if (update) { - bitmap.viewport.changed &= 2; + bitmap.viewport.changed = 0; /* change VI mode */ VIDEO_Configure(rmode); diff --git a/source/render.c b/source/render.c index 1a08d98..b39257f 100644 --- a/source/render.c +++ b/source/render.c @@ -1679,7 +1679,7 @@ void remap_buffer(uint32 line, uint32 width) { /* get line offset from framebuffer */ line = (line + bitmap.viewport.y) % lines_per_frame; - + /* double resolution mode */ if (config.render && interlaced) line = (line * 2) + odd_frame; @@ -1690,7 +1690,7 @@ void remap_buffer(uint32 line, uint32 width) else sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line); return; } - + #ifdef NGC /* directly fill the RGB565 texture */ /* one tile is 32 byte = 4x4 pixels */ diff --git a/source/sound/sound.c b/source/sound/sound.c index 4e10e06..4c51fcc 100644 --- a/source/sound/sound.c +++ b/source/sound/sound.c @@ -73,7 +73,11 @@ void sound_init(int rate) if (config.hq_fm) { m68cycles_per_sample[0] = 144; - Fir_Resampler_time_ratio(vclk/144.0/(double)rate); + + /* "real" ratio is (vclk/144.0)/(rate) but this causes scratchy sound in Wii/GCN 50Hz video mode */ + /* since "real" framerate is lower than 50 fps whereas PAL Wii/GCN framerate is higher than 50 fps */ + /* it's better to directly use the ratio between generated & expected numbers of samples per frame */ + Fir_Resampler_time_ratio((double)m68cycles_per_line * (double)lines_per_frame * (double)vdp_rate / 144.0 / (double)rate); } /* initialize sound chips */ diff --git a/source/sound/ym2612.c b/source/sound/ym2612.c index 9f02a5b..1835279 100644 --- a/source/sound/ym2612.c +++ b/source/sound/ym2612.c @@ -1917,7 +1917,10 @@ void YM2612Update(int length) /* Output samples buffers */ int16 *bufFIR = Fir_Resampler_buffer(); - if (bufFIR) bufFIR += snd.fm.pos*2; + if (bufFIR) + { + bufFIR += (snd.fm.pos << 1); + } else { bufL = snd.fm.buffer[0] + snd.fm.pos; diff --git a/source/system.c b/source/system.c index aa39211..85b5ca6 100644 --- a/source/system.c +++ b/source/system.c @@ -79,7 +79,7 @@ void audio_update (int size) if (config.hq_fm) { int len = Fir_Resampler_input_needed(size * 2); - sound_update(len/2,size); + sound_update(len >> 1,size); Fir_Resampler_write(len); Fir_Resampler_read(fm,size); } @@ -201,9 +201,6 @@ void audio_shutdown(void) /* Resampling buffer */ Fir_Resampler_shutdown(); - - /* sn76489 chip (Blip Buffer allocated memory) */ - SN76489_Shutdown(); } /**************************************************************** @@ -282,24 +279,12 @@ int system_frame (int do_skip) interlaced = (reg[12] & 2) >> 1; if (old_interlaced != interlaced) { - bitmap.viewport.changed |= 1; + bitmap.viewport.changed = 1; im2_flag = ((reg[12] & 6) == 6); odd_frame = 1; } odd_frame ^= 1; -#ifdef NGC - if (bitmap.viewport.changed & 2) - { - /* Update the width of the viewport */ - bitmap.viewport.w = (reg[12] & 1) ? 320 : 256; - bitmap.viewport.changed = 1; - - /* Update clipping */ - window_clip(); - } -#endif - /* clear VBLANK and DMA flags */ status &= 0xFFF5; diff --git a/source/vdp.c b/source/vdp.c index 7571233..ac39346 100644 --- a/source/vdp.c +++ b/source/vdp.c @@ -211,9 +211,9 @@ void vdp_reset(void) bitmap.viewport.ow = 224; /* reset border area */ - bitmap.viewport.x = config.overscan ? 14 : 0; + bitmap.viewport.x = (reg[12] & 1) ? 16 : 12; bitmap.viewport.y = config.overscan ? (vdp_pal ? 32 : 8) : 0; - bitmap.viewport.changed = 2; + bitmap.viewport.changed = 1; /* initialize some registers (normally set by BIOS) */ if (config.bios_enabled != 3) @@ -245,9 +245,9 @@ void vdp_restore(uint8 *vdp_regs) hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32; /* reinitialize overscan area */ - bitmap.viewport.x = config.overscan ? 14 : 0; + bitmap.viewport.x = (reg[12] & 1) ? 16 : 12; bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0; - bitmap.viewport.changed = 2; + bitmap.viewport.changed = 1; /* restore VDP timings */ fifo_latency = (reg[12] & 1) ? 27 : 30; @@ -682,12 +682,13 @@ static inline void reg_w(unsigned int r, unsigned int d) /* See if the viewport height has actually been changed */ if ((d & 8) != (reg[1] & 8)) { - /* update the height of the viewport */ - bitmap.viewport.changed |= 1; + /* update viewport */ + bitmap.viewport.changed = 1; bitmap.viewport.h = (d & 8) ? 240 : 224; - - /* update overscan height */ - if (config.overscan) bitmap.viewport.y = ((vdp_pal ? 288 : 240) - bitmap.viewport.h) / 2; + if (config.overscan) + { + bitmap.viewport.y = ((vdp_pal ? 288 : 240) - bitmap.viewport.h) / 2; + } /* update VC table */ if (vdp_pal) vctab = (d & 8) ? vc_pal_240 : vc_pal_224; @@ -769,10 +770,9 @@ static inline void reg_w(unsigned int r, unsigned int d) /* Update HC table */ hctab = cycle2hc40; -#ifndef NGC /* Update viewport width */ bitmap.viewport.w = 320; -#endif + if (config.overscan) bitmap.viewport.x = 16; } else { @@ -785,22 +785,16 @@ static inline void reg_w(unsigned int r, unsigned int d) /* Update HC table */ hctab = cycle2hc32; -#ifndef NGC /* Update viewport width */ bitmap.viewport.w = 256; -#endif + if (config.overscan) bitmap.viewport.x = 12; } -#ifndef NGC /* Update viewport */ bitmap.viewport.changed = 1; /* Update clipping */ window_clip(); -#else - /* Postpound update on next frame */ - bitmap.viewport.changed = 2; -#endif } /* See if the S/TE mode bit has changed */