mirror of
https://github.com/libretro/Genesis-Plus-GX-Wide.git
synced 2024-11-23 08:19:44 +00:00
Merge pull request #22 from alexkiri/enhanced_vscroll
Enchanced per-tile vertical scroll
This commit is contained in:
commit
7b43fcd3ac
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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);
|
||||
{
|
||||
|
@ -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",
|
||||
|
@ -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];
|
||||
|
@ -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) */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) */
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user