Enchanced per-tile vertical scroll (#453)

* Enchanced per-tile vertical scroll implementation

* Comment cleanup
This commit is contained in:
Kiri 2022-08-13 09:11:41 +03:00 committed by GitHub
parent 47d20265c9
commit e5f77f14b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 700 additions and 2 deletions

View File

@ -1691,7 +1691,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
}
else
{
render_bg = (reg[11] & 0x04) ? render_bg_m5_vs : render_bg_m5;
render_bg = (reg[11] & 0x04) ? (config.enhanced_vscroll ? render_bg_m5_vs_enhanced : render_bg_m5_vs) : render_bg_m5;
render_obj = (reg[12] & 0x08) ? render_obj_m5_ste : render_obj_m5;
}
@ -1902,7 +1902,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
/* Vertical Scrolling mode */
if (d & 0x04)
{
render_bg = im2_flag ? render_bg_m5_im2_vs : render_bg_m5_vs;
render_bg = im2_flag ? render_bg_m5_im2_vs : (config.enhanced_vscroll ? render_bg_m5_vs_enhanced : render_bg_m5_vs);
}
else
{

View File

@ -6,6 +6,7 @@
*
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
* Copyright (C) 2022 AlexKiri (enhanced vscroll mode rendering function)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@ -1847,6 +1848,292 @@ void render_bg_m5_vs(int line)
merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w);
}
/* Enhanced function that allows each cell to be vscrolled individually, instead of being limited to 2-cell */
void render_bg_m5_vs_enhanced(int line)
{
int column, v_offset;
uint32 atex, atbuf, *src, *dst;
uint32 v_line, next_v_line, *nt;
/* Common data */
uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)];
uint32 yscroll = 0;
uint32 pf_col_mask = playfield_col_mask;
uint32 pf_row_mask = playfield_row_mask;
uint32 pf_shift = playfield_shift;
uint32 *vs = (uint32 *)&vsram[0];
/* Window & Plane A */
int a = (reg[18] & 0x1F) << 3;
int w = (reg[18] >> 7) & 1;
/* Plane B width */
int start = 0;
int end = bitmap.viewport.w >> 4;
/* Plane B horizontal scroll */
#ifdef LSB_FIRST
uint32 shift = (xscroll >> 16) & 0x0F;
uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
#else
uint32 shift = (xscroll & 0x0F);
uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
#endif
/* Left-most column vertical scrolling when partially shown horizontally (verified on PAL MD2) */
/* TODO: check on Genesis 3 models since it apparently behaves differently */
/* In H32 mode, vertical scrolling is disabled, in H40 mode, same value is used for both planes */
/* See Formula One / Kawasaki Superbike Challenge (H32) & Gynoug / Cutie Suzuki no Ringside Angel (H40) */
if (reg[12] & 1)
{
yscroll = vs[19] & (vs[19] >> 16);
}
if(shift)
{
/* Plane B vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
/* Plane B line buffer */
dst = (uint32 *)&linebuf[0][0x10 + shift];
atbuf = nt[(index - 1) & pf_col_mask];
DRAW_COLUMN(atbuf, v_line)
}
else
{
/* Plane B line buffer */
dst = (uint32 *)&linebuf[0][0x20];
}
for(column = 0; column < end; column++, index++)
{
/* Plane B vertical scroll */
#ifdef LSB_FIRST
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#else
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#endif
if (column != end - 1)
{
/* The offset of the intermediary cell is an average of the offsets of the current 2-cell and the next 2-cell. */
/* For the last column, the previously calculated offset is used */
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
#else
GET_MSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
#ifdef LSB_FIRST
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
#else
v_line = (line + v_offset + vs[column]) & pf_row_mask;
#endif
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_MSB_TILE(atbuf, v_line)
#else
GET_LSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
}
if (w == (line >= a))
{
/* Window takes up entire line */
a = 0;
w = 1;
}
else
{
/* Window and Plane A share the line */
a = clip[0].enable;
w = clip[1].enable;
}
/* Plane A */
if (a)
{
/* Plane A width */
start = clip[0].left;
end = clip[0].right;
/* Plane A horizontal scroll */
#ifdef LSB_FIRST
shift = (xscroll & 0x0F);
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
#else
shift = (xscroll >> 16) & 0x0F;
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
#endif
if(shift)
{
/* Plane A vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
/* Plane A line buffer */
dst = (uint32 *)&linebuf[1][0x10 + shift + (start << 4)];
/* Window bug */
if (start)
{
atbuf = nt[index & pf_col_mask];
}
else
{
atbuf = nt[(index - 1) & pf_col_mask];
}
DRAW_COLUMN(atbuf, v_line)
}
else
{
/* Plane A line buffer */
dst = (uint32 *)&linebuf[1][0x20 + (start << 4)];
}
for(column = start; column < end; column++, index++)
{
/* Plane A vertical scroll */
#ifdef LSB_FIRST
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#else
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#endif
if (column != end - 1)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
#else
GET_MSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
#ifdef LSB_FIRST
v_line = (line + v_offset + vs[column]) & pf_row_mask;
#else
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
#endif
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_MSB_TILE(atbuf, v_line)
#else
GET_LSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
}
/* Window width */
start = clip[1].left;
end = clip[1].right;
}
/* Window */
if (w)
{
/* Window name table */
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
/* Pattern row index */
v_line = (line & 7) << 3;
/* Plane A line buffer */
dst = (uint32 *)&linebuf[1][0x20 + (start << 4)];
for(column = start; column < end; column++)
{
atbuf = nt[column];
DRAW_COLUMN(atbuf, v_line)
}
}
/* Merge background layers */
merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w);
}
void render_bg_m5_im2(int line)
{
int column;
@ -2543,6 +2830,342 @@ void render_bg_m5_vs(int line)
}
}
void render_bg_m5_vs_enhanced(int line)
{
int column, start, end, v_offset;
uint32 atex, atbuf, *src, *dst;
uint32 shift, index, v_line, next_v_line, *nt;
uint8 *lb;
/* Scroll Planes common data */
uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)];
uint32 yscroll = 0;
uint32 pf_col_mask = playfield_col_mask;
uint32 pf_row_mask = playfield_row_mask;
uint32 pf_shift = playfield_shift;
uint32 *vs = (uint32 *)&vsram[0];
/* Number of columns to draw */
int width = bitmap.viewport.w >> 4;
/* Layer priority table */
uint8 *table = lut[(reg[12] & 8) >> 2];
/* Window vertical range (cell 0-31) */
int a = (reg[18] & 0x1F) << 3;
/* Window position (0=top, 1=bottom) */
int w = (reg[18] >> 7) & 1;
/* Test against current line */
if (w == (line >= a))
{
/* Window takes up entire line */
a = 0;
w = 1;
}
else
{
/* Window and Plane A share the line */
a = clip[0].enable;
w = clip[1].enable;
}
/* Left-most column vertical scrolling when partially shown horizontally */
/* Same value for both planes, only in 40-cell mode, verified on PAL MD2 */
/* See Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge */
if (reg[12] & 1)
{
yscroll = vs[19] & (vs[19] >> 16);
}
/* Plane A*/
if (a)
{
/* Plane A width */
start = clip[0].left;
end = clip[0].right;
/* Plane A horizontal scroll */
#ifdef LSB_FIRST
shift = (xscroll & 0x0F);
index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask);
#else
shift = (xscroll >> 16) & 0x0F;
index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask);
#endif
/* Background line buffer */
dst = (uint32 *)&linebuf[0][0x20 + (start << 4) + shift];
if(shift)
{
/* Left-most column is partially shown */
dst -= 4;
/* Plane A vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
/* Window bug */
if (start)
{
atbuf = nt[index & pf_col_mask];
}
else
{
atbuf = nt[(index-1) & pf_col_mask];
}
DRAW_COLUMN(atbuf, v_line)
}
for(column = start; column < end; column++, index++)
{
/* Plane A vertical scroll */
#ifdef LSB_FIRST
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#else
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#endif
if (column != end - 1)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane A name table */
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
#else
GET_MSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
#ifdef LSB_FIRST
v_line = (line + v_offset + vs[column]) & pf_row_mask;
#else
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
#endif
nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef LSB_FIRST
GET_MSB_TILE(atbuf, v_line)
#else
GET_LSB_TILE(atbuf, v_line)
#endif
#ifdef ALIGN_LONG
WRITE_LONG(dst, src[0] | atex);
dst++;
WRITE_LONG(dst, src[1] | atex);
dst++;
#else
*dst++ = (src[0] | atex);
*dst++ = (src[1] | atex);
#endif
}
/* Window width */
start = clip[1].left;
end = clip[1].right;
}
else
{
/* Window width */
start = 0;
end = width;
}
/* Window Plane */
if (w)
{
/* Background line buffer */
dst = (uint32 *)&linebuf[0][0x20 + (start << 4)];
/* Window name table */
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
/* Pattern row index */
v_line = (line & 7) << 3;
for(column = start; column < end; column++)
{
atbuf = nt[column];
DRAW_COLUMN(atbuf, v_line)
}
}
/* Plane B horizontal scroll */
#ifdef LSB_FIRST
shift = (xscroll >> 16) & 0x0F;
index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask);
#else
shift = (xscroll & 0x0F);
index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
#endif
/* Background line buffer */
lb = &linebuf[0][0x20];
if(shift)
{
/* Left-most column is partially shown */
lb -= (0x10 - shift);
/* Plane B vertical scroll */
v_line = (line + yscroll) & pf_row_mask;
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[(index-1) & pf_col_mask];
DRAW_BG_COLUMN(atbuf, v_line, xscroll, yscroll)
}
for(column = 0; column < width; column++, index++)
{
/* Plane B vertical scroll */
#ifdef LSB_FIRST
v_line = (line + (vs[column] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column + 1] >> 16)) & pf_row_mask;
#else
v_line = (line + vs[column]) & pf_row_mask;
next_v_line = (line + vs[column + 1]) & pf_row_mask;
#endif
if (column != width - 1)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
/* Plane B name table */
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
/* Pattern row index */
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
#ifdef ALIGN_LONG
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_MSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#else
GET_MSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + vs[column]) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_LSB_TILE(atbuf, v_line)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = READ_LONG((uint32 *)lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#endif
#else /* NOT ALIGNED */
#ifdef LSB_FIRST
GET_LSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + v_offset + (vs[column] >> 16)) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_MSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#else
GET_MSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
v_line = (line + vs[column]) & pf_row_mask;
nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)];
v_line = (v_line & 7) << 3;
atbuf = nt[index & pf_col_mask];
GET_LSB_TILE(atbuf, v_line)
xscroll = *(uint32 *)(lb);
yscroll = (src[0] | atex);
DRAW_BG_TILE(xscroll, yscroll)
xscroll = *(uint32 *)(lb);
yscroll = (src[1] | atex);
DRAW_BG_TILE(xscroll, yscroll)
#endif
#endif /* ALIGN_LONG */
}
}
void render_bg_m5_im2(int line)
{
int column, start, end;

View File

@ -118,6 +118,7 @@ extern void render_bg_inv(int line);
extern void render_bg_m4(int line);
extern void render_bg_m5(int line);
extern void render_bg_m5_vs(int line);
extern void render_bg_m5_vs_enhanced(int line);
extern void render_bg_m5_im2(int line);
extern void render_bg_m5_im2_vs(int line);
extern void render_obj_tms(int line);

View File

@ -82,6 +82,8 @@ void set_config_defaults(void)
config.a_stick = 1; /* 1 = A-Stick on */
config.lightgun_speed = 1; /* 1 = simple speed multiplier for lightgun */
config.gcw0_frameskip = 0; /* 0 = off, 1 = skip alternate frames, 2 = skip 2 in 3 frames, etc. Useful for FMV in MCD. */
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
/* controllers options */
config.cursor = 0; /* different cursor designs */

View File

@ -52,6 +52,8 @@ typedef struct
uint8 ntsc;
uint8 lcd;
uint8 render;
uint8 enhanced_vscroll;
uint8 enhanced_vscroll_limit;
t_input_config input[MAX_INPUTS];
uint8 gcw0_fullscreen;
uint8 gcw0_frameskip;

View File

@ -141,6 +141,8 @@ void config_default(void)
config.vsync = 1; /* AUTO */
config.bilinear = 0;
config.vfilter = 1;
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
if (VIDEO_HaveComponentCable())
{

View File

@ -83,6 +83,8 @@ typedef struct
uint8 ntsc;
uint8 vsync;
uint8 render;
uint8 enhanced_vscroll;
uint8 enhanced_vscroll_limit;
uint8 tv_mode;
uint8 bilinear;
uint8 vfilter;

View File

@ -950,6 +950,8 @@ static void config_default(void)
config.overclock = 100;
#endif
config.no_sprite_limit = 0;
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
/* video options */
config.overscan = 0;
@ -1863,6 +1865,19 @@ static void check_variables(bool first_run)
config.no_sprite_limit = 1;
}
var.key = "genesis_plus_gx_enhanced_vscroll";
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
{
if (!var.value || !strcmp(var.value, "disabled"))
config.enhanced_vscroll = 0;
else
config.enhanced_vscroll = 1;
}
var.key = "genesis_plus_gx_enhanced_vscroll_limit";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
config.enhanced_vscroll_limit = strtol(var.value, NULL, 10);
#ifdef USE_PER_SOUND_CHANNELS_CONFIG
var.key = psg_channel_volume_base_str;
for (c = 0; c < 4; c++)

View File

@ -782,6 +782,47 @@ struct retro_core_option_v2_definition option_defs_us[] = {
},
"disabled"
},
{
"genesis_plus_gx_enhanced_vscroll",
"Enchanced per-tile vertical scroll",
NULL,
"Allows each individual cell to be scrolled vertically, instead of 16px 2-cell, by averaging out with the vscroll value of the neighbouring cell. This hack only applies to few games that use 2-cell vertical scroll mode.",
NULL,
"hacks",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"genesis_plus_gx_enhanced_vscroll_limit",
"Enchanced per-tile vertical scroll limit",
NULL,
"Only when Enchance per-tile vertical scroll is enabled. Adjusts the limit of the vertical scroll enhancement. When the vscroll difference between neighbouring tiles is bigger than this limit, the enhancement is disabled.",
NULL,
"hacks",
{
{ "2", NULL },
{ "3", NULL },
{ "4", NULL },
{ "5", NULL },
{ "6", NULL },
{ "7", NULL },
{ "8", NULL },
{ "9", NULL },
{ "10", NULL },
{ "11", NULL },
{ "12", NULL },
{ "13", NULL },
{ "14", NULL },
{ "15", NULL },
{ "16", NULL },
{ NULL, NULL },
},
"8"
},
#ifdef HAVE_OVERCLOCK
{
"genesis_plus_gx_overclock",

View File

@ -133,6 +133,8 @@ typedef struct
uint8 gun_cursor;
uint32 overclock;
uint8 no_sprite_limit;
uint8 enhanced_vscroll;
uint8 enhanced_vscroll_limit;
uint8 cd_latency;
#ifdef USE_PER_SOUND_CHANNELS_CONFIG
unsigned int psg_ch_volumes[4];

View File

@ -43,6 +43,8 @@ void set_config_defaults(void)
config.render = 0; /* 1 = double resolution output (only when interlaced mode 2 is enabled) */
config.ntsc = 0;
config.lcd = 0; /* 0.8 fixed point */
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
/* controllers options */
input.system[0] = SYSTEM_GAMEPAD;

View File

@ -51,6 +51,8 @@ typedef struct
uint8 ntsc;
uint8 lcd;
uint8 render;
uint8 enhanced_vscroll;
uint8 enhanced_vscroll_limit;
t_input_config input[MAX_INPUTS];
} t_config;

View File

@ -46,6 +46,8 @@ void set_config_defaults(void)
config.render = 0; /* 1 = double resolution output (only when interlaced mode 2 is enabled) */
config.ntsc = 0;
config.lcd = 0; /* 0.8 fixed point */
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
/* controllers options */
input.system[0] = SYSTEM_GAMEPAD;

View File

@ -51,6 +51,8 @@ typedef struct
uint8 ntsc;
uint8 lcd;
uint8 render;
uint8 enhanced_vscroll;
uint8 enhanced_vscroll_limit;
t_input_config input[MAX_INPUTS];
} t_config;