mirror of
https://github.com/holub/mame
synced 2025-07-05 01:48:29 +03:00
snk/hng64_sprite.ipp: Improved sprite mosaic effect. (#10935)
* Implemented mosaic effect in Y direction. * Improved transition control register use for fade effects on Buriki One jumbotron. * Updated notes.
This commit is contained in:
parent
369ecb2f77
commit
24c059a2ec
@ -1185,7 +1185,7 @@ void hng64_state::hng_map(address_map &map)
|
||||
map(0x20190000, 0x20190037).ram().w(FUNC(hng64_state::hng64_vregs_w)).share("videoregs");
|
||||
|
||||
// Mixing
|
||||
map(0x20200000, 0x20203fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
|
||||
map(0x20200000, 0x20203fff).ram().w(FUNC(hng64_state::pal_w)).share("paletteram");
|
||||
map(0x20208000, 0x2020805f).w(FUNC(hng64_state::tcram_w)).share("tcram"); // Transition Control
|
||||
map(0x20208000, 0x2020805f).r(FUNC(hng64_state::tcram_r));
|
||||
|
||||
|
@ -139,6 +139,7 @@ public:
|
||||
driver_device(mconfig, type, tag),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_paletteram(*this, "paletteram"),
|
||||
m_vblank(*this, "VBLANK"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
@ -185,6 +186,7 @@ public:
|
||||
uint8_t *m_texturerom = nullptr;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_shared_ptr<u32> m_paletteram;
|
||||
required_ioport m_vblank;
|
||||
|
||||
private:
|
||||
@ -342,6 +344,8 @@ private:
|
||||
void dl_unk_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t dl_vreg_r();
|
||||
|
||||
void update_palette_entry(int entry);
|
||||
void pal_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void tcram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t tcram_r(offs_t offset);
|
||||
|
||||
@ -439,16 +443,16 @@ private:
|
||||
|
||||
void get_tile_details(bool chain, uint16_t spritenum, uint8_t xtile, uint8_t ytile, uint8_t xsize, uint8_t ysize, bool xflip, bool yflip, uint32_t& tileno, uint16_t& pal, uint8_t &gfxregion);
|
||||
void draw_sprites_buffer(screen_device &screen, const rectangle &cliprect);
|
||||
void draw_sprite_line(screen_device& screen, const rectangle& cliprect, int32_t curyy, int16_t cury, int16_t xpos, int chainx, int32_t dx, int32_t dy, int ytileblock, int chaini, int currentsprite, int chainy, int xflip, int yflip, uint16_t zval, bool zsort, bool blend, bool checkerboard, uint8_t mosaic);
|
||||
|
||||
void drawline(bitmap_ind16& dest, bitmap_ind16& destz, const rectangle& cliprect,
|
||||
gfx_element* gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty,
|
||||
int32_t dx, int32_t dy, uint32_t dstwidth, uint32_t dstheight, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int cury, const u8* srcdata, int32_t srcx, int32_t srcy_copy, uint32_t leftovers, int line, uint16_t &srcpix);
|
||||
gfx_element* gfx, uint32_t code, uint32_t color, int flipy, int32_t xpos,
|
||||
int32_t dx, int32_t dy, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int32_t ypos, const u8* srcdata, int32_t srcx, uint32_t leftovers, int line, uint16_t &srcpix);
|
||||
|
||||
void zoom_transpen(bitmap_ind16 &dest, bitmap_ind16 &destz, const rectangle &cliprect,
|
||||
gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty,
|
||||
int32_t dx, int32_t dy, uint32_t dstwidth, uint32_t dstheight, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int line, uint16_t &srcpix);
|
||||
gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t xpos, int32_t ypos,
|
||||
int32_t dx, int32_t dy, uint32_t dstwidth, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int line, uint16_t &srcpix);
|
||||
|
||||
void transition_control(bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
void setCameraTransformation(const uint16_t* packet);
|
||||
void setLighting(const uint16_t* packet);
|
||||
void set3dFlags(const uint16_t* packet);
|
||||
|
@ -45,7 +45,7 @@
|
||||
do \
|
||||
{ \
|
||||
uint32_t srcdata = (SOURCE); \
|
||||
if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left() && cury <= cliprect.bottom() && cury >= cliprect.top()) \
|
||||
if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left() && ypos <= cliprect.bottom() && ypos >= cliprect.top()) \
|
||||
{ \
|
||||
if (zval < (DESTZ)) \
|
||||
{ \
|
||||
@ -64,7 +64,7 @@ while (0)
|
||||
do \
|
||||
{ \
|
||||
uint32_t srcdata = (SOURCE); \
|
||||
if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left() && cury <= cliprect.bottom() && cury >= cliprect.top()) \
|
||||
if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left() && ypos <= cliprect.bottom() && ypos >= cliprect.top()) \
|
||||
{ \
|
||||
if (zval > (DESTZ)) \
|
||||
{ \
|
||||
@ -98,41 +98,36 @@ do \
|
||||
\
|
||||
if (checkerboard) \
|
||||
{ \
|
||||
if (cb & 1) \
|
||||
if (curx & 1) \
|
||||
{ \
|
||||
if (!(cury & 1)) \
|
||||
if (!(ypos & 1)) \
|
||||
srcpix = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if ((cury & 1)) \
|
||||
if ((ypos & 1)) \
|
||||
srcpix = 0; \
|
||||
} \
|
||||
cb++; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
void hng64_state::drawline(bitmap_ind16 & dest, bitmap_ind16 & destz, const rectangle & cliprect,
|
||||
gfx_element * gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty,
|
||||
int32_t dx, int32_t dy, uint32_t dstwidth, uint32_t dstheight, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int cury, const u8 *srcdata, int32_t srcx, int32_t srcy_copy, uint32_t leftovers, int line, uint16_t &srcpix)
|
||||
gfx_element * gfx, uint32_t code, uint32_t color, int flipy, int32_t xpos,
|
||||
int32_t dx, int32_t dy, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int32_t ypos, const u8 *srcdata, int32_t srcx, uint32_t leftovers, int curyy, uint16_t &srcpix)
|
||||
{
|
||||
int srcy = dy * line + srcy_copy;
|
||||
auto* destptr = &dest.pix(ypos, 0);
|
||||
auto* destzptr = &destz.pix(ypos, 0);
|
||||
|
||||
auto* destptr = &dest.pix(cury, 0);
|
||||
auto* destzptr = &destz.pix(cury, 0);
|
||||
|
||||
const u8* srcptr = srcdata + ((srcy >> 16) & 0xf) * gfx->rowbytes();
|
||||
const u8* srcptr = srcdata + (flipy ? ((15-curyy) & 0xf) : (curyy & 0xf)) * gfx->rowbytes();
|
||||
int32_t cursrcx = srcx;
|
||||
|
||||
// iterate over unrolled blocks of 4
|
||||
if (zrev)
|
||||
{
|
||||
uint8_t cb = 0;
|
||||
// iterate over leftover pixels
|
||||
for (int32_t curx = 0; curx < leftovers; curx++)
|
||||
{
|
||||
int xdrawpos = destx + curx;
|
||||
int xdrawpos = xpos + curx;
|
||||
PIX_CHECKERBOARD;
|
||||
PIXEL_OP_REBASE_TRANSPEN_REV(destptr[xdrawpos], destzptr[xdrawpos], srcpix);
|
||||
cursrcx += dx;
|
||||
@ -140,11 +135,10 @@ void hng64_state::drawline(bitmap_ind16 & dest, bitmap_ind16 & destz, const rect
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t cb = 0;
|
||||
// iterate over leftover pixels
|
||||
for (int32_t curx = 0; curx < leftovers; curx++)
|
||||
{
|
||||
int xdrawpos = destx + curx;
|
||||
int xdrawpos = xpos + curx;
|
||||
PIX_CHECKERBOARD;
|
||||
PIXEL_OP_REBASE_TRANSPEN(destptr[xdrawpos], destzptr[xdrawpos], srcpix);
|
||||
cursrcx += dx;
|
||||
@ -153,8 +147,8 @@ void hng64_state::drawline(bitmap_ind16 & dest, bitmap_ind16 & destz, const rect
|
||||
}
|
||||
|
||||
void hng64_state::zoom_transpen(bitmap_ind16 &dest, bitmap_ind16 &destz, const rectangle &cliprect,
|
||||
gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty,
|
||||
int32_t dx, int32_t dy, uint32_t dstwidth, uint32_t dstheight, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int line, uint16_t &srcpix)
|
||||
gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t xpos, int32_t ypos,
|
||||
int32_t dx, int32_t dy, uint32_t dstwidth, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int curyy, uint16_t &srcpix)
|
||||
{
|
||||
// use pen usage to optimize
|
||||
code %= gfx->elements();
|
||||
@ -179,7 +173,7 @@ void hng64_state::zoom_transpen(bitmap_ind16 &dest, bitmap_ind16 &destz, const r
|
||||
if (cliprect.empty())
|
||||
return;
|
||||
|
||||
if (dstwidth < 1 || dstheight < 1)
|
||||
if (dstwidth < 1)
|
||||
return;
|
||||
|
||||
int32_t srcx = 0;
|
||||
@ -190,27 +184,15 @@ void hng64_state::zoom_transpen(bitmap_ind16 &dest, bitmap_ind16 &destz, const r
|
||||
dx = -dx;
|
||||
}
|
||||
|
||||
int32_t srcy = 0;
|
||||
// apply Y flipping
|
||||
if (flipy)
|
||||
{
|
||||
srcy = (dstheight - 1) * dy - srcy;
|
||||
dy = -dy;
|
||||
}
|
||||
|
||||
// fetch the source data
|
||||
const u8 *srcdata = gfx->get_data(code);
|
||||
|
||||
// compute how many blocks of 4 pixels we have
|
||||
int32_t destendx = destx + dstwidth - 1;
|
||||
uint32_t leftovers = (destendx + 1 - destx);
|
||||
|
||||
// iterate over pixels in Y
|
||||
int32_t srcycopy = srcy;
|
||||
int32_t destendx = xpos + dstwidth - 1;
|
||||
uint32_t leftovers = (destendx + 1 - xpos);
|
||||
|
||||
drawline(dest, destz, cliprect,
|
||||
gfx, code, color, flipx, flipy, destx, desty,
|
||||
dx, dy, dstwidth, dstheight, trans_pen, zval, zrev, blend, checkerboard, mosaic, mosaic_count_x, desty, srcdata, srcx, srcycopy, leftovers, line, srcpix);
|
||||
gfx, code, color, flipy, xpos,
|
||||
dx, dy, trans_pen, zval, zrev, blend, checkerboard, mosaic, mosaic_count_x, ypos, srcdata, srcx, leftovers, curyy, srcpix);
|
||||
|
||||
}
|
||||
|
||||
@ -293,11 +275,17 @@ void hng64_state::draw_sprites_buffer(screen_device& screen, const rectangle& cl
|
||||
{
|
||||
uint16_t zval = (m_spriteram[(currentsprite * 8) + 2] & 0x07ff0000) >> 16;
|
||||
|
||||
uint16_t ypos = (m_spriteram[(currentsprite * 8) + 0] & 0xffff0000) >> 16;
|
||||
uint16_t xpos = (m_spriteram[(currentsprite * 8) + 0] & 0x0000ffff) >> 0;
|
||||
int16_t ypos = (m_spriteram[(currentsprite * 8) + 0] & 0xffff0000) >> 16;
|
||||
int16_t xpos = (m_spriteram[(currentsprite * 8) + 0] & 0x0000ffff) >> 0;
|
||||
|
||||
// should the offsets also be sign extended?
|
||||
xpos += (spriteoffsx);
|
||||
ypos += (spriteoffsy);
|
||||
|
||||
// sams64_2 wants bit 0x200 to be the sign bit on character select screen
|
||||
xpos = util::sext(xpos, 10);
|
||||
ypos = util::sext(ypos, 10);
|
||||
|
||||
bool blend = (m_spriteram[(currentsprite * 8) + 4] & 0x00800000);
|
||||
bool checkerboard = (m_spriteram[(currentsprite * 8) + 4] & 0x04000000);
|
||||
uint8_t mosaic = (m_spriteram[(currentsprite * 8) + 4] & 0xf0000000) >> 28;
|
||||
@ -339,26 +327,52 @@ void hng64_state::draw_sprites_buffer(screen_device& screen, const rectangle& cl
|
||||
dy = zoomy << 4;
|
||||
}
|
||||
|
||||
int16_t drawy = ypos;
|
||||
uint32_t srcpix_y = 0;
|
||||
|
||||
for (int ydrw = 0; ydrw <= chainy; ydrw++)
|
||||
{
|
||||
uint32_t dstheight = 0;
|
||||
|
||||
uint32_t full_srcpix_y = 0;
|
||||
uint32_t full_dstheight = 0;
|
||||
do
|
||||
{
|
||||
srcpix_y += dy;
|
||||
dstheight++;
|
||||
} while (srcpix_y < 0x100000);
|
||||
srcpix_y &= 0x0fffff;
|
||||
full_srcpix_y += dy;
|
||||
full_dstheight++;
|
||||
} while (full_srcpix_y < ((chainy+1) * 0x100000));
|
||||
|
||||
int32_t destendy = drawy + dstheight - 1;
|
||||
for (int32_t cury = drawy, line = 0; cury <= destendy; line++, cury++)
|
||||
int realline = 0;
|
||||
int mosaic_y_counter = 0;
|
||||
for (int32_t curyy = 0; curyy <= full_dstheight - 1; curyy++)
|
||||
{
|
||||
int16_t drawx = xpos;
|
||||
uint32_t srcpix_x = 0;
|
||||
if (!mosaic)
|
||||
{
|
||||
realline = curyy;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mosaic_y_counter == 0)
|
||||
{
|
||||
realline = curyy;
|
||||
mosaic_y_counter = mosaic;
|
||||
}
|
||||
else
|
||||
{
|
||||
mosaic_y_counter--;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t full_srcpix_y2 = realline * dy;
|
||||
int used_ysource_pos = full_srcpix_y2 >> 16;
|
||||
int ytilebbb = used_ysource_pos / 0x10;
|
||||
int use_tile_line = used_ysource_pos & 0xf;
|
||||
draw_sprite_line(screen, cliprect, use_tile_line, ypos, xpos, chainx, dx, dy, ytilebbb, chaini, currentsprite, chainy, xflip, yflip, zval, zsort, blend, checkerboard, mosaic);
|
||||
ypos++;
|
||||
}
|
||||
|
||||
currentsprite = nextsprite;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hng64_state::draw_sprite_line(screen_device& screen, const rectangle& cliprect, int32_t curyy, int16_t ypos, int16_t xpos, int chainx, int32_t dx, int32_t dy, int ytileblock, int chaini, int currentsprite, int chainy, int xflip, int yflip, uint16_t zval, bool zsort, bool blend, bool checkerboard, uint8_t mosaic)
|
||||
{
|
||||
uint32_t srcpix_x = 0;
|
||||
uint16_t srcpix = 0;
|
||||
|
||||
uint8_t mosaic_count_x = 0;
|
||||
@ -373,25 +387,13 @@ void hng64_state::draw_sprites_buffer(screen_device& screen, const rectangle& cl
|
||||
} while (srcpix_x < 0x100000);
|
||||
srcpix_x &= 0x0fffff;
|
||||
|
||||
// 0x3ff (0x200 sign bit) based on sams64_2 char select
|
||||
drawx &= 0x3ff;
|
||||
drawy &= 0x3ff;
|
||||
|
||||
if (drawx & 0x0200)drawx -= 0x400;
|
||||
if (drawy & 0x0200)drawy -= 0x400;
|
||||
|
||||
uint32_t tileno;
|
||||
uint16_t pal;
|
||||
uint8_t gfxregion;
|
||||
|
||||
get_tile_details(chaini, currentsprite, xdrw, ydrw, chainx, chainy, xflip, yflip, tileno, pal, gfxregion);
|
||||
zoom_transpen(m_sprite_bitmap, m_sprite_zbuffer, cliprect, m_gfxdecode->gfx(gfxregion), tileno, pal, xflip, yflip, drawx, cury, dx, dy, dstwidth, dstheight, 0, zval, zsort, blend, checkerboard, mosaic, mosaic_count_x, line, srcpix);
|
||||
drawx += dstwidth;
|
||||
}
|
||||
}
|
||||
drawy += dstheight;
|
||||
}
|
||||
currentsprite = nextsprite;
|
||||
}
|
||||
get_tile_details(chaini, currentsprite, xdrw, ytileblock, chainx, chainy, xflip, yflip, tileno, pal, gfxregion);
|
||||
zoom_transpen(m_sprite_bitmap, m_sprite_zbuffer, cliprect, m_gfxdecode->gfx(gfxregion), tileno, pal, xflip, yflip, xpos, ypos, dx, dy, dstwidth, 0, zval, zsort, blend, checkerboard, mosaic, mosaic_count_x, curyy, srcpix);
|
||||
xpos += dstwidth;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -560,26 +560,28 @@ void hng64_state::hng64_tilemap_draw_roz_core_line(screen_device &screen, bitmap
|
||||
* uint32_t | Bits | Use
|
||||
* | 3322 2222 2222 1111 1111 11 |
|
||||
* -------+-1098-7654-3210-9876-5432-1098-7654-3210-+----------------
|
||||
* 0 | ---- -Cdd ---- -??Z ---- ---- ---- ---u | C = global complex zoom
|
||||
* 0 | ---- -Cdd ---- -??Z ---- ---- ---- --uu | C = global complex zoom
|
||||
| 0000 0011 - road edge alt 1 | dd = global tilemap dimension selector
|
||||
| 0000 0111 - road edge alt 2 | ? = Always Set?
|
||||
| | Z = Global Zoom Disable?
|
||||
| | u = explicitly cleared from initialized value in sams64
|
||||
* 1 | oooo oooo oooo oooX ---- ---- ---- ---- | unknown - X is sometimes used (1 in demo of xrally, 0 in game) not always initialized whole register gets set to 0xffff during mosaic bit of roadedge intro
|
||||
* 1 | ---- ---- ---- ---- oooo oooo oYoo oooo | unknown - untouched in sams64 games, initialized elsewhere Y gets set to 4 at some points in xrally attract
|
||||
| | u = bit 0 is explicitly cleared from initialized value in sams64, both bits turned on for buriki 'split' effect
|
||||
* 1 | oooo oooo oooo oooX ---- ---- ---- ---- | unknown - X is sometimes used (1 in demo of xrally, 0 in game) not always initialized whole register gets set to 0xffff during mosaic bit of roadedge intro. Also buriki intro
|
||||
* | ---- ---- ---- ---- oooo oooo oYoo oooo | unknown - untouched in sams64 games, initialized elsewhere Y gets set to 4 at some points in xrally attract
|
||||
* 2 | xxxx xxxx xxxx xxxx ---- ---- ---- ---- | tilemap0 per layer flags
|
||||
* 2 | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap1 per layer flags
|
||||
* | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap1 per layer flags
|
||||
* 3 | xxxx xxxx xxxx xxxx ---- ---- ---- ---- | tilemap2 per layer flags
|
||||
* 3 | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap3 per layer flags
|
||||
* | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap3 per layer flags
|
||||
* 4 | xxxx xxxx xxxx xxxx ---- ---- ---- ---- | tilemap0 scrollbase when not floor, lineram offset when floor
|
||||
* 4 | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap1 scrollbase when not floor, lineram offset when floor
|
||||
* | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap1 scrollbase when not floor, lineram offset when floor
|
||||
* 5 | xxxx xxxx xxxx xxxx ---- ---- ---- ---- | tilemap3 scrollbase when not floor, lineram offset when floor
|
||||
* 5 | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap4 scrollbase when not floor, lineram offset when floor
|
||||
* | ---- ---- ---- ---- xxxx xxxx xxxx xxxx | tilemap4 scrollbase when not floor, lineram offset when floor
|
||||
* 6 | oooo oooo oooo oooo oooo oooo oooo oooo | unknown - always seems to be 000001ff (fatfurwa) ---- bfff (xrally, and fatfurwa despite comment? maybe reads MAME initialized value and changes it?)
|
||||
* 7 | oooo oooo oooo oooo oooo oooo oooo oooo | unknown - always seems to be 000001ff (fatfurwa) 5e00 3fff (xrally ^^ )
|
||||
* 8 | oooo oooo oooo oooo oooo oooo oooo oooo | unknown - always seems to be 80008000 (fatfurwa) 9e00 be00 (xrally ^^ )
|
||||
* 9 | oooo oooo oooo oooo oooo oooo oooo oooo | unknown - always seems to be 00000000 (fatfurwa)
|
||||
* a | oooo oooo oooo oooo oooo oooo oooo oooo | unknown - always seems to be 00000000 (fatfurwa)
|
||||
* 9 | oooo oooo oooo oooo ---- ---- ---- ---- | some kind of tilemap split effect?
|
||||
| ---- ---- ---- ---- oooo oooo oooo oooo | ^
|
||||
* a | oooo oooo oooo oooo ---- ---- ---- ---- | ^
|
||||
* | ---- ---- ---- ---- oooo oooo oooo oooo | ^
|
||||
* b | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | auto animation mask for tilemaps
|
||||
* c | xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx | auto animation bits for tilemaps
|
||||
* d | oooo oooo oooo oooo oooo oooo oooo oooo | not used ??
|
||||
@ -734,6 +736,11 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b
|
||||
if (m_screen_dis)
|
||||
return 0;
|
||||
|
||||
// set during transitions, could be 'disable all palette output'?
|
||||
if ((m_tcram[0x24 / 4] >> 16) & 0x0002)
|
||||
return 0;
|
||||
|
||||
|
||||
// If the auto-animation mask or bits have changed search for tiles using them and mark as dirty
|
||||
const uint32_t animmask = m_videoregs[0x0b];
|
||||
const uint32_t animbits = m_videoregs[0x0c];
|
||||
@ -844,61 +851,78 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b
|
||||
}
|
||||
}
|
||||
|
||||
// Layer the global frame buffer operations on top of everything
|
||||
// transition_control(bitmap, cliprect);
|
||||
|
||||
|
||||
#if HNG64_VIDEO_DEBUG
|
||||
if (0)
|
||||
popmessage("%08x %08x %08x %08x %08x", m_spriteregs[0], m_spriteregs[1], m_spriteregs[2], m_spriteregs[3], m_spriteregs[4]);
|
||||
|
||||
// see notes at top for more detailed info on these
|
||||
if (0)
|
||||
popmessage("%08x %08x TR(%04x %04x %04x %04x) SB(%04x %04x %04x %04x) %08x %08x %08x %08x %08x AA(%08x %08x) %08x",
|
||||
m_videoregs[0x00],
|
||||
m_videoregs[0x01],
|
||||
(m_videoregs[0x02] >> 16) & 0xffff,
|
||||
(m_videoregs[0x02] >> 0) & 0xffff, // ss64_2 debug mode indicates that 0x0040 is enable!
|
||||
(m_videoregs[0x03] >> 16) & 0xffff, // buriki agrees (debug data on text layer) xrally agress (pink layer)
|
||||
(m_videoregs[0x03] >> 0) & 0xffff, // fatal fury doesn't (all backgrounds have it set) joy
|
||||
(m_videoregs[0x04] >> 16) & 0xffff,
|
||||
(m_videoregs[0x04] >> 0) & 0xffff,
|
||||
(m_videoregs[0x05] >> 16) & 0xffff,
|
||||
(m_videoregs[0x05] >> 0) & 0xffff,
|
||||
m_videoregs[0x06],
|
||||
m_videoregs[0x07],
|
||||
m_videoregs[0x08],
|
||||
m_videoregs[0x09],
|
||||
m_videoregs[0x0a],
|
||||
m_videoregs[0x0b],
|
||||
m_videoregs[0x0c],
|
||||
popmessage("%08x %08x\nTR(%04x %04x %04x %04x)\nSB(%04x %04x %04x %04x)\n%08x %08x %08x\nSPLIT?(%04x %04x %04x %04x)\nAA(%08x %08x)\n%08x",
|
||||
// global tilemap control regs?
|
||||
m_videoregs[0x00], m_videoregs[0x01],
|
||||
// general per-tilemap regs
|
||||
(m_videoregs[0x02] >> 16) & 0xffff, (m_videoregs[0x02] >> 0) & 0xffff, (m_videoregs[0x03] >> 16) & 0xffff, (m_videoregs[0x03] >> 0) & 0xffff,
|
||||
// scrollbase regs
|
||||
(m_videoregs[0x04] >> 16) & 0xffff, (m_videoregs[0x04] >> 0) & 0xffff, (m_videoregs[0x05] >> 16) & 0xffff, (m_videoregs[0x05] >> 0) & 0xffff,
|
||||
// initialized to fixed values?
|
||||
m_videoregs[0x06], m_videoregs[0x07], m_videoregs[0x08],
|
||||
// used when a single tilemap gets 'split' on Buriki player entrances?
|
||||
(m_videoregs[0x09] >> 16) & 0xffff, (m_videoregs[0x09] >> 0) & 0xffff, (m_videoregs[0x0a] >> 16) & 0xffff, (m_videoregs[0x0a] >> 0) & 0xffff,
|
||||
// Auto Animation registers
|
||||
m_videoregs[0x0b], m_videoregs[0x0c],
|
||||
// unused?
|
||||
m_videoregs[0x0d]);
|
||||
|
||||
if (0)
|
||||
popmessage("TC: %08x %08x %08x %08x : %08x %08x\n%08x %08x\n%08x %08x\n%08x %08x : %08x %08x %08x %08x : %08x %08x\n%08x %08x : %08x %08x %08x %08x",
|
||||
m_tcram[0x00 / 4],
|
||||
m_tcram[0x04 / 4],
|
||||
m_tcram[0x08 / 4], // tilemaps 0/1 ?
|
||||
m_tcram[0x0c / 4], // ss64_2 debug 04000000 = 'half' on tm1 00000004 = 'half' on tm3 (used in transitions?)
|
||||
m_tcram[0x10 / 4],
|
||||
m_tcram[0x14 / 4],
|
||||
if (1)
|
||||
popmessage("TC: %08x MINX(%d) MINY(%d) MAXX(%d) MAXY(%d)\nBLEND ENABLES? %02x %02x %02x | %02x %02x %02x\nUNUSED?(%04x)\n%04x\n%04x\nMASTER FADES?(%08x %08x)\nUNUSED?(%08x)\nBITFIELD REGS(%04x)\nPALEFFECT_ENABLES(%d %d %d %d %d %d %d %d)\n PALFADES?(%08x %08x : %08x %08x : %08x %08x : %08x %08x)\n % 08x % 08x : % 08x % 08x % 08x % 08x",
|
||||
m_tcram[0x00 / 4], // 0007 00e4 (fatfurwa, bbust2)
|
||||
(m_tcram[0x04 / 4] >> 16) & 0xffff, (m_tcram[0x04 / 4] >> 0) & 0xffff, // 0000 0010 (fatfurwa) 0000 0000 (bbust2, xrally)
|
||||
(m_tcram[0x08 / 4] >> 16) & 0xffff, (m_tcram[0x08 / 4] >> 0) & 0xffff, // 0200 01b0 (fatfurwa) 0200 01c0 (bbust2, xrally)
|
||||
|
||||
(m_tcram[0x0c / 4] >> 24) & 0xff, // 04 = 'blend' on tm1
|
||||
(m_tcram[0x0c / 4] >> 16) & 0xff, // 04 = blend all sprites? (buriki intro, text fades?)
|
||||
(m_tcram[0x0c / 4] >> 8) & 0xff,
|
||||
(m_tcram[0x0c / 4] >> 0) & 0xff, // 04 = 'blend' on tm3 (used in transitions?)
|
||||
(m_tcram[0x10 / 4] >> 24) & 0xff,
|
||||
(m_tcram[0x10 / 4] >> 16) & 0xff,
|
||||
|
||||
m_tcram[0x10 / 4] & 0xffff, // unused?
|
||||
|
||||
(m_tcram[0x14 / 4] >> 16) & 0xffff, // typically 0007 or 0001, - 0011 on ss64 ingame, 0009 on continue screen
|
||||
(m_tcram[0x14 / 4] >> 0) & 0xffff, // 0xxx ? (often 0555 or 0fff, seen 56a, 57f too)
|
||||
|
||||
// these are used for 'fade to black' in most cases, but
|
||||
// in xrally attract, when one image is meant to fade into another, one value increases while the other decreases
|
||||
m_tcram[0x18 / 4], // xRGB fade values? (roadedge attract)
|
||||
m_tcram[0x1c / 4], // xRGB fade values? (roadedge attract) fades on fatfurwa before buildings in intro
|
||||
|
||||
m_tcram[0x20 / 4], // something else?
|
||||
m_tcram[0x24 / 4], // something else?
|
||||
m_tcram[0x20 / 4], // unused?
|
||||
|
||||
// some kind of bitfields
|
||||
(m_tcram[0x24 / 4] >> 16) & 0xffff, // 0002 gets set in roadedge during some transitions (layers are disabled? blacked out?) 0001 set on SNK logo in roadedge
|
||||
(m_tcram[0x24 / 4] >> 0) & 0x3, // 0001 gets set when in a tunnel on roadedge in 1st person mode (state isn't updated otherwise, switching back to 3rd person in a tunnel leaves it set until you flick back to 1st person) briefly set to 3c on roadedge car select during 'no fb clear' effect?
|
||||
(m_tcram[0x24 / 4] >> 2) & 0x3,
|
||||
(m_tcram[0x24 / 4] >> 4) & 0x3,
|
||||
(m_tcram[0x24 / 4] >> 6) & 0x3,
|
||||
(m_tcram[0x24 / 4] >> 8) & 0x3,
|
||||
(m_tcram[0x24 / 4] >> 10) & 0x3,
|
||||
(m_tcram[0x24 / 4] >> 12) & 0x3,
|
||||
(m_tcram[0x24 / 4] >> 14) & 0x3,
|
||||
|
||||
// 7 of these fade during the buriki SNK logo (probably redundant)
|
||||
// in roadedge they're just set to
|
||||
// 0x00000000, 0x01000000, 0x02000000, 0x03000000, 0x04000000, 0x05000000, 0x06000000, 0x07000000
|
||||
// the first 8 bits seem to be which palette this affects (so 0x0b is colours 0xb00-0xbff as you see with xrally 1st person?)
|
||||
// enabled with m_tcram[0x24 / 4] regs above? (see note)
|
||||
|
||||
m_tcram[0x28 / 4], // ?RGB fade values (buriki jumbotron) fades on fatfurwa before high score table etc. + bottom value only on 'fade to red' part of fatfurywa intro
|
||||
m_tcram[0x2c / 4], // ?RGB fade values (buriki jumbotron)
|
||||
m_tcram[0x30 / 4],
|
||||
m_tcram[0x34 / 4],
|
||||
m_tcram[0x38 / 4],
|
||||
m_tcram[0x3c / 4],
|
||||
m_tcram[0x3c / 4], // gets used for the 1st person view on xrally - maybe some fade effect on the front of the car?
|
||||
m_tcram[0x40 / 4],
|
||||
m_tcram[0x44 / 4],
|
||||
|
||||
@ -919,6 +943,21 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b
|
||||
0011057f blending?
|
||||
0001057f
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
palette manipulation note
|
||||
|
||||
pal7 pal6 pal5 pal4 pal3 pal2 pal1 pal0 // which fade register those bits relate to?
|
||||
00 00 11 00 00 00 10 10 // bits in (m_tcram[0x24 / 4] >> 0) (set to 0c0a in this example)
|
||||
|
||||
an entry of 00 means palette effect not in use?
|
||||
an entry of 11 means subtractive?
|
||||
an entry of 10 means addition?
|
||||
an entry of 01 means??
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@ -971,11 +1010,73 @@ WRITE_LINE_MEMBER(hng64_state::screen_vblank_hng64)
|
||||
* Or maybe they set transition type (there seems to be a cute scaling-squares transition in there somewhere)...
|
||||
*/
|
||||
|
||||
void hng64_state::update_palette_entry(int entry)
|
||||
{
|
||||
uint32_t data = m_paletteram[entry];
|
||||
|
||||
int16_t r = (data >> 16) & 0xff;
|
||||
int16_t g = (data >> 8) & 0xff;
|
||||
int16_t b = (data >> 0) & 0xff;
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
uint32_t tcdata = m_tcram[(0x28 / 4) + i];
|
||||
uint8_t tcregion = (tcdata & 0x0f000000) >> 24;
|
||||
|
||||
if (tcregion == (entry >> 8))
|
||||
{
|
||||
uint8_t bmod = (tcdata >> 16) & 0xff;
|
||||
uint8_t gmod = (tcdata >> 8) & 0xff;
|
||||
uint8_t rmod = (tcdata >> 0) & 0xff;
|
||||
|
||||
uint8_t tcreg = (m_tcram[0x24 / 4] >> (i << 1)) & 3;
|
||||
switch (tcreg)
|
||||
{
|
||||
case 0x00: // this entry is disabled
|
||||
break;
|
||||
case 0x01: // this entry is disabled(?)
|
||||
break;
|
||||
case 0x02: // additive blending
|
||||
r = r + rmod;
|
||||
if (r > 0xff)
|
||||
r = 0xff;
|
||||
g = g + gmod;
|
||||
if (g > 0xff)
|
||||
g = 0xff;
|
||||
b = b + bmod;
|
||||
if (b > 0xff)
|
||||
b = 0xff;
|
||||
break;
|
||||
case 0x03: // subtractive blending
|
||||
r = r - rmod;
|
||||
if (r < 0x00)
|
||||
r = 0x00;
|
||||
g = g - gmod;
|
||||
if (g < 0x00)
|
||||
g = 0x00;
|
||||
b = b - bmod;
|
||||
if (b < 0x00)
|
||||
b = 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_palette->set_pen_color(entry, r,g,b);
|
||||
}
|
||||
|
||||
void hng64_state::pal_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_paletteram[offset]);
|
||||
update_palette_entry(offset);
|
||||
}
|
||||
|
||||
// Transition Control memory.
|
||||
void hng64_state::tcram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
uint32_t *hng64_tcram = m_tcram;
|
||||
|
||||
uint32_t old_data = hng64_tcram[offset];
|
||||
COMBINE_DATA(&hng64_tcram[offset]);
|
||||
|
||||
if (offset == 0x02)
|
||||
@ -998,6 +1099,39 @@ void hng64_state::tcram_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
visarea.set(min_x, min_x + max_x - 1, min_y, min_y + max_y - 1);
|
||||
m_screen->configure(HTOTAL, VTOTAL, visarea, m_screen->frame_period().attoseconds());
|
||||
}
|
||||
|
||||
if ((offset >= (0x28 / 4)) && (offset < (0x48 / 4)))
|
||||
{
|
||||
uint32_t new_data = hng64_tcram[offset];
|
||||
if (old_data != new_data)
|
||||
{
|
||||
// the old blend value no longer applies, so update the colours referenced by that
|
||||
uint8_t old_tcregion = (old_data & 0x0f000000) >> 24;
|
||||
for (int i = 0; i < 0x100; i++)
|
||||
{
|
||||
update_palette_entry((old_tcregion * 0x100) + i);
|
||||
}
|
||||
// update the colours referenced by the new blend register
|
||||
uint8_t new_tcregion = (new_data & 0x0f000000) >> 24;
|
||||
for (int i = 0; i < 0x100; i++)
|
||||
{
|
||||
update_palette_entry((new_tcregion * 0x100) + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (offset == (0x24 / 4))
|
||||
{
|
||||
// lazy, just update the lot
|
||||
uint32_t new_data = hng64_tcram[offset];
|
||||
if (old_data != new_data)
|
||||
{
|
||||
for (int i = 0; i < 0x1000; i++)
|
||||
{
|
||||
update_palette_entry(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t hng64_state::tcram_r(offs_t offset)
|
||||
@ -1010,88 +1144,6 @@ uint32_t hng64_state::tcram_r(offs_t offset)
|
||||
return m_tcram[offset];
|
||||
}
|
||||
|
||||
// Very much a work in progress - no hard testing has been done
|
||||
void hng64_state::transition_control(bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// If either of the fading memory regions is non-zero...
|
||||
if (m_tcram[0x00000007] != 0x00000000 || m_tcram[0x0000000a] != 0x00000000)
|
||||
{
|
||||
const int32_t darkR = int32_t(m_tcram[0x00000007] & 0xff);
|
||||
const int32_t darkG = int32_t((m_tcram[0x00000007] >> 8) & 0xff);
|
||||
const int32_t darkB = int32_t((m_tcram[0x00000007] >> 16) & 0xff);
|
||||
|
||||
const int32_t brigR = int32_t(m_tcram[0x0000000a] & 0xff);
|
||||
const int32_t brigG = int32_t((m_tcram[0x0000000a] >> 8) & 0xff);
|
||||
const int32_t brigB = int32_t((m_tcram[0x0000000a] >> 16) & 0xff);
|
||||
|
||||
for (int i = cliprect.min_x; i < cliprect.max_x; i++)
|
||||
{
|
||||
for (int j = cliprect.min_y; j < cliprect.max_y; j++)
|
||||
{
|
||||
rgb_t *thePixel = reinterpret_cast<rgb_t *>(&bitmap.pix(j, i));
|
||||
|
||||
int32_t finR = (int32_t)thePixel->r();
|
||||
int32_t finG = (int32_t)thePixel->g();
|
||||
int32_t finB = (int32_t)thePixel->b();
|
||||
|
||||
#if 0
|
||||
float colorScaleR, colorScaleG, colorScaleB;
|
||||
|
||||
// Apply the darkening pass (0x07)...
|
||||
colorScaleR = 1.0f - (float)(m_tcram[0x00000007] & 0xff) / 255.0f;
|
||||
colorScaleG = 1.0f - (float)((m_tcram[0x00000007] >> 8) & 0xff) / 255.0f;
|
||||
colorScaleB = 1.0f - (float)((m_tcram[0x00000007] >> 16) & 0xff) / 255.0f;
|
||||
|
||||
finR = ((float)thePixel->r() * colorScaleR);
|
||||
finG = ((float)thePixel->g() * colorScaleG);
|
||||
finB = ((float)thePixel->b() * colorScaleB);
|
||||
|
||||
// Apply the lightening pass (0x0a)...
|
||||
colorScaleR = 1.0f + (float)(m_tcram[0x0000000a] & 0xff) / 255.0f;
|
||||
colorScaleG = 1.0f + (float)((m_tcram[0x0000000a] >> 8) & 0xff) / 255.0f;
|
||||
colorScaleB = 1.0f + (float)((m_tcram[0x0000000a] >> 16) & 0xff) / 255.0f;
|
||||
|
||||
finR *= colorScaleR;
|
||||
finG *= colorScaleG;
|
||||
finB *= colorScaleB;
|
||||
|
||||
// Clamp
|
||||
if (finR > 255.0f) finR = 255.0f;
|
||||
if (finG > 255.0f) finG = 255.0f;
|
||||
if (finB > 255.0f) finB = 255.0f;
|
||||
#endif
|
||||
|
||||
// Subtractive fading
|
||||
if (m_tcram[0x00000007] != 0x00000000)
|
||||
{
|
||||
finR -= darkR;
|
||||
finG -= darkG;
|
||||
finB -= darkB;
|
||||
}
|
||||
|
||||
// Additive fading
|
||||
if (m_tcram[0x0000000a] != 0x00000000)
|
||||
{
|
||||
finR += brigR;
|
||||
finG += brigG;
|
||||
finB += brigB;
|
||||
}
|
||||
|
||||
// Clamp the high end
|
||||
if (finR > 255) finR = 255;
|
||||
if (finG > 255) finG = 255;
|
||||
if (finB > 255) finB = 255;
|
||||
|
||||
// Clamp the low end
|
||||
if (finR < 0) finR = 0;
|
||||
if (finG < 0) finG = 0;
|
||||
if (finB < 0) finB = 0;
|
||||
|
||||
*thePixel = rgb_t(255, (uint8_t)finR, (uint8_t)finG, (uint8_t)finB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hng64_state::video_start()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user