stvvdp1.cpp : Updates

Fix transparency and endcode behavior, Fix gouraud shading behavior, Fix sprite count, Add note
This commit is contained in:
cam900 2019-05-21 12:19:52 +09:00
parent f17e47ecfc
commit 9dba752151

View File

@ -869,8 +869,8 @@ void saturn_state::drawpixel_8bpp_trans(int x, int y, int patterndata, int offse
{ {
uint16_t pix; uint16_t pix;
pix = m_vdp1.gfx_decode[patterndata+offsetcnt]; pix = m_vdp1.gfx_decode[patterndata+offsetcnt] & 0xff;
if ( pix & 0xff ) if ( pix != 0 )
{ {
m_vdp1.framebuffer_draw_lines[y][x] = pix | m_sprite_colorbank; m_vdp1.framebuffer_draw_lines[y][x] = pix | m_sprite_colorbank;
} }
@ -891,16 +891,16 @@ void saturn_state::drawpixel_4bpp_trans(int x, int y, int patterndata, int offse
pix = m_vdp1.gfx_decode[patterndata+offsetcnt/2]; pix = m_vdp1.gfx_decode[patterndata+offsetcnt/2];
pix = offsetcnt&1 ? (pix & 0x0f) : ((pix & 0xf0)>>4); pix = offsetcnt&1 ? (pix & 0x0f) : ((pix & 0xf0)>>4);
if ( pix ) if ( pix != 0 )
m_vdp1.framebuffer_draw_lines[y][x] = pix | m_sprite_colorbank; m_vdp1.framebuffer_draw_lines[y][x] = pix | m_sprite_colorbank;
} }
void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcnt) void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcnt)
{ {
int pix,transmask, spd = stv2_current_sprite.CMDPMOD & 0x40; int pix,transpen, spd = stv2_current_sprite.CMDPMOD & 0x40;
// int mode; // int mode;
int mesh = stv2_current_sprite.CMDPMOD & 0x100; int mesh = stv2_current_sprite.CMDPMOD & 0x100;
int pix2; int raw,endcode;
if ( mesh && !((x ^ y) & 1) ) if ( mesh && !((x ^ y) & 1) )
{ {
@ -912,9 +912,10 @@ void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcn
if ( stv2_current_sprite.ispoly ) if ( stv2_current_sprite.ispoly )
{ {
pix = stv2_current_sprite.CMDCOLR&0xffff; raw = pix = stv2_current_sprite.CMDCOLR&0xffff;
transmask = 0xffff; transpen = 0;
endcode = 0xffff;
#if 0 #if 0
if ( pix & 0x8000 ) if ( pix & 0x8000 )
{ {
@ -932,92 +933,74 @@ void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcn
{ {
case 0x0000: // mode 0 16 colour bank mode (4bits) (hanagumi blocks) case 0x0000: // mode 0 16 colour bank mode (4bits) (hanagumi blocks)
// most of the shienryu sprites use this mode // most of the shienryu sprites use this mode
pix = m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff]; raw = m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff];
pix = offsetcnt&1 ? (pix & 0x0f) : ((pix & 0xf0)>>4); raw = offsetcnt&1 ? (raw & 0x0f) : ((raw & 0xf0)>>4);
pix = pix+((stv2_current_sprite.CMDCOLR&0xfff0)); pix = raw+((stv2_current_sprite.CMDCOLR&0xfff0));
//mode = 0; //mode = 0;
transmask = 0xf; transpen = 0;
endcode = 0xf;
break; break;
case 0x0008: // mode 1 16 colour lookup table mode (4bits) case 0x0008: // mode 1 16 colour lookup table mode (4bits)
// shienryu explosions (and some enemies) use this mode // shienryu explosions (and some enemies) use this mode
pix2 = m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff]; raw = m_vdp1.gfx_decode[(patterndata+offsetcnt/2) & 0xfffff];
pix2 = offsetcnt&1 ? (pix2 & 0x0f) : ((pix2 & 0xf0)>>4); raw = offsetcnt&1 ? (raw & 0x0f) : ((raw & 0xf0)>>4);
pix = pix2&1 ? pix = raw&1 ?
((((m_vdp1_vram[(((stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((pix2&0xfffe)/2)])) & 0x0000ffff) >> 0): ((((m_vdp1_vram[(((stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((raw&0xfffe)/2)])) & 0x0000ffff) >> 0):
((((m_vdp1_vram[(((stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((pix2&0xfffe)/2)])) & 0xffff0000) >> 16); ((((m_vdp1_vram[(((stv2_current_sprite.CMDCOLR&0xffff)*8)>>2)+((raw&0xfffe)/2)])) & 0xffff0000) >> 16);
//mode = 5; //mode = 5;
// TODO: transparency code wrong for after burner 2 transpen = 0;
transmask = 0xffff; endcode = 0xf;
if ( !spd )
{
if ( (pix2 & 0xf) == 0 )
{
return;
}
else
{
spd = 1;
}
}
break; break;
case 0x0010: // mode 2 64 colour bank mode (8bits) (character select portraits on hanagumi) case 0x0010: // mode 2 64 colour bank mode (8bits) (character select portraits on hanagumi)
pix = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; raw = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff] & 0xff;
//mode = 2; //mode = 2;
pix = pix+(stv2_current_sprite.CMDCOLR&0xffc0); pix = raw+(stv2_current_sprite.CMDCOLR&0xffc0);
// disable transmask since transparent pen is checked below (sasissu racing stage background clouds) transpen = 0;
transmask = 0xffff; endcode = 0xff;
// Scud: the disposable assassin wants transparent pen on 0
if ( !spd )
{
if ( (pix & 0x3f) == 0 )
{
return;
}
else
{
spd = 1;
}
}
break; break;
case 0x0018: // mode 3 128 colour bank mode (8bits) (little characters on hanagumi use this mode) case 0x0018: // mode 3 128 colour bank mode (8bits) (little characters on hanagumi use this mode)
pix = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; raw = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff] & 0xff;
pix = pix+(stv2_current_sprite.CMDCOLR&0xff80); pix = raw+(stv2_current_sprite.CMDCOLR&0xff80);
transmask = 0x7f; transpen = 0;
endcode = 0xff;
//mode = 3; //mode = 3;
break; break;
case 0x0020: // mode 4 256 colour bank mode (8bits) (hanagumi title) case 0x0020: // mode 4 256 colour bank mode (8bits) (hanagumi title)
pix = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff]; raw = m_vdp1.gfx_decode[(patterndata+offsetcnt) & 0xfffff] & 0xff;
pix = pix+(stv2_current_sprite.CMDCOLR&0xff00); pix = raw+(stv2_current_sprite.CMDCOLR&0xff00);
transmask = 0xff; transpen = 0;
endcode = 0xff;
//mode = 4; //mode = 4;
break; break;
case 0x0028: // mode 5 32,768 colour RGB mode (16bits) case 0x0028: // mode 5 32,768 colour RGB mode (16bits)
pix = m_vdp1.gfx_decode[(patterndata+offsetcnt*2+1) & 0xfffff] | (m_vdp1.gfx_decode[(patterndata+offsetcnt*2) & 0xfffff]<<8); raw = m_vdp1.gfx_decode[(patterndata+offsetcnt*2+1) & 0xfffff] | (m_vdp1.gfx_decode[(patterndata+offsetcnt*2) & 0xfffff]<<8);
//mode = 5; //mode = 5;
// TODO: check transmask // TODO: 0x1-0x7ffe reserved (color bank)
transmask = -1; pix = raw;
transpen = 0;
endcode = 0x7fff;
break; break;
case 0x0038: // invalid case 0x0038: // invalid
// game tengoku uses this on hi score screen (tate mode) // game tengoku uses this on hi score screen (tate mode)
// according to Charles, reads from VRAM address 0 // according to Charles, reads from VRAM address 0
pix = m_vdp1.gfx_decode[1] | (m_vdp1.gfx_decode[0]<<8) ; raw = pix = m_vdp1.gfx_decode[1] | (m_vdp1.gfx_decode[0]<<8) ;
// TODO: check transmask // TODO: check transpen
transmask = -1; transpen = 0;
endcode = -1;
break; break;
default: // other settings illegal default: // other settings illegal
pix = machine().rand(); pix = machine().rand();
raw = pix & 0xff; // just mimic old driver behavior
//mode = 0; //mode = 0;
transmask = 0xff; transpen = 0;
endcode = 0xff;
popmessage("Illegal Sprite Mode %02x, contact MAMEdev",stv2_current_sprite.CMDPMOD&0x0038); popmessage("Illegal Sprite Mode %02x, contact MAMEdev",stv2_current_sprite.CMDPMOD&0x0038);
} }
// preliminary end code disable support // preliminary end code disable support
if ( ((stv2_current_sprite.CMDPMOD & 0x80) == 0) && if ( ((stv2_current_sprite.CMDPMOD & 0x80) == 0) &&
((pix & transmask) == transmask) ) (raw == endcode) )
{ {
return; return;
} }
@ -1035,7 +1018,7 @@ void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcn
#if 0 #if 0
if ( mode != 5 ) if ( mode != 5 )
{ {
if ( (pix & transmask) || spd ) if ( (raw != transpen) || spd )
{ {
m_vdp1.framebuffer_draw_lines[y][x] = pix; m_vdp1.framebuffer_draw_lines[y][x] = pix;
} }
@ -1043,9 +1026,12 @@ void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcn
else else
#endif #endif
{ {
if ( (pix & transmask) || spd ) if ( (raw != transpen) || spd )
{ {
switch( stv2_current_sprite.CMDPMOD & 0x7 ) if ( stv2_current_sprite.CMDPMOD & 0x4 ) /* Gouraud shading */
pix = stv_vdp1_apply_gouraud_shading( x, y, pix );
switch( stv2_current_sprite.CMDPMOD & 0x3 )
{ {
case 0: /* replace */ case 0: /* replace */
m_vdp1.framebuffer_draw_lines[y][x] = pix; m_vdp1.framebuffer_draw_lines[y][x] = pix;
@ -1069,25 +1055,14 @@ void saturn_state::drawpixel_generic(int x, int y, int patterndata, int offsetcn
m_vdp1.framebuffer_draw_lines[y][x] = pix; m_vdp1.framebuffer_draw_lines[y][x] = pix;
} }
break; break;
case 4: /* Gouraud shading */ //case 4: /* Gouraud shading */
m_vdp1.framebuffer_draw_lines[y][x] = stv_vdp1_apply_gouraud_shading( x, y, pix );
break;
// TODO: Pro Yakyuu Team mo Tsukurou (during team creation, on PR girl select) // TODO: Pro Yakyuu Team mo Tsukurou (during team creation, on PR girl select)
//case 6: //case 6:
// break; // break;
case 7: /* Gouraud-shading + half-transparent */ //case 7: /* Gouraud-shading + half-transparent */
// Lupin the 3rd Pyramid no Kenja enemy shadows // Lupin the 3rd Pyramid no Kenja enemy shadows
// Death Crimson lives indicators // Death Crimson lives indicators
// TODO: latter looks really bad. // TODO: latter looks really bad.
if ( m_vdp1.framebuffer_draw_lines[y][x] & 0x8000 )
{
m_vdp1.framebuffer_draw_lines[y][x] = stv_vdp1_apply_gouraud_shading( x, y, alpha_blend_r16( m_vdp1.framebuffer_draw_lines[y][x], pix, 0x80 ) | 0x8000 );
}
else
{
m_vdp1.framebuffer_draw_lines[y][x] = stv_vdp1_apply_gouraud_shading( x, y, pix );
}
break;
default: default:
// TODO: mode 5: prohibited, mode 6: gouraud shading + half-luminance, mode 7: gouraud-shading + half-transparent // TODO: mode 5: prohibited, mode 6: gouraud shading + half-luminance, mode 7: gouraud-shading + half-transparent
popmessage("VDP1 PMOD = %02x, contact MAMEdev",stv2_current_sprite.CMDPMOD & 0x7); popmessage("VDP1 PMOD = %02x, contact MAMEdev",stv2_current_sprite.CMDPMOD & 0x7);
@ -1851,7 +1826,7 @@ void saturn_state::stv_vdp1_process_list( void )
CEF_0; CEF_0;
// TODO: is there an actual limit for this? // TODO: is there an actual limit for this?
while (spritecount<10000) // if its drawn this many sprites something is probably wrong or sega were crazy ;-) while (spritecount<16383) // max 16383 with texture or max 16384 without texture - vitrually unlimited
{ {
int draw_this_sprite; int draw_this_sprite;