mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
Merge branch 'master' of https://github.com/ekeeke/Genesis-Plus-GX
This commit is contained in:
commit
f5f192fc0a
@ -1691,7 +1691,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
|
|||||||
}
|
}
|
||||||
else
|
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;
|
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 */
|
/* Vertical Scrolling mode */
|
||||||
if (d & 0x04)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
||||||
* Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
|
* 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
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* 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);
|
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)
|
void render_bg_m5_im2(int line)
|
||||||
{
|
{
|
||||||
int column;
|
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)
|
void render_bg_m5_im2(int line)
|
||||||
{
|
{
|
||||||
int column, start, end;
|
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_m4(int line);
|
||||||
extern void render_bg_m5(int line);
|
extern void render_bg_m5(int line);
|
||||||
extern void render_bg_m5_vs(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(int line);
|
||||||
extern void render_bg_m5_im2_vs(int line);
|
extern void render_bg_m5_im2_vs(int line);
|
||||||
extern void render_obj_tms(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.a_stick = 1; /* 1 = A-Stick on */
|
||||||
config.lightgun_speed = 1; /* 1 = simple speed multiplier for lightgun */
|
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.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 */
|
/* controllers options */
|
||||||
config.cursor = 0; /* different cursor designs */
|
config.cursor = 0; /* different cursor designs */
|
||||||
|
@ -52,6 +52,8 @@ typedef struct
|
|||||||
uint8 ntsc;
|
uint8 ntsc;
|
||||||
uint8 lcd;
|
uint8 lcd;
|
||||||
uint8 render;
|
uint8 render;
|
||||||
|
uint8 enhanced_vscroll;
|
||||||
|
uint8 enhanced_vscroll_limit;
|
||||||
t_input_config input[MAX_INPUTS];
|
t_input_config input[MAX_INPUTS];
|
||||||
uint8 gcw0_fullscreen;
|
uint8 gcw0_fullscreen;
|
||||||
uint8 gcw0_frameskip;
|
uint8 gcw0_frameskip;
|
||||||
|
@ -141,6 +141,8 @@ void config_default(void)
|
|||||||
config.vsync = 1; /* AUTO */
|
config.vsync = 1; /* AUTO */
|
||||||
config.bilinear = 0;
|
config.bilinear = 0;
|
||||||
config.vfilter = 1;
|
config.vfilter = 1;
|
||||||
|
config.enhanced_vscroll = 0;
|
||||||
|
config.enhanced_vscroll_limit = 8;
|
||||||
|
|
||||||
if (VIDEO_HaveComponentCable())
|
if (VIDEO_HaveComponentCable())
|
||||||
{
|
{
|
||||||
|
@ -83,6 +83,8 @@ typedef struct
|
|||||||
uint8 ntsc;
|
uint8 ntsc;
|
||||||
uint8 vsync;
|
uint8 vsync;
|
||||||
uint8 render;
|
uint8 render;
|
||||||
|
uint8 enhanced_vscroll;
|
||||||
|
uint8 enhanced_vscroll_limit;
|
||||||
uint8 tv_mode;
|
uint8 tv_mode;
|
||||||
uint8 bilinear;
|
uint8 bilinear;
|
||||||
uint8 vfilter;
|
uint8 vfilter;
|
||||||
|
@ -950,6 +950,8 @@ static void config_default(void)
|
|||||||
config.overclock = 100;
|
config.overclock = 100;
|
||||||
#endif
|
#endif
|
||||||
config.no_sprite_limit = 0;
|
config.no_sprite_limit = 0;
|
||||||
|
config.enhanced_vscroll = 0;
|
||||||
|
config.enhanced_vscroll_limit = 8;
|
||||||
|
|
||||||
/* video options */
|
/* video options */
|
||||||
config.overscan = 0;
|
config.overscan = 0;
|
||||||
@ -1863,6 +1865,19 @@ static void check_variables(bool first_run)
|
|||||||
config.no_sprite_limit = 1;
|
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
|
#ifdef USE_PER_SOUND_CHANNELS_CONFIG
|
||||||
var.key = psg_channel_volume_base_str;
|
var.key = psg_channel_volume_base_str;
|
||||||
for (c = 0; c < 4; c++)
|
for (c = 0; c < 4; c++)
|
||||||
|
@ -782,6 +782,47 @@ struct retro_core_option_v2_definition option_defs_us[] = {
|
|||||||
},
|
},
|
||||||
"disabled"
|
"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
|
#ifdef HAVE_OVERCLOCK
|
||||||
{
|
{
|
||||||
"genesis_plus_gx_overclock",
|
"genesis_plus_gx_overclock",
|
||||||
|
@ -133,6 +133,8 @@ typedef struct
|
|||||||
uint8 gun_cursor;
|
uint8 gun_cursor;
|
||||||
uint32 overclock;
|
uint32 overclock;
|
||||||
uint8 no_sprite_limit;
|
uint8 no_sprite_limit;
|
||||||
|
uint8 enhanced_vscroll;
|
||||||
|
uint8 enhanced_vscroll_limit;
|
||||||
uint8 cd_latency;
|
uint8 cd_latency;
|
||||||
#ifdef USE_PER_SOUND_CHANNELS_CONFIG
|
#ifdef USE_PER_SOUND_CHANNELS_CONFIG
|
||||||
unsigned int psg_ch_volumes[4];
|
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.render = 0; /* 1 = double resolution output (only when interlaced mode 2 is enabled) */
|
||||||
config.ntsc = 0;
|
config.ntsc = 0;
|
||||||
config.lcd = 0; /* 0.8 fixed point */
|
config.lcd = 0; /* 0.8 fixed point */
|
||||||
|
config.enhanced_vscroll = 0;
|
||||||
|
config.enhanced_vscroll_limit = 8;
|
||||||
|
|
||||||
/* controllers options */
|
/* controllers options */
|
||||||
input.system[0] = SYSTEM_GAMEPAD;
|
input.system[0] = SYSTEM_GAMEPAD;
|
||||||
|
@ -51,6 +51,8 @@ typedef struct
|
|||||||
uint8 ntsc;
|
uint8 ntsc;
|
||||||
uint8 lcd;
|
uint8 lcd;
|
||||||
uint8 render;
|
uint8 render;
|
||||||
|
uint8 enhanced_vscroll;
|
||||||
|
uint8 enhanced_vscroll_limit;
|
||||||
t_input_config input[MAX_INPUTS];
|
t_input_config input[MAX_INPUTS];
|
||||||
} t_config;
|
} 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.render = 0; /* 1 = double resolution output (only when interlaced mode 2 is enabled) */
|
||||||
config.ntsc = 0;
|
config.ntsc = 0;
|
||||||
config.lcd = 0; /* 0.8 fixed point */
|
config.lcd = 0; /* 0.8 fixed point */
|
||||||
|
config.enhanced_vscroll = 0;
|
||||||
|
config.enhanced_vscroll_limit = 8;
|
||||||
|
|
||||||
/* controllers options */
|
/* controllers options */
|
||||||
input.system[0] = SYSTEM_GAMEPAD;
|
input.system[0] = SYSTEM_GAMEPAD;
|
||||||
|
@ -51,6 +51,8 @@ typedef struct
|
|||||||
uint8 ntsc;
|
uint8 ntsc;
|
||||||
uint8 lcd;
|
uint8 lcd;
|
||||||
uint8 render;
|
uint8 render;
|
||||||
|
uint8 enhanced_vscroll;
|
||||||
|
uint8 enhanced_vscroll_limit;
|
||||||
t_input_config input[MAX_INPUTS];
|
t_input_config input[MAX_INPUTS];
|
||||||
} t_config;
|
} t_config;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user