mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-25 02:31:49 +01:00
Enchanced per-tile vertical scroll (#453)
* Enchanced per-tile vertical scroll implementation * Comment cleanup
This commit is contained in:
parent
47d20265c9
commit
e5f77f14b9
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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++)
|
||||
|
@ -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",
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user