mirror of
https://github.com/holub/mame
synced 2025-04-29 03:20:50 +03:00
improved and optimized super22 fog
This commit is contained in:
parent
1262c315c3
commit
a1345d9a64
@ -77,6 +77,8 @@ public:
|
|||||||
int m_mbSpotlightEnable;
|
int m_mbSpotlightEnable;
|
||||||
UINT32 *m_czram;
|
UINT32 *m_czram;
|
||||||
UINT16 *m_banked_czram[4];
|
UINT16 *m_banked_czram[4];
|
||||||
|
UINT8 *m_recalc_czram[4];
|
||||||
|
UINT32 m_cz_was_written[4];
|
||||||
int m_cz_adjust;
|
int m_cz_adjust;
|
||||||
poly_manager *m_poly;
|
poly_manager *m_poly;
|
||||||
UINT16 *m_mpTextureTileMap16;
|
UINT16 *m_mpTextureTileMap16;
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
* - tokyowar tanks are not shootable, same for timecris helicopter, there's still a very small hitbox but almost impossible to hit
|
* - tokyowar tanks are not shootable, same for timecris helicopter, there's still a very small hitbox but almost impossible to hit
|
||||||
* (is this related to dsp? or cpu?)
|
* (is this related to dsp? or cpu?)
|
||||||
* - eliminate sprite garbage in airco22b: find out how/where vics num_sprites is determined exactly, or is it linktable related?
|
* - eliminate sprite garbage in airco22b: find out how/where vics num_sprites is determined exactly, or is it linktable related?
|
||||||
* - super22 poly fog currently doesn't work on reversed tables (see testmode), or on 'short' tables (see airco22b)
|
|
||||||
* - optimize super22 poly fog: precompute 2KB tables at czram write
|
|
||||||
* - window clipping (acedrvrw, victlapw)
|
* - window clipping (acedrvrw, victlapw)
|
||||||
* - using rgbint to set brightness may cause problems if a color channel is 00 (eg. victlapw attract)
|
* - using rgbint to set brightness may cause problems if a color channel is 00 (eg. victlapw attract)
|
||||||
* (probably a bug in rgbint, not here?)
|
* (probably a bug in rgbint, not here?)
|
||||||
@ -351,8 +349,7 @@ struct _poly_extra_data
|
|||||||
int zfog_enabled;
|
int zfog_enabled;
|
||||||
int cz_adjust;
|
int cz_adjust;
|
||||||
int cz_sdelta;
|
int cz_sdelta;
|
||||||
const UINT8 *czram_8;
|
const UINT8 *czram;
|
||||||
const UINT16 *czram_16;
|
|
||||||
|
|
||||||
/* sprites */
|
/* sprites */
|
||||||
const UINT8 *source;
|
const UINT8 *source;
|
||||||
@ -378,8 +375,7 @@ static void renderscanline_uvi_full(void *destbase, INT32 scanline, const poly_e
|
|||||||
bitmap_t *destmap = (bitmap_t *)destbase;
|
bitmap_t *destmap = (bitmap_t *)destbase;
|
||||||
int bn = extra->bn * 0x1000;
|
int bn = extra->bn * 0x1000;
|
||||||
const pen_t *pens = extra->pens;
|
const pen_t *pens = extra->pens;
|
||||||
const UINT8 *czram_8 = extra->czram_8;
|
const UINT8 *czram = extra->czram;
|
||||||
const UINT16 *czram_16 = extra->czram_16;
|
|
||||||
int cz_adjust = extra->cz_adjust;
|
int cz_adjust = extra->cz_adjust;
|
||||||
int cz_sdelta = extra->cz_sdelta;
|
int cz_sdelta = extra->cz_sdelta;
|
||||||
int zfog_enabled = extra->zfog_enabled;
|
int zfog_enabled = extra->zfog_enabled;
|
||||||
@ -410,6 +406,11 @@ static void renderscanline_uvi_full(void *destbase, INT32 scanline, const poly_e
|
|||||||
penshift = 4 * (~extra->cmode & 1);
|
penshift = 4 * (~extra->cmode & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// slight differences between super and non-super, do the branch here for optimization
|
||||||
|
// normal: 1 fader, no alpha, shading after fog
|
||||||
|
// super: 2 faders, alpha, shading before fog
|
||||||
|
if (state->m_mbSuperSystem22)
|
||||||
|
{
|
||||||
for( x=extent->startx; x<extent->stopx; x++ )
|
for( x=extent->startx; x<extent->stopx; x++ )
|
||||||
{
|
{
|
||||||
float ooz = 1.0f / z;
|
float ooz = 1.0f / z;
|
||||||
@ -419,6 +420,10 @@ static void renderscanline_uvi_full(void *destbase, INT32 scanline, const poly_e
|
|||||||
rgbint rgb;
|
rgbint rgb;
|
||||||
rgb_to_rgbint(&rgb, pens[pen>>penshift&penmask]);
|
rgb_to_rgbint(&rgb, pens[pen>>penshift&penmask]);
|
||||||
|
|
||||||
|
// apply shading before fog
|
||||||
|
int shade = i*ooz;
|
||||||
|
rgbint_scale_immediate_and_clamp(&rgb, shade << 2);
|
||||||
|
|
||||||
// per-z distance fogging
|
// per-z distance fogging
|
||||||
if (zfog_enabled)
|
if (zfog_enabled)
|
||||||
{
|
{
|
||||||
@ -426,32 +431,15 @@ static void renderscanline_uvi_full(void *destbase, INT32 scanline, const poly_e
|
|||||||
// discard low byte and clamp to 0-1fff
|
// discard low byte and clamp to 0-1fff
|
||||||
if ((UINT32)cz < 0x200000) cz >>= 8;
|
if ((UINT32)cz < 0x200000) cz >>= 8;
|
||||||
else cz = (cz < 0) ? 0 : 0x1fff;
|
else cz = (cz < 0) ? 0 : 0x1fff;
|
||||||
if (state->m_mbSuperSystem22)
|
if ((fogFactor = czram[cz] + cz_sdelta) > 0)
|
||||||
{
|
|
||||||
// compare against cz table, slow :(
|
|
||||||
for (fogFactor=0; fogFactor<0x100; fogFactor++)
|
|
||||||
if (czram_16[fogFactor] >= cz) break;
|
|
||||||
|
|
||||||
fogFactor = (fogFactor&0xff) + cz_sdelta;
|
|
||||||
if (fogFactor>0)
|
|
||||||
{
|
{
|
||||||
if (fogFactor>0xff) fogFactor=0xff;
|
if (fogFactor>0xff) fogFactor=0xff;
|
||||||
rgbint_blend(&rgb, &fogColor, 0xff-fogFactor);
|
rgbint_blend(&rgb, &fogColor, 0xff-fogFactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((fogFactor = czram_8[NATIVE_ENDIAN_VALUE_LE_BE(3,0)^cz]) != 0)
|
|
||||||
rgbint_blend(&rgb, &fogColor, 0xff-fogFactor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fogFactor != 0xff) // direct
|
else if (fogFactor != 0xff) // direct
|
||||||
rgbint_blend(&rgb, &fogColor, fogFactor);
|
rgbint_blend(&rgb, &fogColor, fogFactor);
|
||||||
|
|
||||||
// apply shading after fog
|
|
||||||
int shade = i*ooz;
|
|
||||||
rgbint_scale_immediate_and_clamp(&rgb, shade << 2);
|
|
||||||
|
|
||||||
if( polyfade_enabled )
|
if( polyfade_enabled )
|
||||||
rgbint_scale_channel_and_clamp(&rgb, &polyColor);
|
rgbint_scale_channel_and_clamp(&rgb, &polyColor);
|
||||||
|
|
||||||
@ -473,6 +461,47 @@ static void renderscanline_uvi_full(void *destbase, INT32 scanline, const poly_e
|
|||||||
i += di;
|
i += di;
|
||||||
z += dz;
|
z += dz;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( x=extent->startx; x<extent->stopx; x++ )
|
||||||
|
{
|
||||||
|
float ooz = 1.0f / z;
|
||||||
|
int pen = texel(state, (int)(u*ooz), bn+(int)(v*ooz));
|
||||||
|
// pen = 0x55; // debug: disable textures
|
||||||
|
|
||||||
|
rgbint rgb;
|
||||||
|
rgb_to_rgbint(&rgb, pens[pen>>penshift&penmask]);
|
||||||
|
|
||||||
|
// per-z distance fogging
|
||||||
|
if (zfog_enabled)
|
||||||
|
{
|
||||||
|
int cz = ooz + cz_adjust;
|
||||||
|
// discard low byte and clamp to 0-1fff
|
||||||
|
if ((UINT32)cz < 0x200000) cz >>= 8;
|
||||||
|
else cz = (cz < 0) ? 0 : 0x1fff;
|
||||||
|
if ((fogFactor = czram[NATIVE_ENDIAN_VALUE_LE_BE(3,0)^cz]) != 0)
|
||||||
|
rgbint_blend(&rgb, &fogColor, 0xff-fogFactor);
|
||||||
|
}
|
||||||
|
else if (fogFactor != 0xff) // direct
|
||||||
|
rgbint_blend(&rgb, &fogColor, fogFactor);
|
||||||
|
|
||||||
|
// apply shading after fog
|
||||||
|
int shade = i*ooz;
|
||||||
|
rgbint_scale_immediate_and_clamp(&rgb, shade << 2);
|
||||||
|
|
||||||
|
if( polyfade_enabled )
|
||||||
|
rgbint_scale_channel_and_clamp(&rgb, &polyColor);
|
||||||
|
|
||||||
|
dest[x] = rgbint_to_rgb(&rgb);
|
||||||
|
primap[x] |= prioverchar;
|
||||||
|
|
||||||
|
u += du;
|
||||||
|
v += dv;
|
||||||
|
i += di;
|
||||||
|
z += dz;
|
||||||
|
}
|
||||||
|
}
|
||||||
} /* renderscanline_uvi_full */
|
} /* renderscanline_uvi_full */
|
||||||
|
|
||||||
static void poly3d_DrawQuad(running_machine &machine, bitmap_t *bitmap, int textureBank, int color, Poly3dVertex pv[4], int flags, int cz_adjust, int direct, int cmode )
|
static void poly3d_DrawQuad(running_machine &machine, bitmap_t *bitmap, int textureBank, int color, Poly3dVertex pv[4], int flags, int cz_adjust, int direct, int cmode )
|
||||||
@ -602,9 +631,9 @@ static void poly3d_DrawQuad(running_machine &machine, bitmap_t *bitmap, int text
|
|||||||
^^^^ maincpu ram access bank
|
^^^^ maincpu ram access bank
|
||||||
^^^^ flags, nybble per cztype 3,2,1,0 - ?
|
^^^^ flags, nybble per cztype 3,2,1,0 - ?
|
||||||
^^^^ ? (only set sometimes in timecris)
|
^^^^ ? (only set sometimes in timecris)
|
||||||
0000 0000 0000 0000 7555 0000 00e4 0000 // testmode normal
|
0000 0000 0000 0000 7555 0000 00e4 0000 // testmode normal - 0=white to black(mid), 1=white to black(weak), 2=white to black(strong), 3=black to white(mid, reverse of 0)
|
||||||
7fff 8000 7fff 8000 7555 0000 00e4 0000 // testmode offset
|
7fff 8000 7fff 8000 7555 0000 00e4 0000 // testmode offset - 0=black, 1=white, 2=black, 3=white
|
||||||
0000 0000 0000 0000 3111 0000 00e4 0000 // testmode off
|
0000 0000 0000 0000 3111 0000 00e4 0000 // testmode off - 0=white, 1=white, 2=white, 3=white
|
||||||
0000 0000 0000 0000 4444 0000 0000 0000 // propcycl solitar
|
0000 0000 0000 0000 4444 0000 0000 0000 // propcycl solitar
|
||||||
0004 0004 0004 0004 4444 0000 0000 0000 // propcycl out pool
|
0004 0004 0004 0004 4444 0000 0000 0000 // propcycl out pool
|
||||||
00a4 00a4 00a4 00a4 4444 0000 0000 0000 // propcycl in pool
|
00a4 00a4 00a4 00a4 4444 0000 0000 0000 // propcycl in pool
|
||||||
@ -630,12 +659,7 @@ static void poly3d_DrawQuad(running_machine &machine, bitmap_t *bitmap, int text
|
|||||||
if (cz < 0) cz = 0;
|
if (cz < 0) cz = 0;
|
||||||
else if (cz > 0x1fff) cz = 0x1fff;
|
else if (cz > 0x1fff) cz = 0x1fff;
|
||||||
|
|
||||||
// bad (see testmode)
|
int fogFactor = state->m_recalc_czram[cztype][cz] + delta;
|
||||||
int fogFactor;
|
|
||||||
for (fogFactor=0; fogFactor<0x100; fogFactor++)
|
|
||||||
if (state->m_banked_czram[cztype][fogFactor] >= cz) break;
|
|
||||||
|
|
||||||
fogFactor = (fogFactor&0xff) + delta;
|
|
||||||
if (fogFactor>0)
|
if (fogFactor>0)
|
||||||
{
|
{
|
||||||
if (fogFactor>0xff) fogFactor = 0xff;
|
if (fogFactor>0xff) fogFactor = 0xff;
|
||||||
@ -646,7 +670,7 @@ static void poly3d_DrawQuad(running_machine &machine, bitmap_t *bitmap, int text
|
|||||||
{
|
{
|
||||||
extra->zfog_enabled = 1;
|
extra->zfog_enabled = 1;
|
||||||
extra->cz_sdelta = delta;
|
extra->cz_sdelta = delta;
|
||||||
extra->czram_16 = state->m_banked_czram[cztype];
|
extra->czram = state->m_recalc_czram[cztype];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -679,7 +703,7 @@ static void poly3d_DrawQuad(running_machine &machine, bitmap_t *bitmap, int text
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
extra->zfog_enabled = 1;
|
extra->zfog_enabled = 1;
|
||||||
extra->czram_8 = (UINT8*)&state->m_czram[cztype<<(13-2)];
|
extra->czram = (UINT8*)&state->m_czram[cztype<<(13-2)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1200,22 +1224,89 @@ namcos22_point_rom_r( running_machine &machine, offs_t offs )
|
|||||||
WRITE32_HANDLER( namcos22s_czram_w )
|
WRITE32_HANDLER( namcos22s_czram_w )
|
||||||
{
|
{
|
||||||
namcos22_state *state = space->machine().driver_data<namcos22_state>();
|
namcos22_state *state = space->machine().driver_data<namcos22_state>();
|
||||||
int bank = nthword(state->m_czattr,0xa/2);
|
int bank = nthword(state->m_czattr,0xa/2)&3;
|
||||||
UINT16 *czram = state->m_banked_czram[bank&3];
|
UINT16 *czram = state->m_banked_czram[bank];
|
||||||
UINT32 dat = (czram[offset*2]<<16)|czram[offset*2+1];
|
UINT32 dat = (czram[offset*2]<<16)|czram[offset*2+1];
|
||||||
|
UINT32 prev = dat;
|
||||||
COMBINE_DATA( &dat );
|
COMBINE_DATA( &dat );
|
||||||
czram[offset*2] = dat>>16;
|
czram[offset*2] = dat>>16;
|
||||||
czram[offset*2+1] = dat&0xffff;
|
czram[offset*2+1] = dat&0xffff;
|
||||||
|
state->m_cz_was_written[bank] |= (prev^dat);
|
||||||
}
|
}
|
||||||
|
|
||||||
READ32_HANDLER( namcos22s_czram_r )
|
READ32_HANDLER( namcos22s_czram_r )
|
||||||
{
|
{
|
||||||
namcos22_state *state = space->machine().driver_data<namcos22_state>();
|
namcos22_state *state = space->machine().driver_data<namcos22_state>();
|
||||||
int bank = nthword(state->m_czattr,0xa/2);
|
int bank = nthword(state->m_czattr,0xa/2)&3;
|
||||||
const UINT16 *czram = state->m_banked_czram[bank&3];
|
const UINT16 *czram = state->m_banked_czram[bank];
|
||||||
return (czram[offset*2]<<16)|czram[offset*2+1];
|
return (czram[offset*2]<<16)|czram[offset*2+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void namcos22s_recalc_czram( running_machine &machine )
|
||||||
|
{
|
||||||
|
namcos22_state *state = machine.driver_data<namcos22_state>();
|
||||||
|
int i, j, table;
|
||||||
|
for (table=0; table<4; table++)
|
||||||
|
{
|
||||||
|
// as documented above, ss22 czram is 'just' a big compare table
|
||||||
|
// this is very slow when emulating, so let's recalculate it to a simpler lookup table
|
||||||
|
if (state->m_cz_was_written[table])
|
||||||
|
{
|
||||||
|
int small_val = 0x2000;
|
||||||
|
int small_offset = 0;
|
||||||
|
int large_val = 0;
|
||||||
|
int large_offset = 0;
|
||||||
|
int prev = 0x2000;
|
||||||
|
|
||||||
|
for (i=0; i<0x100; i++)
|
||||||
|
{
|
||||||
|
int val = state->m_banked_czram[table][i];
|
||||||
|
|
||||||
|
// discard if larger than 1fff
|
||||||
|
if (val>0x1fff) val = prev;
|
||||||
|
if (prev>0x1fff)
|
||||||
|
{
|
||||||
|
prev = val;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start = prev;
|
||||||
|
int end = val;
|
||||||
|
if (start>end)
|
||||||
|
{
|
||||||
|
start = val;
|
||||||
|
end = prev;
|
||||||
|
}
|
||||||
|
prev = val;
|
||||||
|
|
||||||
|
// fill range
|
||||||
|
for (j=start; j<end; j++)
|
||||||
|
state->m_recalc_czram[table][j] = i;
|
||||||
|
|
||||||
|
// remember largest/smallest for later
|
||||||
|
if (val<small_val)
|
||||||
|
{
|
||||||
|
small_val = val;
|
||||||
|
small_offset = i;
|
||||||
|
}
|
||||||
|
if (val>large_val)
|
||||||
|
{
|
||||||
|
large_val = val;
|
||||||
|
large_offset = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill possible leftover ranges
|
||||||
|
for (j=0; j<small_val; j++)
|
||||||
|
state->m_recalc_czram[table][j] = small_offset;
|
||||||
|
for (j=large_val; j<0x2000; j++)
|
||||||
|
state->m_recalc_czram[table][j] = large_offset;
|
||||||
|
|
||||||
|
state->m_cz_was_written[table] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
InitXYAttrToPixel( namcos22_state *state )
|
InitXYAttrToPixel( namcos22_state *state )
|
||||||
@ -1300,7 +1391,7 @@ namcos22_draw_direct_poly( running_machine &machine, const UINT16 *pSource )
|
|||||||
struct SceneNode *node = NewSceneNode(machine, zsortvalue24, eSCENENODE_QUAD3D);
|
struct SceneNode *node = NewSceneNode(machine, zsortvalue24, eSCENENODE_QUAD3D);
|
||||||
int i;
|
int i;
|
||||||
node->data.quad3d.cz_adjust = state->m_cz_adjust;
|
node->data.quad3d.cz_adjust = state->m_cz_adjust;
|
||||||
node->data.quad3d.flags = (pSource[3]<<6&0x1fff00) | (pSource[3]&3);
|
node->data.quad3d.flags = (pSource[3]<<6&0x1fff00) | (~pSource[3]&3);
|
||||||
node->data.quad3d.color = (pSource[2]&0xff00)>>8;
|
node->data.quad3d.color = (pSource[2]&0xff00)>>8;
|
||||||
if( state->m_mbSuperSystem22 )
|
if( state->m_mbSuperSystem22 )
|
||||||
{
|
{
|
||||||
@ -2535,15 +2626,17 @@ VIDEO_START( namcos22s )
|
|||||||
{
|
{
|
||||||
namcos22_state *state = machine.driver_data<namcos22_state>();
|
namcos22_state *state = machine.driver_data<namcos22_state>();
|
||||||
state->m_mbSuperSystem22 = 1;
|
state->m_mbSuperSystem22 = 1;
|
||||||
state->m_banked_czram[0] = auto_alloc_array(machine, UINT16, 0x200/2 );
|
|
||||||
state->m_banked_czram[1] = auto_alloc_array(machine, UINT16, 0x200/2 );
|
|
||||||
state->m_banked_czram[2] = auto_alloc_array(machine, UINT16, 0x200/2 );
|
|
||||||
state->m_banked_czram[3] = auto_alloc_array(machine, UINT16, 0x200/2 );
|
|
||||||
|
|
||||||
memset(state->m_banked_czram[0], 0, 0x200);
|
// init czram tables
|
||||||
memset(state->m_banked_czram[1], 0, 0x200);
|
int table;
|
||||||
memset(state->m_banked_czram[2], 0, 0x200);
|
for (table=0; table<4; table++)
|
||||||
memset(state->m_banked_czram[3], 0, 0x200);
|
{
|
||||||
|
state->m_banked_czram[table] = auto_alloc_array(machine, UINT16, 0x100);
|
||||||
|
memset(state->m_banked_czram[table], 0, 0x100*2);
|
||||||
|
state->m_recalc_czram[table] = auto_alloc_array(machine, UINT8, 0x2000);
|
||||||
|
memset(state->m_recalc_czram[table], 0, 0x2000);
|
||||||
|
state->m_cz_was_written[table] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
VIDEO_START_CALL(common);
|
VIDEO_START_CALL(common);
|
||||||
}
|
}
|
||||||
@ -2553,6 +2646,7 @@ SCREEN_UPDATE( namcos22s )
|
|||||||
namcos22_state *state = screen->machine().driver_data<namcos22_state>();
|
namcos22_state *state = screen->machine().driver_data<namcos22_state>();
|
||||||
UpdateVideoMixer(screen->machine());
|
UpdateVideoMixer(screen->machine());
|
||||||
UpdatePalette(screen->machine());
|
UpdatePalette(screen->machine());
|
||||||
|
namcos22s_recalc_czram(screen->machine());
|
||||||
bitmap_fill(screen->machine().priority_bitmap, cliprect, 0);
|
bitmap_fill(screen->machine().priority_bitmap, cliprect, 0);
|
||||||
|
|
||||||
// background color
|
// background color
|
||||||
|
Loading…
Reference in New Issue
Block a user