diff --git a/core/vdp_render.c b/core/vdp_render.c index c4a1876..6b65e22 100644 --- a/core/vdp_render.c +++ b/core/vdp_render.c @@ -43,6 +43,14 @@ #include "md_ntsc.h" #include "sms_ntsc.h" +#ifndef HAVE_NO_SPRITE_LIMIT +#define MAX_SPRITES_PER_LINE 20 +#define TMS_MAX_SPRITES_PER_LINE 4 +#define MODE4_MAX_SPRITES_PER_LINE 8 +#define MODE5_MAX_SPRITES_PER_LINE (bitmap.viewport.w >> 4) +#define MODE5_MAX_SPRITE_PIXELS max_sprite_pixels +#endif + /*** NTSC Filters ***/ extern md_ntsc_t *md_ntsc; extern sms_ntsc_t *sms_ntsc; @@ -584,7 +592,7 @@ typedef struct uint16 size; } object_info_t; -static object_info_t obj_info[2][20]; +static object_info_t obj_info[2][MAX_SPRITES_PER_LINE]; /* Sprite Counter */ static uint8 object_count[2]; @@ -3149,6 +3157,7 @@ void render_obj_m5(int line) int xpos, width; int pixelcount = 0; int masked = 0; + int max_pixels = MODE5_MAX_SPRITE_PIXELS; uint8 *src, *s, *lb; uint32 temp, v_line; @@ -3213,10 +3222,10 @@ void render_obj_m5(int line) lb = &linebuf[0][0x20 + xpos]; /* Max. number of sprite pixels rendered per line */ - if (pixelcount > max_sprite_pixels) + if (pixelcount > max_pixels) { /* Adjust number of pixels to draw */ - width -= (pixelcount - max_sprite_pixels); + width -= (pixelcount - max_pixels); } /* Number of tiles to draw */ @@ -3235,7 +3244,7 @@ void render_obj_m5(int line) } /* Sprite limit */ - if (pixelcount >= max_sprite_pixels) + if (pixelcount >= max_pixels) { /* Sprite masking is effective on next line if max pixel width is reached */ spr_ovr = (pixelcount >= bitmap.viewport.w); @@ -3258,6 +3267,7 @@ void render_obj_m5_ste(int line) int xpos, width; int pixelcount = 0; int masked = 0; + int max_pixels = MODE5_MAX_SPRITE_PIXELS; uint8 *src, *s, *lb; uint32 temp, v_line; @@ -3325,9 +3335,9 @@ void render_obj_m5_ste(int line) lb = &linebuf[1][0x20 + xpos]; /* Adjust number of pixels to draw for sprite limit */ - if (pixelcount > max_sprite_pixels) + if (pixelcount > max_pixels) { - width -= (pixelcount - max_sprite_pixels); + width -= (pixelcount - max_pixels); } /* Number of tiles to draw */ @@ -3346,7 +3356,7 @@ void render_obj_m5_ste(int line) } /* Sprite limit */ - if (pixelcount >= max_sprite_pixels) + if (pixelcount >= max_pixels) { /* Sprite masking is effective on next line if max pixel width is reached */ spr_ovr = (pixelcount >= bitmap.viewport.w); @@ -3376,6 +3386,7 @@ void render_obj_m5_im2(int line) int pixelcount = 0; int masked = 0; int odd = odd_frame; + int max_pixels = MODE5_MAX_SPRITE_PIXELS; uint8 *src, *s, *lb; uint32 temp, v_line; @@ -3440,9 +3451,9 @@ void render_obj_m5_im2(int line) lb = &linebuf[0][0x20 + xpos]; /* Adjust width for sprite limit */ - if (pixelcount > max_sprite_pixels) + if (pixelcount > max_pixels) { - width -= (pixelcount - max_sprite_pixels); + width -= (pixelcount - max_pixels); } /* Number of tiles to draw */ @@ -3461,7 +3472,7 @@ void render_obj_m5_im2(int line) } /* Sprite Limit */ - if (pixelcount >= max_sprite_pixels) + if (pixelcount >= max_pixels) { /* Sprite masking is effective on next line if max pixel width is reached */ spr_ovr = (pixelcount >= bitmap.viewport.w); @@ -3485,6 +3496,7 @@ void render_obj_m5_im2_ste(int line) int pixelcount = 0; int masked = 0; int odd = odd_frame; + int max_pixels = MODE5_MAX_SPRITE_PIXELS; uint8 *src, *s, *lb; uint32 temp, v_line; @@ -3552,9 +3564,9 @@ void render_obj_m5_im2_ste(int line) lb = &linebuf[1][0x20 + xpos]; /* Adjust width for sprite limit */ - if (pixelcount > max_sprite_pixels) + if (pixelcount > max_pixels) { - width -= (pixelcount - max_sprite_pixels); + width -= (pixelcount - max_pixels); } /* Number of tiles to draw */ @@ -3573,7 +3585,7 @@ void render_obj_m5_im2_ste(int line) } /* Sprite Limit */ - if (pixelcount >= max_sprite_pixels) + if (pixelcount >= max_pixels) { /* Sprite masking is effective on next line if max pixel width is reached */ spr_ovr = (pixelcount >= bitmap.viewport.w); @@ -3654,7 +3666,7 @@ void parse_satb_tms(int line) if ((ypos >= 0) && (ypos < height)) { /* Sprite overflow */ - if (count == 4) + if (count == TMS_MAX_SPRITES_PER_LINE) { /* Flag is set only during active area */ if (line < bitmap.viewport.h) @@ -3750,7 +3762,7 @@ void parse_satb_m4(int line) if ((ypos >= 0) && (ypos < height)) { /* Sprite overflow */ - if (count == 8) + if (count == MODE4_MAX_SPRITES_PER_LINE) { /* Flag is set only during active area */ if ((line >= 0) && (line < bitmap.viewport.h)) @@ -3796,7 +3808,7 @@ void parse_satb_m5(int line) int count = 0; /* max. number of rendered sprites (16 or 20 sprites per line by default) */ - int max = bitmap.viewport.w >> 4; + int max = MODE5_MAX_SPRITES_PER_LINE; /* max. number of parsed sprites (64 or 80 sprites per line by default) */ int total = max_sprite_pixels >> 2; diff --git a/libretro/libretro.c b/libretro/libretro.c index 61f2865..35f3d1e 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -543,6 +543,7 @@ static void config_default(void) #ifdef HAVE_OVERCLOCK config.overclock = 0; #endif + config.no_sprite_limit = 0; /* video options */ config.overscan = 0; @@ -1271,6 +1272,15 @@ static void check_variables(void) } #endif + var.key = "genesis_plus_gx_no_sprite_limit"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + if (strcmp(var.value, "disabled") == 0) + config.no_sprite_limit = 0; + else + config.no_sprite_limit = 1; + } + if (reinit) { #ifdef HAVE_OVERCLOCK @@ -1718,6 +1728,7 @@ void retro_set_environment(retro_environment_t cb) #ifdef HAVE_OVERCLOCK { "genesis_plus_gx_overclock", "CPU speed; 100%|125%|150%|175%|200%" }, #endif + { "genesis_plus_gx_no_sprite_limit", "Remove per-line sprite limit; disabled|enabled" }, { NULL, NULL }, }; diff --git a/libretro/osd.h b/libretro/osd.h index cbd1a78..61e2f36 100644 --- a/libretro/osd.h +++ b/libretro/osd.h @@ -76,6 +76,13 @@ typedef unsigned char bool; #define HAVE_YM3438_CORE +#define HAVE_NO_SPRITE_LIMIT +#define MAX_SPRITES_PER_LINE 80 +#define TMS_MAX_SPRITES_PER_LINE (config.no_sprite_limit ? MAX_SPRITES_PER_LINE : 4) +#define MODE4_MAX_SPRITES_PER_LINE (config.no_sprite_limit ? MAX_SPRITES_PER_LINE : 8) +#define MODE5_MAX_SPRITES_PER_LINE (config.no_sprite_limit ? MAX_SPRITES_PER_LINE : (bitmap.viewport.w >> 4)) +#define MODE5_MAX_SPRITE_PIXELS (config.no_sprite_limit ? MAX_SPRITES_PER_LINE * 32 : max_sprite_pixels) + typedef struct { int8 device; @@ -121,6 +128,7 @@ struct uint8 invert_mouse; uint8 gun_cursor; uint32 overclock; + uint8 no_sprite_limit; } config; extern char GG_ROM[256];