[Core/VDP] improved Mode 5 sprites rendering (fixes "Overdrive" demo)

This commit is contained in:
EkeEke 2013-10-20 20:53:33 +02:00
parent cbf8f4ed2a
commit 42ea79cf73
5 changed files with 318 additions and 251 deletions

View File

@ -1172,7 +1172,7 @@ void system_frame_sms(int do_skip)
/* Sprites are still processed during vertical borders */ /* Sprites are still processed during vertical borders */
if (reg[1] & 0x40) if (reg[1] & 0x40)
{ {
render_obj(bitmap.viewport.w); render_obj(1);
} }
} }
@ -1349,7 +1349,7 @@ void system_frame_sms(int do_skip)
if ((system_hw < SYSTEM_MD) && (line > (lines_per_frame - 16))) if ((system_hw < SYSTEM_MD) && (line > (lines_per_frame - 16)))
{ {
/* Sprites are still processed during top border */ /* Sprites are still processed during top border */
render_obj(bitmap.viewport.w); render_obj((line - lines_per_frame) & 1);
parse_satb(line - lines_per_frame); parse_satb(line - lines_per_frame);
} }

View File

@ -85,6 +85,7 @@ uint8 vdp_pal; /* 1: PAL , 0: NTSC (default) */
uint16 v_counter; /* Vertical counter */ uint16 v_counter; /* Vertical counter */
uint16 vc_max; /* Vertical counter overflow value */ uint16 vc_max; /* Vertical counter overflow value */
uint16 lines_per_frame; /* PAL: 313 lines, NTSC: 262 lines */ uint16 lines_per_frame; /* PAL: 313 lines, NTSC: 262 lines */
uint16 max_sprite_pixels; /* Max. sprites pixels per line (parsing & rendering) */
int32 fifo_write_cnt; /* VDP FIFO write count */ int32 fifo_write_cnt; /* VDP FIFO write count */
uint32 fifo_slots; /* VDP FIFO access slot count */ uint32 fifo_slots; /* VDP FIFO access slot count */
uint32 hvc_latch; /* latched HV counter */ uint32 hvc_latch; /* latched HV counter */
@ -278,6 +279,9 @@ void vdp_reset(void)
bitmap.viewport.ow = 256; bitmap.viewport.ow = 256;
bitmap.viewport.oh = 192; bitmap.viewport.oh = 192;
/* default sprite pixel width */
max_sprite_pixels = 256;
/* default overscan area */ /* default overscan area */
if ((system_hw == SYSTEM_GG) && !config.gg_extra) if ((system_hw == SYSTEM_GG) && !config.gg_extra)
{ {
@ -1575,21 +1579,28 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
if ((r & 0x40) && (v_counter < bitmap.viewport.h)) if ((r & 0x40) && (v_counter < bitmap.viewport.h))
{ {
/* Cycle offset vs HBLANK */ /* Cycle offset vs HBLANK */
int offset = cycles - mcycles_vdp - 860; int offset = cycles - mcycles_vdp;
if (offset <= 0) if (offset <= 860)
{ {
/* If display was disabled during HBLANK (Mickey Mania 3D level), sprite rendering is limited */ /* Sprite rendering is limited if display was disabled during HBLANK (Mickey Mania 3d level, Overdrive Demo) */
if ((d & 0x40) && (object_count > 5) && (offset >= -500)) if (d & 0x40)
{ {
object_count = 5; /* NB: This is not 100% accurate. On real hardware, the maximal number of rendered sprites pixels */
/* for the current line (normally 256 or 320 pixels) but also the maximal number of pre-processed */
/* sprites for the next line (normally 64 or 80 sprites) are both reduced depending on the amount */
/* of cycles spent with display disabled. Here we only reduce them by a fixed amount when display */
/* has been reenabled after a specific point within HBLANK. */
if (offset > 360)
{
max_sprite_pixels = 128;
}
} }
/* Redraw entire line (Legend of Galahad, Lemmings 2, Formula One, Kawasaki Super Bike, Deadly Moves,...) */ /* Redraw entire line (Legend of Galahad, Lemmings 2, Formula One, Kawasaki Super Bike, Deadly Moves,...) */
render_line(v_counter); render_line(v_counter);
#ifdef LOGVDP /* Restore default */
error("Line redrawn (%d sprites) \n",object_count); max_sprite_pixels = 256 + ((reg[12] & 1) << 6);
#endif
} }
else if (system_hw & SYSTEM_MD) else if (system_hw & SYSTEM_MD)
{ {
@ -1597,20 +1608,17 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
if (reg[12] & 1) if (reg[12] & 1)
{ {
/* dot clock = MCLK / 8 */ /* dot clock = MCLK / 8 */
offset = (offset / 8); offset = ((offset - 860) / 8) + 16;
} }
else else
{ {
/* dot clock = MCLK / 10 */ /* dot clock = MCLK / 10 */
offset = (offset / 10) + 16; offset = ((offset - 860) / 10) + 16;
} }
/* Line is partially blanked (Nigel Mansell's World Championship Racing , Ren & Stimpy Show, ...) */ /* Line is partially blanked (Nigel Mansell's World Championship Racing , Ren & Stimpy Show, ...) */
if (offset < bitmap.viewport.w) if (offset < bitmap.viewport.w)
{ {
#ifdef LOGVDP
error("Line %d redrawn from pixel %d\n",v_counter,offset);
#endif
if (d & 0x40) if (d & 0x40)
{ {
render_line(v_counter); render_line(v_counter);
@ -1974,6 +1982,9 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
/* Update clipping */ /* Update clipping */
window_clip(reg[17], 1); window_clip(reg[17], 1);
/* Max. sprite pixels per line */
max_sprite_pixels = 320;
} }
else else
{ {
@ -1988,6 +1999,9 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
/* Update clipping */ /* Update clipping */
window_clip(reg[17], 0); window_clip(reg[17], 0);
/* Max. sprite pixels per line */
max_sprite_pixels = 256;
} }
/* Active display width modified during HBLANK (Bugs Bunny Double Trouble) */ /* Active display width modified during HBLANK (Bugs Bunny Double Trouble) */

View File

@ -74,6 +74,7 @@ extern uint16 v_counter;
extern uint16 vc_max; extern uint16 vc_max;
extern uint16 vscroll; extern uint16 vscroll;
extern uint16 lines_per_frame; extern uint16 lines_per_frame;
extern uint16 max_sprite_pixels;
extern int32 fifo_write_cnt; extern int32 fifo_write_cnt;
extern uint32 fifo_slots; extern uint32 fifo_slots;
extern uint32 hvc_latch; extern uint32 hvc_latch;

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,6 @@
#define _RENDER_H_ #define _RENDER_H_
/* Global variables */ /* Global variables */
extern uint8 object_count;
extern uint16 spr_col; extern uint16 spr_col;
/* Function prototypes */ /* Function prototypes */
@ -53,24 +52,24 @@ extern void render_line(int line);
extern void blank_line(int line, int offset, int width); extern void blank_line(int line, int offset, int width);
extern void remap_line(int line); extern void remap_line(int line);
extern void window_clip(unsigned int data, unsigned int sw); extern void window_clip(unsigned int data, unsigned int sw);
extern void render_bg_m0(int line, int width); extern void render_bg_m0(int line);
extern void render_bg_m1(int line, int width); extern void render_bg_m1(int line);
extern void render_bg_m1x(int line, int width); extern void render_bg_m1x(int line);
extern void render_bg_m2(int line, int width); extern void render_bg_m2(int line);
extern void render_bg_m3(int line, int width); extern void render_bg_m3(int line);
extern void render_bg_m3x(int line, int width); extern void render_bg_m3x(int line);
extern void render_bg_inv(int line, int width); extern void render_bg_inv(int line);
extern void render_bg_m4(int line, int width); extern void render_bg_m4(int line);
extern void render_bg_m5(int line, int width); extern void render_bg_m5(int line);
extern void render_bg_m5_vs(int line, int width); extern void render_bg_m5_vs(int line);
extern void render_bg_m5_im2(int line, int width); extern void render_bg_m5_im2(int line);
extern void render_bg_m5_im2_vs(int line, int width); extern void render_bg_m5_im2_vs(int line);
extern void render_obj_tms(int max_width); extern void render_obj_tms(int line);
extern void render_obj_m4(int max_width); extern void render_obj_m4(int line);
extern void render_obj_m5(int max_width); extern void render_obj_m5(int line);
extern void render_obj_m5_ste(int max_width); extern void render_obj_m5_ste(int line);
extern void render_obj_m5_im2(int max_width); extern void render_obj_m5_im2(int line);
extern void render_obj_m5_im2_ste(int max_width); extern void render_obj_m5_im2_ste(int line);
extern void parse_satb_tms(int line); extern void parse_satb_tms(int line);
extern void parse_satb_m4(int line); extern void parse_satb_m4(int line);
extern void parse_satb_m5(int line); extern void parse_satb_m5(int line);
@ -80,8 +79,8 @@ extern void color_update_m4(int index, unsigned int data);
extern void color_update_m5(int index, unsigned int data); extern void color_update_m5(int index, unsigned int data);
/* Function pointers */ /* Function pointers */
extern void (*render_bg)(int line, int width); extern void (*render_bg)(int line);
extern void (*render_obj)(int max_width); extern void (*render_obj)(int line);
extern void (*parse_satb)(int line); extern void (*parse_satb)(int line);
extern void (*update_bg_pattern_cache)(int index); extern void (*update_bg_pattern_cache)(int index);