Merge pull request #22 from alexkiri/enhanced_vscroll

Enchanced per-tile vertical scroll
This commit is contained in:
ds22x 2022-08-13 13:53:40 +02:00 committed by GitHub
commit 7b43fcd3ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 756 additions and 2 deletions

View File

@ -1743,7 +1743,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;
}
@ -1957,7 +1957,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:
@ -1902,6 +1903,322 @@ 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);
}
void render_bg_m5_vs_enhanced(int line)
{
int column, v_offset;
int start_real, end_real;
uint32 atex, atbuf, *src, *dst;
uint32 v_line, next_v_line, *nt;
uint32 yscroll = 0, pf_col_mask, pf_row_mask, pf_shift;
uint32 *vs;
int a, w, start = 0, end;
uint32 shift, index;
/* Common data */
uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)];
if (
(render_obj == render_obj_m5) ||
(render_obj == render_obj_m5_im2) ||
(render_obj == render_obj_m5_im2_ste) ||
(render_obj == render_obj_m5_ste)
) {
xscroll = (
((xscroll + config.h40_extra_columns * 4) & 0xFFFF) +
((xscroll + ((config.h40_extra_columns * 4) << 16)) & 0xFFFF0000)
);
}
pf_col_mask = playfield_col_mask;
pf_row_mask = playfield_row_mask;
pf_shift = playfield_shift;
vs = (uint32 *)&vsram[0];
/* Window & Plane A */
a = (reg[18] & 0x1F) << 3;
w = (reg[18] >> 7) & 1;
/* Plane B width */
end = bitmap.viewport.w >> 4;
/* 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
/* 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++)
{
int column_capped = column - (config.h40_extra_columns / 4);
column_capped = MAX(0, MIN(column_capped, 19));
/* Plane B vertical scroll */
#ifdef LSB_FIRST
v_line = (line + (vs[column_capped] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column_capped + 1] >> 16)) & pf_row_mask;
#else
v_line = (line + vs[column_capped]) & pf_row_mask;
next_v_line = (line + vs[column_capped + 1]) & pf_row_mask;
#endif
if (column >= (config.h40_extra_columns / 4) && column < (config.h40_extra_columns / 4) + 19)
{
/* The offset of the intermediary cell is an average of the offsets of the current 2-cell and the next 2-cell. */
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
else {
v_offset = 0;
}
/* 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_capped] >> 16)) & pf_row_mask;
#else
v_line = (line + v_offset + vs[column_capped]) & 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++)
{
int column_capped = column - (config.h40_extra_columns / 4);
column_capped = MAX(0, MIN(column_capped, 19));
/* Plane A vertical scroll */
#ifdef LSB_FIRST
v_line = (line + vs[column_capped]) & pf_row_mask & pf_row_mask;
next_v_line = (line + vs[column_capped + 1]) & pf_row_mask;
#else
v_line = (line + (vs[column_capped] >> 16)) & pf_row_mask & pf_row_mask;
next_v_line = (line + (vs[column_capped + 1] >> 16)) & pf_row_mask;
#endif
if (column >= (config.h40_extra_columns / 4) && column < (config.h40_extra_columns / 4) + 19)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
else {
v_offset = 0;
}
/* 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)];
start_real = start + (config.h40_extra_columns / 4);
end_real = end - (config.h40_extra_columns / 4);
for(column = start; column < end; column++)
{
atbuf = nt[column - (config.h40_extra_columns / 4)];
if ((column >= start_real) && (column < end_real)) {
DRAW_COLUMN(atbuf, v_line)
} else {
*dst++ = 0; *dst++ = 0; *dst++ = 0; *dst++ = 0;
}
}
}
/* 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 start_real, end_real;
@ -2684,6 +3001,370 @@ 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)];
if (
(render_obj == render_obj_m5) ||
(render_obj == render_obj_m5_im2) ||
(render_obj == render_obj_m5_im2_ste) ||
(render_obj == render_obj_m5_ste)
) {
xscroll = (
((xscroll + config.h40_extra_columns * 4) & 0xFFFF) +
((xscroll + ((config.h40_extra_columns * 4) << 16)) & 0xFFFF0000)
);
}
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++)
{
int column_capped = column - (config.h40_extra_columns / 4);
column_capped = MAX(0, MIN(column_capped, 19));
/* Plane A vertical scroll */
#ifdef LSB_FIRST
v_line = (line + vs[column_capped]) & pf_row_mask;
next_v_line = (line + vs[column_capped + 1]) & pf_row_mask;
#else
v_line = (line + (vs[column_capped] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column_capped + 1] >> 16)) & pf_row_mask;
#endif
if (column >= (config.h40_extra_columns / 4) && column < (config.h40_extra_columns / 4) + 19)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
else {
v_offset = 0;
}
/* 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_capped]) & pf_row_mask;
#else
v_line = (line + v_offset + (vs[column_capped] >> 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;
int start_real = start + (config.h40_extra_columns / 4);
int end_real = end - (config.h40_extra_columns / 4);
for(column = start; column < end; column++)
{
atbuf = nt[column - (config.h40_extra_columns / 4)];
if ((column >= start_real) && (column < end_real)) {
DRAW_COLUMN(atbuf, v_line)
} else {
*dst++ = 0; *dst++ = 0; *dst++ = 0; *dst++ = 0;
}
}
}
/* 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++)
{
int column_capped = column - (config.h40_extra_columns / 4);
column_capped = MAX(0, MIN(column_capped, 19));
/* Plane B vertical scroll */
#ifdef LSB_FIRST
v_line = (line + (vs[column_capped] >> 16)) & pf_row_mask;
next_v_line = (line + (vs[column_capped + 1] >> 16)) & pf_row_mask;
#else
v_line = (line + vs[column_capped]) & pf_row_mask;
next_v_line = (line + vs[column_capped + 1]) & pf_row_mask;
#endif
if (column >= (config.h40_extra_columns / 4) && column < (config.h40_extra_columns / 4) + 19)
{
v_offset = ((int)next_v_line - (int)v_line) / 2;
v_offset = (abs(v_offset) >= config.enhanced_vscroll_limit) ? 0 : v_offset;
}
else {
v_offset = 0;
}
/* 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_capped] >> 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_capped]) & 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_capped] >> 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_capped]) & 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

@ -79,6 +79,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

@ -49,6 +49,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

@ -138,6 +138,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

@ -951,6 +951,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;
@ -1852,6 +1854,19 @@ static void check_variables(bool first_run)
config.no_sprite_limit = 1;
}
var.key = CORE_NAME "_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 = CORE_NAME "_enhanced_vscroll_limit";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
config.enhanced_vscroll_limit = strtol(var.value, NULL, 10);
var.key = CORE_NAME "_h40_extra_columns";
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
{

View File

@ -755,6 +755,47 @@ struct retro_core_option_v2_definition option_defs_us[] = {
},
"disabled"
},
{
CORE_NAME "_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"
},
{
CORE_NAME "_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
{
CORE_NAME "_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;
#ifdef USE_PER_SOUND_CHANNELS_CONFIG
unsigned int psg_ch_volumes[4];
int32 md_ch_volumes[6];

View File

@ -35,6 +35,8 @@ void set_config_defaults(void)
config.add_on = 0; /* = HW_ADDON_AUTO (or HW_ADDON_MEGACD, HW_ADDON_MEGASD & HW_ADDON_NONE) */
config.ntsc = 0;
config.lcd = 0; /* 0.8 fixed point */
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
/* display options */
config.overscan = 0; /* 3 = all borders (0 = no borders , 1 = vertical borders only, 2 = horizontal borders only) */

View File

@ -48,6 +48,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

@ -38,6 +38,8 @@ void set_config_defaults(void)
config.add_on = 0; /* = HW_ADDON_AUTO (or HW_ADDON_MEGACD, HW_ADDON_MEGASD & HW_ADDON_ONE) */
config.ntsc = 0;
config.lcd = 0; /* 0.8 fixed point */
config.enhanced_vscroll = 0;
config.enhanced_vscroll_limit = 8;
/* display options */
config.overscan = 0; /* 3 = all borders (0 = no borders , 1 = vertical borders only, 2 = horizontal borders only) */

View File

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