mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
SunPlus refactoring checkpoint (nw) (#6793)
This commit is contained in:
parent
509a99b6c0
commit
3708071150
@ -1538,6 +1538,9 @@ void sunplus_gcm394_base_device::device_reset()
|
||||
m_system_dma_memtype = 0x0000;
|
||||
|
||||
m_unk_timer->adjust(attotime::from_hz(60), 0, attotime::from_hz(60));
|
||||
|
||||
m_spg_video->set_video_spaces(this->space(AS_PROGRAM), *m_cs_space, m_csbase);
|
||||
m_spg_video->reset();
|
||||
}
|
||||
|
||||
void generalplus_gpac800_device::device_reset()
|
||||
@ -1649,7 +1652,6 @@ uint16_t sunplus_gcm394_base_device::read_space(uint32_t offset)
|
||||
|
||||
|
||||
|
||||
|
||||
void sunplus_gcm394_base_device::write_space(uint32_t offset, uint16_t data)
|
||||
{
|
||||
address_space& space = this->space(AS_PROGRAM);
|
||||
|
@ -8,97 +8,6 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/* lots of games, including wrlshunt are not copying tilemap data properly
|
||||
the analysis below is for wrlshunt, although gormiti could prove to be an easier case to look at
|
||||
while jak_ths and jak_swc might be more difficult (the latter uses line/bitmap mode, but still
|
||||
fails to copy the line data)
|
||||
|
||||
|
||||
--
|
||||
|
||||
wrlshunt BG Tilemap location note
|
||||
|
||||
background tilemap appears to be at 24ad30 - 24af87 (byte address) in RAM == 125698 - 1257c3 (word address)
|
||||
there are pointers to this
|
||||
(2879-287a) = 98 56 12 00 (00125698) (main background tilemap data is at this address)
|
||||
(287b-287c) = 30 5e 12 00 (00125e30) (address for other layer tilemap) (or 'end' of above)
|
||||
where do we get these copied to registers or used as a source to copy from?
|
||||
|
||||
|
||||
-- callled from here
|
||||
058F79: call 054e56 (with values above, for tilemap 0)
|
||||
and
|
||||
058FB1: call 054e56 (for tilemap 1)
|
||||
(both of these are at the start of the function at 058F46, which we loop in at the moment, possible main loop for the menu?)
|
||||
|
||||
there are other calls in the code, but those are the ones before sprites are uploaded for the menu
|
||||
|
||||
--
|
||||
054E91: r4 = [bp+27] (contains lower part of address)
|
||||
054E92: ds:[r1++] = r4 -- write 5698 to 2879
|
||||
054E93: r4 = [bp+28] (contains upper part of address)
|
||||
054E94: ds:[r1] = r4 -- write 0012 to 287a
|
||||
|
||||
(this is a huge function that ends at 55968, also has lots of calls in it)
|
||||
|
||||
---
|
||||
|
||||
the base for tilemap params being written to RAM is 2879 + 0xe * tilmap number (0,1,2,3)
|
||||
the code to calculate this offset from base uses 32-bit multiplication and even sign extends the tilemap number before using it, making it
|
||||
look more complex than it really is!
|
||||
|
||||
054E7B: 0B0D 0088 bp = bp + 0088
|
||||
054E7D: 9800 r4 = [bp+00] -- which tilemap? (0,1,2,3)
|
||||
054E7E: 2B0D 0088 bp = bp - 0088
|
||||
|
||||
054E80: 973C r3 = r4 asr 4 -- sign extend tilemap 16-bit register r4 with r3 forming the upper word (always 0)
|
||||
054E81: 973B r3 = r3 asr 4
|
||||
054E82: 973B r3 = r3 asr 4
|
||||
054E83: 973B r3 = r3 asr 4
|
||||
|
||||
054E84: D688 push r3, r3 to [sp] -- push onto stack for use in call below
|
||||
054E85: D888 push r4, r4 to [sp]
|
||||
|
||||
054E86: 964E r3 = 0e -- store 0000 000e as the 32-bit value to multply with
|
||||
054E87: 9840 r4 = 00
|
||||
054E88: D890 push r3, r4 to [sp] -- push that onto stack for function call below
|
||||
|
||||
054E89: F045 D706 call 05d706 -- returns result in r1,r2
|
||||
|
||||
the result of this is then added to the base value of 2879 (which was stored earlier)
|
||||
an additional offset is then added for each parameter.
|
||||
|
||||
this code is repeated multiple times, with slight changes
|
||||
|
||||
---
|
||||
|
||||
by the time you hit 055098 (which is a switch on tilemap type to disable a tilemap) the following params have been put at
|
||||
2879 ( tilemap 0 call )
|
||||
2879 + 0x0e (tilemap 1 call )
|
||||
|
||||
tmap0 params
|
||||
5698 0012 | 5E30 0012 | 0280 01E0 | 0002 0020 0020 0000 0000 0100 0000 0000
|
||||
125698 | 125e30 | = 640 = 480
|
||||
|
||||
tmap1 params
|
||||
7280 000D | 89F0 000D | 0280 01E0 | 0002 0020 0020 0002 0000 0040 0000 0000
|
||||
0d7280 | 0d89f0 | = 640 = 480 |
|
||||
|
||||
these parameter lists are not read after this? is there some kind of indirect dma mode, or is code not being called that should use them.
|
||||
plenty more code is called, including more that looks a lot like the above, some use of 707f and at the end of the funciton, code to
|
||||
write various tilemap registers, including reenabling the tilemap that was disabled around 055098.
|
||||
|
||||
--
|
||||
|
||||
|
||||
if you return rand() on 707f reads sometimes you see
|
||||
[:maincpu] pc:053775: r4 = r4 lsr r3 (5698 0009) : [:maincpu] result 002b (possible unrelated)
|
||||
|
||||
(bg tile addressing is also done by tile #, like the sprites, not fixed step like smartfp)
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "generalplus_gpl16250soc_video.h"
|
||||
@ -118,20 +27,15 @@ DEFINE_DEVICE_TYPE(GCM394_VIDEO, gcm394_video_device, "gcm394_video", "GeneralPl
|
||||
|
||||
gcm394_base_video_device::gcm394_base_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
//device_gfx_interface(mconfig, *this, nullptr),
|
||||
device_video_interface(mconfig, *this),
|
||||
m_cpu(*this, finder_base::DUMMY_TAG),
|
||||
m_screen(*this, finder_base::DUMMY_TAG),
|
||||
// m_scrollram(*this, "scrollram"),
|
||||
m_video_irq_cb(*this),
|
||||
m_palette(*this, "palette"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_space_read_cb(*this),
|
||||
m_rowscroll(*this, "^rowscroll"),
|
||||
m_rowzoom(*this, "^rowzoom"),
|
||||
// m_pal_displaybank_high(0),
|
||||
// m_pal_sprites(0x100),
|
||||
// m_pal_back(0x000),
|
||||
m_alt_extrasprite_hack(0),
|
||||
m_alt_tile_addressing(0),
|
||||
m_renderer(*this, "renderer")
|
||||
@ -295,17 +199,6 @@ void gcm394_base_video_device::decodegfx(const char* tag)
|
||||
|
||||
void gcm394_base_video_device::device_start()
|
||||
{
|
||||
for (uint8_t i = 0; i < 32; i++)
|
||||
{
|
||||
m_rgb5_to_rgb8[i] = (i << 3) | (i >> 2);
|
||||
}
|
||||
for (uint16_t i = 0; i < 0x8000; i++)
|
||||
{
|
||||
m_rgb555_to_rgb888[i] = (m_rgb5_to_rgb8[(i >> 10) & 0x1f] << 16) |
|
||||
(m_rgb5_to_rgb8[(i >> 5) & 0x1f] << 8) |
|
||||
(m_rgb5_to_rgb8[(i >> 0) & 0x1f] << 0);
|
||||
}
|
||||
|
||||
m_video_irq_cb.resolve();
|
||||
|
||||
m_maxgfxelement = 0;
|
||||
@ -319,10 +212,6 @@ void gcm394_base_video_device::device_start()
|
||||
m_screenpos_timer = timer_alloc(TIMER_SCREENPOS);
|
||||
m_screenpos_timer->adjust(attotime::never);
|
||||
|
||||
|
||||
save_item(NAME(m_screenbuf));
|
||||
save_item(NAME(m_rgb5_to_rgb8));
|
||||
save_item(NAME(m_rgb555_to_rgb888));
|
||||
save_item(NAME(m_page0_addr_lsb));
|
||||
save_item(NAME(m_page0_addr_msb));
|
||||
save_item(NAME(m_page1_addr_lsb));
|
||||
@ -365,10 +254,8 @@ void gcm394_base_video_device::device_start()
|
||||
save_item(NAME(m_page3_addr_lsb));
|
||||
save_item(NAME(m_page3_addr_msb));
|
||||
save_item(NAME(m_spriteram));
|
||||
save_item(NAME(m_spriteextra));
|
||||
save_item(NAME(m_paletteram));
|
||||
save_item(NAME(m_maxgfxelement));
|
||||
// save_item(NAME(m_pal_displaybank_high));
|
||||
save_item(NAME(m_alt_tile_addressing));
|
||||
}
|
||||
|
||||
@ -390,16 +277,14 @@ void gcm394_base_video_device::device_reset()
|
||||
m_tmap1_scroll[i] = 0x0000;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 0x400; i++)
|
||||
for (int i = 0; i < 0x400*2; i++)
|
||||
{
|
||||
m_spriteextra[i] = 0x0000;
|
||||
m_spriteram[i] = 0x0000;
|
||||
}
|
||||
|
||||
for (int i=0;i<0x100 * 0x10;i++)
|
||||
m_paletteram[i] = machine().rand()&0x7fff;
|
||||
|
||||
|
||||
m_707f = 0x0000;
|
||||
m_703a_palettebank = 0x0000;
|
||||
m_video_irq_enable = 0x0000;
|
||||
@ -435,546 +320,7 @@ void gcm394_base_video_device::device_reset()
|
||||
m_page3_addr_lsb = 0;
|
||||
m_page3_addr_msb = 0;
|
||||
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Video Hardware *
|
||||
*************************/
|
||||
|
||||
template<gcm394_base_video_device::blend_enable_t Blend, gcm394_base_video_device::rowscroll_enable_t RowScroll, gcm394_base_video_device::flipx_t FlipX>
|
||||
void gcm394_base_video_device::draw(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t bitmap_addr, uint32_t tile, int32_t h, int32_t w, uint8_t bpp, uint32_t yflipmask, uint32_t palette_offset, int addressing_mode)
|
||||
{
|
||||
uint32_t nc_bpp = ((bpp) + 1) << 1;
|
||||
|
||||
// probably don't do this here as this SoC has extended palette for higher bpp modes
|
||||
//palette_offset >>= nc_bpp;
|
||||
//palette_offset <<= nc_bpp;
|
||||
|
||||
uint32_t bits_per_row = nc_bpp * w / 16;
|
||||
uint32_t words_per_tile;
|
||||
|
||||
if (addressing_mode == 1)
|
||||
{
|
||||
words_per_tile = bits_per_row * h;
|
||||
}
|
||||
else
|
||||
{
|
||||
words_per_tile = 8; // seems to be correct for sprites regardless of size / bpp on smartfp
|
||||
}
|
||||
|
||||
int x_max;
|
||||
if (m_707f & 0x0010)
|
||||
{
|
||||
x_max = 0x400;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_max = 0x200;
|
||||
}
|
||||
|
||||
|
||||
uint32_t m = (bitmap_addr) + (words_per_tile * tile + bits_per_row * (line ^ yflipmask));
|
||||
|
||||
|
||||
uint32_t bits = 0;
|
||||
uint32_t nbits = 0;
|
||||
uint32_t y = line;
|
||||
|
||||
int yy = (yoff + y);// &0x1ff;
|
||||
//if (yy >= 0x01c0)
|
||||
// yy -= 0x0200;
|
||||
|
||||
if (yy > cliprect.max_y || yy < 0)
|
||||
return;
|
||||
|
||||
int y_index = yy * m_screen->width();
|
||||
|
||||
for (int32_t x = FlipX ? (w - 1) : 0; FlipX ? x >= 0 : x < w; FlipX ? x-- : x++)
|
||||
{
|
||||
int xx = xoff + x;
|
||||
|
||||
bits <<= nc_bpp;
|
||||
|
||||
if (nbits < nc_bpp)
|
||||
{
|
||||
uint16_t b = m_space_read_cb((m++)&0x7ffffff); // smartfp suggests either 0x7ffffff mask, or some bits are being set incorrectly, jak_s500 needs over 0x3ffffff at least
|
||||
b = (b << 8) | (b >> 8);
|
||||
bits |= b << (nc_bpp - nbits);
|
||||
nbits += 16;
|
||||
}
|
||||
nbits -= nc_bpp;
|
||||
|
||||
int pen = bits >> 16;
|
||||
|
||||
int current_palette_offset = palette_offset;
|
||||
|
||||
uint32_t pal = current_palette_offset + pen;
|
||||
bits &= 0xffff;
|
||||
|
||||
if (RowScroll)
|
||||
xx -= 0;// (int16_t)m_scrollram[yy & 0x1ff];
|
||||
|
||||
xx &= (x_max-1);
|
||||
if (xx >= (x_max-0x40))
|
||||
xx -= x_max;
|
||||
|
||||
if (xx >= 0 && xx <= cliprect.max_x)
|
||||
{
|
||||
int pix_index = xx + y_index;
|
||||
|
||||
uint16_t rgb = m_paletteram[pal];
|
||||
|
||||
if (!(rgb & 0x8000))
|
||||
{
|
||||
if (Blend)
|
||||
{
|
||||
/*
|
||||
m_screenbuf[pix_index] = (mix_channel((uint8_t)(m_screenbuf[pix_index] >> 16), m_rgb5_to_rgb8[(rgb >> 10) & 0x1f]) << 16) |
|
||||
(mix_channel((uint8_t)(m_screenbuf[pix_index] >> 8), m_rgb5_to_rgb8[(rgb >> 5) & 0x1f]) << 8) |
|
||||
(mix_channel((uint8_t)(m_screenbuf[pix_index] >> 0), m_rgb5_to_rgb8[rgb & 0x1f]));
|
||||
*/
|
||||
m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t *regs, uint16_t *scroll, int which)
|
||||
{
|
||||
uint32_t xscroll = scroll[0];
|
||||
uint32_t yscroll = scroll[1];
|
||||
uint32_t attr_reg = regs[0];
|
||||
uint32_t ctrl_reg = regs[1];
|
||||
uint32_t tilemap = regs[2];
|
||||
uint32_t palette_map = regs[3];
|
||||
address_space &space = m_cpu->space(AS_PROGRAM);
|
||||
|
||||
// attr_reg bits
|
||||
// -Bzz pppp hhww ffbb
|
||||
//
|
||||
// B = blend
|
||||
// zz = depth
|
||||
// pppp = palette
|
||||
// ff = flips
|
||||
// bb = bpp
|
||||
// hh = height
|
||||
// ww = width
|
||||
|
||||
// ctrl_reg bits
|
||||
// ---- ---B h--r ewRl
|
||||
//
|
||||
// e = enable
|
||||
// l = bitmape/line mode
|
||||
// r = rowscroll
|
||||
// w = wallpaper mode
|
||||
// R = regset mode
|
||||
// h = high colour
|
||||
// B = blend
|
||||
|
||||
|
||||
if (!(ctrl_reg & 0x0008))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (((attr_reg & 0x3000) >> 12) != priority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctrl_reg & 0x0001) // bitmap mode jak_car2 and jak_s500 use for the ingame race sections, also have a bitmap test in test mode
|
||||
{
|
||||
if (0)
|
||||
{
|
||||
if (ctrl_reg & 0x0010)
|
||||
popmessage("bitmap mode %08x with rowscroll\n", bitmap_addr);
|
||||
else
|
||||
popmessage("bitmap mode %08x\n", bitmap_addr);
|
||||
}
|
||||
|
||||
// note, in interlace modes it appears every other line is unused? (480 entry table, but with blank values)
|
||||
// and furthermore the rowscroll and rowzoom tables only have 240 entries, not enough for every line
|
||||
// the end of the rowscroll table (entries 240-255) contain something else, maybe garbage data as it's offscreen, maybe not
|
||||
|
||||
uint32_t linebase = space.read_word(tilemap + scanline); // every other word is unused, but there are only enough entries for 240 lines then, sometimes to do with interlace mode?
|
||||
uint16_t palette = space.read_word(palette_map + (scanline / 2));
|
||||
|
||||
if (scanline & 1)
|
||||
palette >>= 8;
|
||||
else
|
||||
palette &= 0xff;
|
||||
|
||||
if (!linebase)
|
||||
return;
|
||||
|
||||
linebase = linebase | (palette << 16);
|
||||
|
||||
// this logic works for jak_s500 and the test modes to get the correct base, doesn't seem to work for jak_car2 ingame, maybe data is copied to wrong place?
|
||||
int gfxbase = (bitmap_addr&0x7ffffff) + (linebase&0x7ffffff);
|
||||
|
||||
for (int i = 0; i < 160; i++) // will have to be 320 for jak_car2 ingame, jak_s500 lines are wider than screen, and zoomed
|
||||
{
|
||||
uint16_t pix = m_space_read_cb((gfxbase++)&0x7ffffff);
|
||||
int xx;
|
||||
int y_index = scanline * m_screen->width();
|
||||
uint16_t pal;
|
||||
|
||||
if ((scanline >= 0) && (scanline < 480))
|
||||
{
|
||||
xx = i * 2;
|
||||
|
||||
pal = (pix & 0xff) | 0x100;
|
||||
|
||||
if (xx >= 0 && xx <= cliprect.max_x)
|
||||
{
|
||||
int pix_index = xx + y_index;
|
||||
|
||||
uint16_t rgb = m_paletteram[pal];
|
||||
|
||||
if (!(rgb & 0x8000))
|
||||
{
|
||||
m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb];
|
||||
}
|
||||
}
|
||||
|
||||
xx = (i * 2)+1;
|
||||
pal = (pix >> 8) + 0x100;
|
||||
|
||||
if (xx >= 0 && xx <= cliprect.max_x)
|
||||
{
|
||||
int pix_index = xx + y_index;
|
||||
|
||||
uint16_t rgb = m_paletteram[pal];
|
||||
|
||||
if (!(rgb & 0x8000))
|
||||
{
|
||||
m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t tile_h = 8 << ((attr_reg & 0x00c0) >> 6);
|
||||
uint32_t tile_w = 8 << ((attr_reg & 0x0030) >> 4);
|
||||
|
||||
int total_width;
|
||||
int use_alt_drawmode = m_alt_tile_addressing;
|
||||
int y_mask = 0;
|
||||
|
||||
// just a guess based on this being set on the higher resolution tilemaps we've seen, could be 100% incorrect register
|
||||
if ((attr_reg >> 15) & 0x1)
|
||||
{
|
||||
total_width = 1024;
|
||||
y_mask = 0x1ff;
|
||||
// use_alt_drawmode = 1; // probably doesn't control this
|
||||
}
|
||||
else
|
||||
{
|
||||
total_width = 512;
|
||||
y_mask = 0xff;
|
||||
// use_alt_drawmode = 0; // probably doesn't control this
|
||||
}
|
||||
|
||||
uint32_t tile_count_x = total_width / tile_w;
|
||||
|
||||
uint32_t bitmap_y = (scanline + yscroll) & y_mask;
|
||||
uint32_t y0 = bitmap_y / tile_h;
|
||||
uint32_t tile_scanline = bitmap_y % tile_h;
|
||||
uint32_t tile_address = tile_count_x * y0;
|
||||
|
||||
for (uint32_t x0 = 0; x0 < tile_count_x; x0++, tile_address++)
|
||||
{
|
||||
uint32_t yy = ((tile_h * y0 - yscroll + 0x10) & y_mask) - 0x10;
|
||||
uint32_t xx = (tile_w * x0 - xscroll) & (total_width-1);
|
||||
uint32_t tile = (ctrl_reg & 0x0004) ? space.read_word(tilemap) : space.read_word(tilemap + tile_address);
|
||||
|
||||
if (!tile)
|
||||
continue;
|
||||
|
||||
bool blend;
|
||||
bool row_scroll;
|
||||
bool flip_x;
|
||||
uint32_t yflipmask;
|
||||
uint32_t palette_offset;
|
||||
|
||||
blend = (attr_reg & 0x4000 || ctrl_reg & 0x0100);
|
||||
row_scroll = (ctrl_reg & 0x0010);
|
||||
|
||||
if ((ctrl_reg & 0x0002) == 0) // RegSet:0
|
||||
{
|
||||
uint16_t palette = (ctrl_reg & 0x0004) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2);
|
||||
if (x0 & 1)
|
||||
palette >>= 8;
|
||||
|
||||
// 'palette' format
|
||||
// --ff pppp
|
||||
//
|
||||
// f = flip bits
|
||||
// p = palette
|
||||
|
||||
flip_x = palette & 0x10;
|
||||
yflipmask = (palette & 0x20) ? tile_h - 1 : 0;
|
||||
palette_offset = (palette & 0x0f) << 4;
|
||||
}
|
||||
else // RegSet:1
|
||||
{
|
||||
if (m_alt_tile_addressing == 0)
|
||||
{
|
||||
// smartfp needs the attribute table to contain extra tile bits even if regset is 1
|
||||
uint16_t palette = (ctrl_reg & 0x0004) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2);
|
||||
if (x0 & 1)
|
||||
palette >>= 8;
|
||||
|
||||
// 'palette' format
|
||||
// -- -ttt
|
||||
//
|
||||
// t = extra tile number bits
|
||||
|
||||
tile |= (palette & 0x0007) << 16;
|
||||
}
|
||||
|
||||
flip_x = (attr_reg & 0x0004);
|
||||
yflipmask = attr_reg & 0x0008 ? tile_h - 1 : 0;
|
||||
palette_offset = (attr_reg & 0x0f00) >> 4;
|
||||
}
|
||||
|
||||
const uint8_t bpp = attr_reg & 0x0003;
|
||||
|
||||
// HACKS
|
||||
// There must be a select bit for the tilemap palettes somewhere, but where?!
|
||||
|
||||
// the different games in paccon also expect a variety of different configs here, maybe a good place to look
|
||||
|
||||
if (m_703a_palettebank & 1) // this actually seems to be the sprite palette bank enable, but for tkmag220 it gives us an easy way to ignore the logic below
|
||||
{
|
||||
if (which == 0) // tilemap 0
|
||||
{
|
||||
if (ctrl_reg & 0x0002) // RegSet:1
|
||||
{
|
||||
// smartfp has a conflict between the bootlogos and the first screen, it's in regset mode, no obvious difference in registers but needs palette from different places?
|
||||
// not even m_707f changes here, which makes the m_707f case specific hacks for jak_s500 below very unlikely to actually be related
|
||||
if ((bpp + 1) * 2 == 4)
|
||||
if (m_alt_tile_addressing == 0)
|
||||
palette_offset |= 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
if (which == 1)
|
||||
{
|
||||
// can't do this for jak_s500 logos
|
||||
// jak_s500 also uses this tilemap in both 4 and 6bpp modes expecting the same palette base, so the hack used for smartfp on tilemap 0 is not applicable here
|
||||
|
||||
// m_707f != 0x2d3 for jak_S500 main menu
|
||||
if ((m_707f != 0x53) && (m_707f != 0x63) && (m_707f != 0x2d3))
|
||||
palette_offset |= 0x200;
|
||||
}
|
||||
|
||||
// jak_car2 screen transitions use layers 2 and 3 the same way, alternating each frame
|
||||
if (which == 2)
|
||||
{
|
||||
// jak_s500 title screen + loading screen before race
|
||||
if ((m_707f == 0x2d3) || (m_707f == 0x2db))
|
||||
palette_offset |= 0x200;
|
||||
}
|
||||
|
||||
}
|
||||
//palette_offset |= m_pal_back;
|
||||
|
||||
if (blend)
|
||||
{
|
||||
if (row_scroll)
|
||||
{
|
||||
if (flip_x)
|
||||
draw<BlendOn, RowScrollOn, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
else
|
||||
draw<BlendOn, RowScrollOn, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flip_x)
|
||||
draw<BlendOn, RowScrollOff, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
else
|
||||
draw<BlendOn, RowScrollOff, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (row_scroll)
|
||||
{
|
||||
if (flip_x)
|
||||
draw<BlendOff, RowScrollOn, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
else
|
||||
draw<BlendOff, RowScrollOn, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flip_x)
|
||||
draw<BlendOff, RowScrollOff, FlipXOn>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
else
|
||||
draw<BlendOff, RowScrollOff, FlipXOff>(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void gcm394_base_video_device::draw_sprite(const rectangle& cliprect, uint32_t scanline, int priority, uint32_t base_addr)
|
||||
{
|
||||
uint32_t bitmap_addr = (m_sprite_702d_gfxbase_msb << 16) | m_sprite_7022_gfxbase_lsb;
|
||||
uint32_t tile = m_spriteram[base_addr + 0];
|
||||
int16_t x = m_spriteram[base_addr + 1];
|
||||
int16_t y = m_spriteram[base_addr + 2];
|
||||
uint16_t attr = m_spriteram[base_addr + 3];
|
||||
|
||||
|
||||
if (!tile) // this check needs to come before the additional attribute bits are added in? (smartfp title)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int addressing_mode = 0;
|
||||
|
||||
int screenwidth, screenheight, x_max;
|
||||
if (m_707f & 0x0010)
|
||||
{
|
||||
screenwidth = 640;
|
||||
screenheight = 480;
|
||||
x_max = 0x400;
|
||||
}
|
||||
else
|
||||
{
|
||||
screenwidth = 320;
|
||||
screenheight = 240;
|
||||
x_max = 0x200;
|
||||
}
|
||||
|
||||
|
||||
// good for gormiti, smartfp, wrlshunt, paccon, jak_totm, jak_s500, jak_gtg
|
||||
if ((m_7042_sprite & 0x0010) == 0x10)
|
||||
addressing_mode = 0; // smartfp, paccon
|
||||
else
|
||||
addressing_mode = 1;
|
||||
|
||||
if (m_alt_extrasprite_hack == 0)
|
||||
if (addressing_mode == 0) // smartfp, paccon
|
||||
tile |= m_spriteextra[base_addr / 4] << 16;
|
||||
|
||||
if (m_alt_extrasprite_hack == 1) // jak_prft
|
||||
tile |= (m_spriteextra[base_addr] & 0x000f) << 16;
|
||||
|
||||
if (((attr & 0x3000) >> 12) != priority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// attr PBzz pppp hhww ffdd
|
||||
|
||||
// P = high palette bit
|
||||
// b = blend enable
|
||||
// zz = priority
|
||||
// pppp = palette
|
||||
// hh = height
|
||||
// ww = width
|
||||
// ff = flips
|
||||
// dd = depth
|
||||
|
||||
const uint32_t h = 8 << ((attr & 0x00c0) >> 6);
|
||||
const uint32_t w = 8 << ((attr & 0x0030) >> 4);
|
||||
|
||||
|
||||
if (!(m_7042_sprite & 0x0002))
|
||||
{
|
||||
x = ((screenwidth / 2) + x) - w / 2;
|
||||
y = ((screenheight / 2) - y) - (h / 2) + 8;
|
||||
}
|
||||
|
||||
x &= (x_max - 1);
|
||||
y &= 0x01ff;
|
||||
|
||||
uint32_t tile_line = ((scanline - y) + 0x200) % h;
|
||||
int16_t test_y = (y + tile_line) & 0x1ff;
|
||||
if (test_y >= 0x01c0)
|
||||
test_y -= 0x0200;
|
||||
|
||||
if (test_y != scanline)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool blend = (attr & 0x4000);
|
||||
|
||||
bool flip_x;
|
||||
uint8_t bpp;
|
||||
uint32_t yflipmask;
|
||||
uint32_t palette_offset;
|
||||
|
||||
// different attribute use?
|
||||
if (screenwidth == 320)
|
||||
{
|
||||
if (m_alt_extrasprite_hack == 0)
|
||||
{
|
||||
flip_x = (attr & 0x0004);
|
||||
yflipmask = attr & 0x0008 ? h - 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
flip_x = 0;
|
||||
yflipmask = 0;
|
||||
}
|
||||
|
||||
bpp = attr & 0x0003;
|
||||
palette_offset = (attr & 0x0f00) >> 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
flip_x = 0;// (attr & 0x0004);
|
||||
yflipmask = 0;// attr& 0x0008 ? h - 1 : 0;
|
||||
|
||||
bpp = attr & 0x0003;
|
||||
palette_offset = (attr & 0x0f00) >> 4;
|
||||
}
|
||||
|
||||
if (m_703a_palettebank & 1)
|
||||
palette_offset |= 0x100;
|
||||
|
||||
if (attr & 0x8000)
|
||||
palette_offset |= 0x200;
|
||||
|
||||
if (blend)
|
||||
{
|
||||
if (flip_x)
|
||||
draw<BlendOn, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode);
|
||||
else
|
||||
draw<BlendOn, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flip_x)
|
||||
draw<BlendOff, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode);
|
||||
else
|
||||
draw<BlendOff, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset, addressing_mode);
|
||||
}
|
||||
}
|
||||
|
||||
void gcm394_base_video_device::draw_sprites(const rectangle &cliprect, uint32_t scanline, int priority)
|
||||
{
|
||||
// paccon suggests this, does older hardware have similar?
|
||||
int numsprites = (m_7042_sprite & 0xff00) >> 8;
|
||||
if (numsprites == 0)
|
||||
numsprites = 0x100;
|
||||
|
||||
for (uint32_t n = 0; n < numsprites; n++)
|
||||
{
|
||||
draw_sprite(cliprect, scanline, priority, 4 * n);
|
||||
}
|
||||
m_renderer->set_video_spaces(m_cpuspace, m_cs_space, m_csbase);
|
||||
}
|
||||
|
||||
uint32_t gcm394_base_video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
@ -1021,48 +367,45 @@ uint32_t gcm394_base_video_device::screen_update(screen_device &screen, bitmap_r
|
||||
}
|
||||
|
||||
//const uint16_t bgcol = 0x7c1f; // magenta
|
||||
const uint16_t bgcol = 0x0000; // black
|
||||
|
||||
|
||||
// const uint16_t bgcol = 0x0000; // black
|
||||
bool highres;
|
||||
if (m_707f & 0x0010)
|
||||
{
|
||||
highres = true;
|
||||
m_screen->set_visible_area(0, 640-1, 0, 480-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
highres = false;
|
||||
m_screen->set_visible_area(0, 320-1, 0, 240-1);
|
||||
}
|
||||
|
||||
address_space &mem = m_cpu->space(AS_PROGRAM);
|
||||
|
||||
const uint32_t page0_addr = (m_page0_addr_msb << 16) | m_page0_addr_lsb;
|
||||
const uint32_t page1_addr = (m_page1_addr_msb << 16) | m_page1_addr_lsb;
|
||||
const uint32_t page2_addr = (m_page2_addr_msb << 16) | m_page2_addr_lsb;
|
||||
const uint32_t page3_addr = (m_page3_addr_msb << 16) | m_page3_addr_lsb;
|
||||
|
||||
const uint32_t sprites_addr = (m_sprite_702d_gfxbase_msb << 16) | m_sprite_7022_gfxbase_lsb;
|
||||
|
||||
bitmap.fill(0, cliprect);
|
||||
|
||||
for (uint32_t scanline = (uint32_t)cliprect.min_y; scanline <= (uint32_t)cliprect.max_y; scanline++)
|
||||
{
|
||||
uint32_t* bufferline = &m_screenbuf[scanline * m_screen->width()];
|
||||
|
||||
for (int x = 0; x < m_screen->width(); x++)
|
||||
{
|
||||
bufferline[x] = m_rgb555_to_rgb888[bgcol];
|
||||
}
|
||||
uint32_t* dst = &bitmap.pix32(scanline, cliprect.min_x);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
const int draw_all = 1;
|
||||
m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page0_addr, m_tmap0_scroll, m_tmap0_regs, mem, m_paletteram, m_rowscroll, 0);
|
||||
m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page1_addr, m_tmap1_scroll, m_tmap1_regs, mem, m_paletteram, m_rowscroll, 1);
|
||||
m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page2_addr, m_tmap2_scroll, m_tmap2_regs, mem, m_paletteram, m_rowscroll, 2);
|
||||
m_renderer->draw_page(true, true, m_alt_tile_addressing ? false : true, m_703a_palettebank, cliprect, dst, scanline, i, page3_addr, m_tmap3_scroll, m_tmap3_regs, mem, m_paletteram, m_rowscroll, 3);
|
||||
|
||||
if (1)
|
||||
{
|
||||
if ((!(machine().input().code_pressed(KEYCODE_Q))) || draw_all) draw_page(cliprect, scanline, i, (m_page0_addr_lsb | (m_page0_addr_msb<<16)), m_tmap0_regs, m_tmap0_scroll, 0);
|
||||
if ((!(machine().input().code_pressed(KEYCODE_W))) || draw_all) draw_page(cliprect, scanline, i, (m_page1_addr_lsb | (m_page1_addr_msb<<16)), m_tmap1_regs, m_tmap1_scroll, 1);
|
||||
if ((!(machine().input().code_pressed(KEYCODE_E))) || draw_all) draw_page(cliprect, scanline, i, (m_page2_addr_lsb | (m_page2_addr_msb<<16)), m_tmap2_regs, m_tmap2_scroll, 2);
|
||||
if ((!(machine().input().code_pressed(KEYCODE_R))) || draw_all) draw_page(cliprect, scanline, i, (m_page3_addr_lsb | (m_page3_addr_msb<<16)), m_tmap3_regs, m_tmap3_scroll, 3);
|
||||
|
||||
}
|
||||
if ((!(machine().input().code_pressed(KEYCODE_T))) || draw_all) draw_sprites(cliprect, scanline, i);
|
||||
m_renderer->draw_sprites(true, true, m_alt_extrasprite_hack ? true : false, m_703a_palettebank, highres, cliprect, dst, scanline, i, sprites_addr, mem, m_paletteram, m_spriteram, -1);
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
|
||||
{
|
||||
uint32_t *dest = &bitmap.pix32(y, cliprect.min_x);
|
||||
uint32_t *src = &m_screenbuf[cliprect.min_x + m_screen->width() * y];
|
||||
memcpy(dest, src, sizeof(uint32_t) * ((cliprect.max_x - cliprect.min_x) + 1));
|
||||
m_renderer->apply_saturation_and_fade(bitmap, cliprect, scanline);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1391,6 +734,8 @@ WRITE16_MEMBER(gcm394_base_video_device::sprite_7042_extra_w)
|
||||
{
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::sprite_7042_extra_w %04x\n", machine().describe_context(), data);
|
||||
m_7042_sprite = data;
|
||||
m_renderer->set_video_reg_42(data);
|
||||
|
||||
//popmessage("extra modes %04x\n", data);
|
||||
}
|
||||
|
||||
@ -1470,7 +815,7 @@ READ16_MEMBER(gcm394_base_video_device::video_707c_r)
|
||||
|
||||
READ16_MEMBER(gcm394_base_video_device::video_707f_r)
|
||||
{
|
||||
uint16_t retdata = m_707f;
|
||||
uint16_t retdata = m_renderer->get_video_reg_7f();
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_707f_r (returning %04x)\n", machine().describe_context(), retdata);
|
||||
return retdata;
|
||||
}
|
||||
@ -1496,7 +841,7 @@ WRITE16_MEMBER(gcm394_base_video_device::video_707f_w)
|
||||
}
|
||||
|
||||
m_707f = data;
|
||||
|
||||
m_renderer->set_video_reg_7f(data);
|
||||
//popmessage("707f is %04x\n", data);
|
||||
}
|
||||
|
||||
@ -1558,6 +903,7 @@ WRITE16_MEMBER(gcm394_base_video_device::video_702a_w)
|
||||
{
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_702a_w %04x\n", machine().describe_context(), data);
|
||||
m_702a = data;
|
||||
m_renderer->set_video_reg_2a(data);
|
||||
}
|
||||
|
||||
READ16_MEMBER(gcm394_base_video_device::video_curline_r)
|
||||
@ -1582,15 +928,17 @@ WRITE16_MEMBER(gcm394_base_video_device::video_7030_brightness_w)
|
||||
{
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_7030_brightness_w %04x\n", machine().describe_context(), data);
|
||||
m_7030_brightness = data;
|
||||
m_renderer->set_video_reg_30(data);
|
||||
}
|
||||
|
||||
void gcm394_base_video_device::update_raster_split_position()
|
||||
{
|
||||
// this might need updating to handle higher res modes
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "update_raster_split_position: %04x,%04x\n", m_yirqpos, m_xirqpos);
|
||||
if (m_xirqpos < 300 && m_yirqpos < 240)
|
||||
if (m_xirqpos < 300 && m_yirqpos < 256)
|
||||
{
|
||||
m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos, m_xirqpos));
|
||||
// where does -19 come from? needed for raster on paccon xevious to fire at correct line for bg scrolling to be seamless
|
||||
m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos-19, m_xirqpos));
|
||||
//printf("setting irq timer for y:%d x:%d", m_yirqpos, m_xirqpos);
|
||||
}
|
||||
else
|
||||
@ -1623,6 +971,7 @@ WRITE16_MEMBER(gcm394_base_video_device::video_703c_tvcontrol1_w)
|
||||
{
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_703c_tvcontrol1_w %04x\n", machine().describe_context(), data);
|
||||
m_703c_tvcontrol1 = data;
|
||||
m_renderer->set_video_reg_3c(data);
|
||||
}
|
||||
|
||||
READ16_MEMBER(gcm394_base_video_device::video_7051_r)
|
||||
@ -1668,7 +1017,7 @@ WRITE16_MEMBER(gcm394_base_video_device::spriteram_w)
|
||||
}
|
||||
else if (m_707e_spritebank == 0x0001)
|
||||
{
|
||||
m_spriteextra[offset] = data;
|
||||
m_spriteram[offset + 0x400] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1684,7 +1033,7 @@ READ16_MEMBER(gcm394_base_video_device::spriteram_r)
|
||||
}
|
||||
else if (m_707e_spritebank == 0x0001)
|
||||
{
|
||||
return m_spriteextra[offset];
|
||||
return m_spriteram[offset + 0x400];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1705,13 +1054,9 @@ WRITE16_MEMBER(gcm394_base_video_device::palette_w)
|
||||
{
|
||||
offset |= (m_703a_palettebank & 0x000c) << 6;
|
||||
m_paletteram[offset] = data;
|
||||
|
||||
uint32_t pal = m_rgb555_to_rgb888[data & 0x7fff];
|
||||
int r = (pal >> 16) & 0xff;
|
||||
int g = (pal >> 8) & 0xff;
|
||||
int b = (pal >> 0) & 0xff;
|
||||
|
||||
m_palette->set_pen_color(offset, rgb_t(r, g, b));
|
||||
|
||||
// for debug
|
||||
m_palette->set_pen_color(offset, rgb_t((((data >> 15) & 0x1f)<<3), (((data >> 10) & 0x1f)<<3), (((data >> 0) & 0x1f)<<3)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1731,16 +1076,19 @@ READ16_MEMBER(gcm394_base_video_device::palette_r)
|
||||
WRITE16_MEMBER(gcm394_base_video_device::video_701c_w)
|
||||
{
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_701c_w (unknown video reg?) %04x\n", machine().describe_context(), data);
|
||||
m_renderer->set_video_reg_1c(data);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(gcm394_base_video_device::video_701d_w)
|
||||
{
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_701d_w (unknown video reg?) %04x\n", machine().describe_context(), data);
|
||||
m_renderer->set_video_reg_1d(data);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(gcm394_base_video_device::video_701e_w)
|
||||
{
|
||||
LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_701e_w (unknown video reg?) %04x\n", machine().describe_context(), data);
|
||||
m_renderer->set_video_reg_1e(data);
|
||||
}
|
||||
|
||||
|
||||
@ -1787,7 +1135,7 @@ void gcm394_base_video_device::device_timer(emu_timer &timer, device_timer_id id
|
||||
m_screen->update_partial(m_screen->vpos());
|
||||
|
||||
// fire again, jak_dbz pinball needs this
|
||||
m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos, m_xirqpos));
|
||||
m_screenpos_timer->adjust(m_screen->time_until_pos(m_yirqpos-19, m_xirqpos));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
void set_alt_extrasprite(int alt_extrasprite_hack) { m_alt_extrasprite_hack = alt_extrasprite_hack; }
|
||||
|
||||
|
||||
void set_video_spaces(address_space& cpuspace, address_space& cs_space, int csbase) { m_cpuspace = &cpuspace; m_cs_space = &cs_space; m_csbase = csbase; }
|
||||
|
||||
//void set_pal_sprites(int pal_sprites) { m_pal_sprites = pal_sprites; }
|
||||
//void set_pal_back(int pal_back) { m_pal_back = pal_back; }
|
||||
|
||||
@ -147,37 +149,8 @@ protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
enum blend_enable_t : bool
|
||||
{
|
||||
BlendOff = false,
|
||||
BlendOn = true
|
||||
};
|
||||
|
||||
enum rowscroll_enable_t : bool
|
||||
{
|
||||
RowScrollOff = false,
|
||||
RowScrollOn = true
|
||||
};
|
||||
|
||||
enum flipx_t : bool
|
||||
{
|
||||
FlipXOff = false,
|
||||
FlipXOn = true
|
||||
};
|
||||
|
||||
template<blend_enable_t Blend, rowscroll_enable_t RowScroll, flipx_t FlipX>
|
||||
void draw(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t bitmap_addr, uint32_t tile, int32_t h, int32_t w, uint8_t bpp, uint32_t yflipmask, uint32_t palette_offset, int addressing_mode);
|
||||
void draw_page(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t *regs, uint16_t *scroll, int which);
|
||||
void draw_sprites(const rectangle& cliprect, uint32_t scanline, int priority);
|
||||
void draw_sprite(const rectangle& cliprect, uint32_t scanline, int priority, uint32_t base_addr);
|
||||
|
||||
uint32_t m_screenbuf[640 * 480];
|
||||
uint8_t m_rgb5_to_rgb8[32];
|
||||
uint32_t m_rgb555_to_rgb888[0x8000];
|
||||
|
||||
required_device<unsp_device> m_cpu;
|
||||
required_device<screen_device> m_screen;
|
||||
// required_shared_ptr<uint16_t> m_scrollram;
|
||||
|
||||
uint16_t m_page0_addr_lsb;
|
||||
uint16_t m_page0_addr_msb;
|
||||
@ -242,8 +215,7 @@ protected:
|
||||
|
||||
emu_timer *m_screenpos_timer;
|
||||
|
||||
uint16_t m_spriteram[0x400];
|
||||
uint16_t m_spriteextra[0x400];
|
||||
uint16_t m_spriteram[0x400*2];
|
||||
uint16_t m_paletteram[0x100*0x10];
|
||||
|
||||
required_device<palette_device> m_palette;
|
||||
@ -263,6 +235,10 @@ protected:
|
||||
int m_alt_tile_addressing;
|
||||
|
||||
required_device<spg_renderer_device> m_renderer;
|
||||
|
||||
address_space* m_cpuspace;
|
||||
address_space* m_cs_space;
|
||||
int m_csbase;
|
||||
};
|
||||
|
||||
class gcm394_video_device : public gcm394_base_video_device
|
||||
|
@ -103,6 +103,8 @@ uint32_t spg2xx_video_device::screen_update(screen_device &screen, bitmap_rgb32
|
||||
|
||||
const uint32_t page1_addr = 0x40 * m_video_regs[0x20];
|
||||
const uint32_t page2_addr = 0x40 * m_video_regs[0x21];
|
||||
const uint32_t sprite_addr = 0x40 * m_video_regs[0x22];
|
||||
|
||||
uint16_t *page1_scroll = m_video_regs + 0x10;
|
||||
uint16_t *page2_scroll = m_video_regs + 0x16;
|
||||
uint16_t *page1_regs = m_video_regs + 0x12;
|
||||
@ -116,9 +118,9 @@ uint32_t spg2xx_video_device::screen_update(screen_device &screen, bitmap_rgb32
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_renderer->draw_page(cliprect, dst, scanline, i, page1_addr, page1_scroll, page1_regs, mem, m_paletteram, m_scrollram);
|
||||
m_renderer->draw_page(cliprect, dst, scanline, i, page2_addr, page2_scroll, page2_regs, mem, m_paletteram, m_scrollram);
|
||||
m_renderer->draw_sprites(cliprect, dst, scanline, i, mem, m_paletteram, m_spriteram, m_sprlimit_read_cb());
|
||||
m_renderer->draw_page(false, false, false, 0, cliprect, dst, scanline, i, page1_addr, page1_scroll, page1_regs, mem, m_paletteram, m_scrollram, 0);
|
||||
m_renderer->draw_page(false, false, false, 0, cliprect, dst, scanline, i, page2_addr, page2_scroll, page2_regs, mem, m_paletteram, m_scrollram, 1);
|
||||
m_renderer->draw_sprites(false, false, false, 0, false, cliprect, dst, scanline, i, sprite_addr, mem, m_paletteram, m_spriteram, m_sprlimit_read_cb());
|
||||
}
|
||||
|
||||
m_renderer->apply_saturation_and_fade(bitmap, cliprect, scanline);
|
||||
@ -177,7 +179,7 @@ READ16_MEMBER(spg2xx_video_device::video_r)
|
||||
|
||||
case 0x22: // Sprite Segment Address
|
||||
LOGMASKED(LOG_PPU_READS, "video_r: Sprite Segment Address\n");
|
||||
return m_renderer->get_video_reg_22();
|
||||
return m_video_regs[offset];
|
||||
|
||||
case 0x2a: // Blend Level Control
|
||||
LOGMASKED(LOG_PPU_READS, "video_r: Blend Level Control\n");
|
||||
@ -334,7 +336,6 @@ WRITE16_MEMBER(spg2xx_video_device::video_w)
|
||||
case 0x22: // Sprite Segment Address
|
||||
LOGMASKED(LOG_PPU_WRITES, "video_w: Sprite Segment Address = %04x\n", data);
|
||||
m_video_regs[offset] = data;
|
||||
m_renderer->set_video_reg_22(data);
|
||||
break;
|
||||
|
||||
case 0x2a: // Blend Level Control
|
||||
|
@ -7,7 +7,8 @@
|
||||
DEFINE_DEVICE_TYPE(SPG_RENDERER, spg_renderer_device, "spg_renderer", "SunPlus / GeneralPlus video rendering")
|
||||
|
||||
spg_renderer_device::spg_renderer_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock)
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
m_space_read_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -18,6 +19,8 @@ spg_renderer_device::spg_renderer_device(const machine_config &mconfig, const ch
|
||||
|
||||
void spg_renderer_device::device_start()
|
||||
{
|
||||
m_space_read_cb.resolve_safe(0);
|
||||
|
||||
for (uint8_t i = 0; i < 32; i++)
|
||||
{
|
||||
m_rgb5_to_rgb8[i] = (i << 3) | (i >> 2);
|
||||
@ -33,7 +36,6 @@ void spg_renderer_device::device_start()
|
||||
save_item(NAME(m_video_regs_1d));
|
||||
save_item(NAME(m_video_regs_1e));
|
||||
|
||||
save_item(NAME(m_video_regs_22));
|
||||
save_item(NAME(m_video_regs_2a));
|
||||
|
||||
save_item(NAME(m_video_regs_30));
|
||||
@ -41,6 +43,8 @@ void spg_renderer_device::device_start()
|
||||
|
||||
save_item(NAME(m_video_regs_42));
|
||||
|
||||
save_item(NAME(m_video_regs_7f));
|
||||
|
||||
save_item(NAME(m_ycmp_table));
|
||||
}
|
||||
|
||||
@ -50,7 +54,6 @@ void spg_renderer_device::device_reset()
|
||||
m_video_regs_1d = 0x0000;
|
||||
m_video_regs_1e = 0x0000;
|
||||
|
||||
m_video_regs_22 = 0x0000;
|
||||
m_video_regs_2a = 0x0000;
|
||||
|
||||
m_video_regs_30 = 0x0000;
|
||||
@ -58,6 +61,8 @@ void spg_renderer_device::device_reset()
|
||||
|
||||
m_video_regs_42 = 0x0001;
|
||||
|
||||
m_video_regs_7f = 0x0000;
|
||||
|
||||
for (int i = 0; i < 480; i++)
|
||||
{
|
||||
m_ycmp_table[i] = 0xffffffff;
|
||||
@ -66,14 +71,13 @@ void spg_renderer_device::device_reset()
|
||||
|
||||
|
||||
// Perform a lerp between a and b
|
||||
inline uint8_t spg_renderer_device::mix_channel(uint8_t bottom, uint8_t top)
|
||||
inline uint8_t spg_renderer_device::mix_channel(uint8_t bottom, uint8_t top, uint8_t alpha)
|
||||
{
|
||||
uint8_t alpha = (m_video_regs_2a & 3) << 6;
|
||||
return ((256 - alpha) * bottom + alpha * top) >> 8;
|
||||
}
|
||||
|
||||
template<spg_renderer_device::blend_enable_t Blend, spg_renderer_device::flipx_t FlipX>
|
||||
void spg_renderer_device::draw_tilestrip(const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint16_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space &spc, uint16_t* paletteram)
|
||||
void spg_renderer_device::draw_tilestrip(bool read_from_csspace, uint32_t screenwidth, uint32_t drawwidthmask, const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint32_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space &spc, uint16_t* paletteram, uint8_t blendlevel)
|
||||
{
|
||||
const uint32_t yflipmask = flip_y ? tile_h - 1 : 0;
|
||||
uint32_t m = tilegfxdata_addr + words_per_tile * tile + bits_per_row * (tile_scanline ^ yflipmask);
|
||||
@ -82,23 +86,44 @@ void spg_renderer_device::draw_tilestrip(const rectangle& cliprect, uint32_t* ds
|
||||
|
||||
for (int32_t x = FlipX ? (tile_w - 1) : 0; FlipX ? x >= 0 : x < tile_w; FlipX ? x-- : x++)
|
||||
{
|
||||
int realdrawpos = (drawx + x) & 0x1ff;
|
||||
int realdrawpos = (drawx + x) & drawwidthmask;
|
||||
|
||||
bits <<= nc_bpp;
|
||||
|
||||
if (nbits < nc_bpp)
|
||||
{
|
||||
uint16_t b = spc.read_word(m++ & 0x3fffff);
|
||||
b = (b << 8) | (b >> 8);
|
||||
bits |= b << (nc_bpp - nbits);
|
||||
nbits += 16;
|
||||
if (!read_from_csspace)
|
||||
{
|
||||
uint16_t b = spc.read_word(m++ & 0x3fffff);
|
||||
b = (b << 8) | (b >> 8);
|
||||
bits |= b << (nc_bpp - nbits);
|
||||
nbits += 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t b;
|
||||
const int addr = m & 0x7ffffff;
|
||||
if (addr < m_csbase)
|
||||
{
|
||||
b = m_cpuspace->read_word(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
b = m_cs_space->read_word(addr-m_csbase);
|
||||
}
|
||||
m++;
|
||||
b = (b << 8) | (b >> 8);
|
||||
bits |= b << (nc_bpp - nbits);
|
||||
nbits += 16;
|
||||
}
|
||||
}
|
||||
nbits -= nc_bpp;
|
||||
|
||||
uint32_t pal = palette_offset + (bits >> 16);
|
||||
bits &= 0xffff;
|
||||
|
||||
if (realdrawpos >= 0 && realdrawpos < 320)
|
||||
|
||||
if (realdrawpos >= 0 && realdrawpos < screenwidth)
|
||||
{
|
||||
uint16_t rgb = paletteram[pal];
|
||||
|
||||
@ -106,9 +131,10 @@ void spg_renderer_device::draw_tilestrip(const rectangle& cliprect, uint32_t* ds
|
||||
{
|
||||
if (Blend)
|
||||
{
|
||||
dst[realdrawpos] = (mix_channel((uint8_t)(dst[realdrawpos] >> 16), m_rgb5_to_rgb8[(rgb >> 10) & 0x1f]) << 16) |
|
||||
(mix_channel((uint8_t)(dst[realdrawpos] >> 8), m_rgb5_to_rgb8[(rgb >> 5) & 0x1f]) << 8) |
|
||||
(mix_channel((uint8_t)(dst[realdrawpos] >> 0), m_rgb5_to_rgb8[rgb & 0x1f]));
|
||||
|
||||
dst[realdrawpos] = (mix_channel((uint8_t)(dst[realdrawpos] >> 16), m_rgb5_to_rgb8[(rgb >> 10) & 0x1f], blendlevel) << 16) |
|
||||
(mix_channel((uint8_t)(dst[realdrawpos] >> 8), m_rgb5_to_rgb8[(rgb >> 5) & 0x1f], blendlevel) << 8) |
|
||||
(mix_channel((uint8_t)(dst[realdrawpos] >> 0), m_rgb5_to_rgb8[(rgb >> 0) & 0x1f], blendlevel) << 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -120,122 +146,166 @@ void spg_renderer_device::draw_tilestrip(const rectangle& cliprect, uint32_t* ds
|
||||
}
|
||||
|
||||
|
||||
void spg_renderer_device::draw_linemap(const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space &spc, uint16_t* paletteram)
|
||||
void spg_renderer_device::draw_linemap(bool has_extended_tilemaps, const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space &spc, uint16_t* paletteram)
|
||||
{
|
||||
if ((scanline < 0) || (scanline >= 240))
|
||||
return;
|
||||
|
||||
|
||||
uint32_t tilemap = tilemapregs[2];
|
||||
uint32_t palette_map = tilemapregs[3];
|
||||
|
||||
//printf("draw bitmap bases %04x %04x\n", tilemap, palette_map);
|
||||
|
||||
//uint32_t xscroll = scrollregs[0];
|
||||
uint32_t yscroll = scrollregs[1];
|
||||
|
||||
int realline = (scanline + yscroll) & 0xff;
|
||||
|
||||
|
||||
uint16_t tile = spc.read_word(tilemap + realline);
|
||||
uint16_t palette = 0;
|
||||
|
||||
//if (!tile)
|
||||
// continue;
|
||||
|
||||
palette = spc.read_word(palette_map + realline / 2);
|
||||
if (scanline & 1)
|
||||
palette >>= 8;
|
||||
else
|
||||
palette &= 0x00ff;
|
||||
|
||||
//const int linewidth = 320 / 2;
|
||||
int sourcebase = tile | (palette << 16);
|
||||
|
||||
uint32_t ctrl = tilemapregs[1];
|
||||
|
||||
if (ctrl & 0x80) // HiColor mode (rad_digi)
|
||||
if (has_extended_tilemaps)
|
||||
{
|
||||
for (int i = 0; i < 320; i++)
|
||||
uint32_t ctrl = tilemapregs[1];
|
||||
|
||||
if (0)
|
||||
{
|
||||
const uint16_t data = spc.read_word(sourcebase + i);
|
||||
if (ctrl & 0x0010)
|
||||
popmessage("bitmap mode %08x with rowscroll\n", tilegfxdata_addr);
|
||||
else
|
||||
popmessage("bitmap mode %08x\n", tilegfxdata_addr);
|
||||
}
|
||||
|
||||
if (!(data & 0x8000))
|
||||
// note, in interlace modes it appears every other line is unused? (480 entry table, but with blank values)
|
||||
// and furthermore the rowscroll and rowzoom tables only have 240 entries, not enough for every line
|
||||
// the end of the rowscroll table (entries 240-255) contain something else, maybe garbage data as it's offscreen, maybe not
|
||||
uint32_t tilemap = tilemapregs[2];
|
||||
uint32_t palette_map = tilemapregs[3];
|
||||
|
||||
uint32_t linebase = spc.read_word(tilemap + scanline); // every other word is unused, but there are only enough entries for 240 lines then, sometimes to do with interlace mode?
|
||||
uint16_t palette = spc.read_word(palette_map + (scanline / 2));
|
||||
|
||||
if (scanline & 1)
|
||||
palette >>= 8;
|
||||
else
|
||||
palette &= 0xff;
|
||||
|
||||
if (!linebase)
|
||||
return;
|
||||
|
||||
linebase = linebase | (palette << 16);
|
||||
|
||||
// this logic works for jak_s500 and the test modes to get the correct base, doesn't seem to work for jak_car2 ingame, maybe data is copied to wrong place?
|
||||
int gfxbase = (tilegfxdata_addr&0x7ffffff) + (linebase&0x7ffffff);
|
||||
|
||||
for (int i = 0; i < 160; i++) // will have to be 320 for jak_car2 ingame, jak_s500 lines are wider than screen, and zoomed
|
||||
{
|
||||
uint16_t pix;
|
||||
const int addr = gfxbase & 0x7ffffff;
|
||||
if (addr < m_csbase)
|
||||
{
|
||||
dst[i] = m_rgb555_to_rgb888[data & 0x7fff];
|
||||
pix = m_cpuspace->read_word(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
pix = m_cs_space->read_word(addr-m_csbase);
|
||||
}
|
||||
gfxbase++;
|
||||
|
||||
int xx;
|
||||
uint16_t pal;
|
||||
|
||||
if ((scanline >= 0) && (scanline < 480))
|
||||
{
|
||||
xx = i * 2;
|
||||
|
||||
pal = (pix & 0xff) | 0x100;
|
||||
|
||||
if (xx >= 0 && xx <= cliprect.max_x)
|
||||
{
|
||||
uint16_t rgb = paletteram[pal];
|
||||
|
||||
if (!(rgb & 0x8000))
|
||||
{
|
||||
dst[xx] = m_rgb555_to_rgb888[rgb];
|
||||
}
|
||||
}
|
||||
|
||||
xx = (i * 2)+1;
|
||||
pal = (pix >> 8) + 0x100;
|
||||
|
||||
if (xx >= 0 && xx <= cliprect.max_x)
|
||||
{
|
||||
uint16_t rgb = paletteram[pal];
|
||||
|
||||
if (!(rgb & 0x8000))
|
||||
{
|
||||
dst[xx] = m_rgb555_to_rgb888[rgb];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else // code used for spg2xx cases
|
||||
{
|
||||
for (int i = 0; i < 320 / 2; i++)
|
||||
{
|
||||
uint8_t palette_entry;
|
||||
uint16_t color;
|
||||
const uint16_t data = spc.read_word(sourcebase + i);
|
||||
if ((scanline < 0) || (scanline >= 240))
|
||||
return;
|
||||
|
||||
palette_entry = (data & 0x00ff);
|
||||
color = paletteram[palette_entry];
|
||||
uint32_t tilemap = tilemapregs[2];
|
||||
uint32_t palette_map = tilemapregs[3];
|
||||
|
||||
if (!(color & 0x8000))
|
||||
{
|
||||
dst[(i * 2) + 0] = m_rgb555_to_rgb888[color & 0x7fff];
|
||||
}
|
||||
popmessage("draw draw_linemap bases %04x %04x\n", tilemap, palette_map);
|
||||
|
||||
palette_entry = (data & 0xff00) >> 8;
|
||||
color = paletteram[palette_entry];
|
||||
//uint32_t xscroll = scrollregs[0];
|
||||
uint32_t yscroll = scrollregs[1];
|
||||
|
||||
if (!(color & 0x8000))
|
||||
{
|
||||
dst[(i * 2) + 1] = m_rgb555_to_rgb888[color & 0x7fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int realline = (scanline + yscroll) & 0xff;
|
||||
|
||||
|
||||
bool spg_renderer_device::get_tile_info(uint32_t tilemap_rambase, uint32_t palettemap_rambase, uint32_t x0, uint32_t y0, uint32_t tile_count_x, uint32_t ctrl, uint32_t attr, uint16_t& tile, spg_renderer_device::blend_enable_t& blend, spg_renderer_device::flipx_t& flip_x, bool& flip_y, uint32_t& palette_offset, address_space &spc)
|
||||
{
|
||||
uint32_t tile_address = x0 + (tile_count_x * y0);
|
||||
uint32_t tile = spc.read_word(tilemap + realline);
|
||||
uint16_t palette = 0;
|
||||
|
||||
tile = (ctrl & 0x0004) ? spc.read_word(tilemap_rambase) : spc.read_word(tilemap_rambase + tile_address);
|
||||
//if (!tile)
|
||||
// continue;
|
||||
|
||||
if (!tile)
|
||||
return false;
|
||||
|
||||
uint32_t tileattr = attr;
|
||||
uint32_t tilectrl = ctrl;
|
||||
if ((ctrl & 2) == 0)
|
||||
{ // -(1) bld(1) flip(2) pal(4)
|
||||
|
||||
uint16_t palette = (ctrl & 0x0004) ? spc.read_word(palettemap_rambase) : spc.read_word(palettemap_rambase + tile_address / 2);
|
||||
if (x0 & 1)
|
||||
palette = spc.read_word(palette_map + realline / 2);
|
||||
if (scanline & 1)
|
||||
palette >>= 8;
|
||||
else
|
||||
palette &= 0x00ff;
|
||||
|
||||
//const int linewidth = 320 / 2;
|
||||
int sourcebase = tile | (palette << 16);
|
||||
|
||||
tileattr &= ~0x000c;
|
||||
tileattr |= (palette >> 2) & 0x000c; // flip
|
||||
uint32_t ctrl = tilemapregs[1];
|
||||
|
||||
tileattr &= ~0x0f00;
|
||||
tileattr |= (palette << 8) & 0x0f00; // palette
|
||||
if (ctrl & 0x80) // HiColor mode (rad_digi)
|
||||
{
|
||||
for (int i = 0; i < 320; i++)
|
||||
{
|
||||
const uint16_t data = spc.read_word(sourcebase + i);
|
||||
|
||||
tilectrl &= ~0x0100;
|
||||
tilectrl |= (palette << 2) & 0x0100; // blend
|
||||
if (!(data & 0x8000))
|
||||
{
|
||||
dst[i] = m_rgb555_to_rgb888[data & 0x7fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 320 / 2; i++)
|
||||
{
|
||||
uint8_t palette_entry;
|
||||
uint16_t color;
|
||||
const uint16_t data = spc.read_word(sourcebase + i);
|
||||
|
||||
palette_entry = (data & 0x00ff);
|
||||
color = paletteram[palette_entry];
|
||||
|
||||
if (!(color & 0x8000))
|
||||
{
|
||||
dst[(i * 2) + 0] = m_rgb555_to_rgb888[color & 0x7fff];
|
||||
}
|
||||
|
||||
palette_entry = (data & 0xff00) >> 8;
|
||||
color = paletteram[palette_entry];
|
||||
|
||||
if (!(color & 0x8000))
|
||||
{
|
||||
dst[(i * 2) + 1] = m_rgb555_to_rgb888[color & 0x7fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blend = ((tileattr & 0x4000 || tilectrl & 0x0100)) ? BlendOn : BlendOff;
|
||||
flip_x = (tileattr & 0x0004) ? FlipXOn : FlipXOff;
|
||||
flip_y= (tileattr & 0x0008);
|
||||
|
||||
palette_offset = (tileattr & 0x0f00) >> 4;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// this builds up a line table for the vcmp effect, this is not correct when step is used
|
||||
void spg_renderer_device::update_vcmp_table()
|
||||
{
|
||||
@ -257,7 +327,7 @@ void spg_renderer_device::update_vcmp_table()
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((currentline >= 0) && (currentline < 240))
|
||||
if ((currentline >= 0) && (currentline < 256))
|
||||
{
|
||||
m_ycmp_table[i] = currentline;
|
||||
}
|
||||
@ -275,33 +345,33 @@ void spg_renderer_device::update_vcmp_table()
|
||||
}
|
||||
}
|
||||
|
||||
void spg_renderer_device::draw_tilestrip(spg_renderer_device::blend_enable_t blend, spg_renderer_device::flipx_t flip_x, const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint16_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space& spc, uint16_t* paletteram)
|
||||
void spg_renderer_device::draw_tilestrip(bool read_from_csspace, uint32_t screenwidth, uint32_t drawwidthmask, spg_renderer_device::blend_enable_t blend, spg_renderer_device::flipx_t flip_x, const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint32_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space& spc, uint16_t* paletteram, uint8_t blendlevel)
|
||||
{
|
||||
if (blend)
|
||||
{
|
||||
if (flip_x)
|
||||
{
|
||||
draw_tilestrip<BlendOn, FlipXOn>(cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
draw_tilestrip<BlendOn, FlipXOn>(read_from_csspace, screenwidth, drawwidthmask, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_tilestrip<BlendOn, FlipXOff>(cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
draw_tilestrip<BlendOn, FlipXOff>(read_from_csspace, screenwidth, drawwidthmask, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flip_x)
|
||||
{
|
||||
draw_tilestrip<BlendOff, FlipXOn>(cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
draw_tilestrip<BlendOff, FlipXOn>(read_from_csspace, screenwidth, drawwidthmask, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_tilestrip<BlendOff, FlipXOff>(cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
draw_tilestrip<BlendOff, FlipXOff>(read_from_csspace, screenwidth, drawwidthmask, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void spg_renderer_device::draw_page(const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space& spc, uint16_t* paletteram, uint16_t* scrollram)
|
||||
void spg_renderer_device::draw_page(bool read_from_csspace, bool has_extended_tilemaps, bool use_alt_tile_addressing, uint32_t palbank, const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space& spc, uint16_t* paletteram, uint16_t* scrollram, uint32_t which)
|
||||
{
|
||||
const uint32_t attr = tilemapregs[0];
|
||||
const uint32_t ctrl = tilemapregs[1];
|
||||
@ -318,7 +388,7 @@ void spg_renderer_device::draw_page(const rectangle& cliprect, uint32_t* dst, ui
|
||||
|
||||
if (ctrl & 0x0001) // Bitmap / Linemap mode! (basically screen width tile mode)
|
||||
{
|
||||
draw_linemap(cliprect, dst, scanline, priority, tilegfxdata_addr, scrollregs, tilemapregs, spc, paletteram);
|
||||
draw_linemap(has_extended_tilemaps, cliprect, dst, scanline, priority, tilegfxdata_addr, scrollregs, tilemapregs, spc, paletteram);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -328,61 +398,186 @@ void spg_renderer_device::draw_page(const rectangle& cliprect, uint32_t* dst, ui
|
||||
{
|
||||
if (m_video_regs_1e != 0x0000)
|
||||
popmessage("vertical compression mode with non-0 step amount %04x offset %04x step %04x\n", m_video_regs_1c, m_video_regs_1d, m_video_regs_1e);
|
||||
|
||||
|
||||
logical_scanline = m_ycmp_table[scanline];
|
||||
if (logical_scanline == 0xffffffff)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t total_width;
|
||||
uint32_t y_mask;
|
||||
uint32_t screenwidth;
|
||||
uint32_t drawwidthmask;
|
||||
|
||||
if (read_from_csspace && ((attr >> 15) & 0x1))
|
||||
{
|
||||
// just a guess based on this being set on the higher resolution tilemaps we've seen, could be 100% incorrect register
|
||||
total_width = 1024;
|
||||
y_mask = 0x1ff;
|
||||
screenwidth = 640;
|
||||
drawwidthmask = 0x400 - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
total_width = 512;
|
||||
y_mask = 0xff;
|
||||
screenwidth = 320;
|
||||
drawwidthmask = 0x200 - 1;
|
||||
}
|
||||
|
||||
|
||||
const uint32_t xscroll = scrollregs[0];
|
||||
const uint32_t yscroll = scrollregs[1];
|
||||
const uint32_t tilemap_rambase = tilemapregs[2];
|
||||
const uint32_t palettemap_rambase = tilemapregs[3];
|
||||
const uint32_t exattributemap_rambase = tilemapregs[3];
|
||||
const int tile_width = (attr & 0x0030) >> 4;
|
||||
const uint32_t tile_h = 8 << ((attr & 0x00c0) >> 6);
|
||||
const uint32_t tile_w = 8 << (tile_width);
|
||||
const uint32_t tile_count_x = 512 / tile_w; // all tilemaps are 512 pixels wide
|
||||
const uint32_t bitmap_y = (logical_scanline + yscroll) & 0xff; // all tilemaps are 256 pixels high
|
||||
const uint32_t tile_count_x = total_width / tile_w; // tilemaps are 512 or 1024 wide depending on screen mode?
|
||||
const uint32_t bitmap_y = (logical_scanline + yscroll) & y_mask; // tilemaps are 256 or 512 high depending on screen mode?
|
||||
const uint32_t y0 = bitmap_y / tile_h;
|
||||
const uint32_t tile_scanline = bitmap_y % tile_h;
|
||||
const uint8_t bpp = attr & 0x0003;
|
||||
const uint32_t nc_bpp = ((bpp)+1) << 1;
|
||||
const uint32_t bits_per_row = nc_bpp * tile_w / 16;
|
||||
const uint32_t words_per_tile = bits_per_row * tile_h;
|
||||
//const uint32_t words_per_tile = bits_per_row * tile_h;
|
||||
const bool row_scroll = (ctrl & 0x0010);
|
||||
uint8_t blendlevel = (m_video_regs_2a & 3) << 6;
|
||||
|
||||
uint32_t words_per_tile;
|
||||
|
||||
// good for gormiti, smartfp, wrlshunt, paccon, jak_totm, jak_s500, jak_gtg
|
||||
if (has_extended_tilemaps && use_alt_tile_addressing)
|
||||
{
|
||||
words_per_tile = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
words_per_tile = bits_per_row * tile_h;
|
||||
}
|
||||
|
||||
int realxscroll = xscroll;
|
||||
if (row_scroll)
|
||||
{
|
||||
// Tennis in My Wireless Sports confirms the need to add the scroll value here rather than rowscroll being screen-aligned
|
||||
realxscroll += (int16_t)scrollram[(logical_scanline+yscroll) & 0xff];
|
||||
realxscroll += (int16_t)scrollram[(logical_scanline + yscroll) & 0xff];
|
||||
}
|
||||
|
||||
const int upperscrollbits = (realxscroll >> (tile_width + 3));
|
||||
const int endpos = (320 + tile_w) / tile_w;
|
||||
const int endpos = (screenwidth + tile_w) / tile_w;
|
||||
for (uint32_t x0 = 0; x0 < endpos; x0++)
|
||||
{
|
||||
spg_renderer_device::blend_enable_t blend;
|
||||
spg_renderer_device::flipx_t flip_x;
|
||||
bool flip_y;
|
||||
uint16_t tile;
|
||||
uint32_t tile;
|
||||
uint32_t palette_offset;
|
||||
|
||||
if (!get_tile_info(tilemap_rambase, palettemap_rambase, (x0 + upperscrollbits) & (tile_count_x-1) , y0, tile_count_x, ctrl, attr, tile, blend, flip_x, flip_y, palette_offset, spc))
|
||||
// get tile info
|
||||
const int realx0 = (x0 + upperscrollbits) & (tile_count_x - 1);
|
||||
uint32_t tile_address = realx0 + (tile_count_x * y0);
|
||||
|
||||
tile = (ctrl & 0x0004) ? spc.read_word(tilemap_rambase) : spc.read_word(tilemap_rambase + tile_address);
|
||||
|
||||
if (!tile)
|
||||
continue;
|
||||
|
||||
uint32_t tileattr = attr;
|
||||
uint32_t tilectrl = ctrl;
|
||||
|
||||
if (has_extended_tilemaps && use_alt_tile_addressing)
|
||||
{
|
||||
// in this mode what would be the 'palette' bits get used for extra tile bits (even if the usual 'extended table' mode is disabled?)
|
||||
// used by smartfp
|
||||
uint16_t exattribute = (ctrl & 0x0004) ? spc.read_word(exattributemap_rambase) : spc.read_word(exattributemap_rambase + tile_address / 2);
|
||||
if (realx0 & 1)
|
||||
exattribute >>= 8;
|
||||
else
|
||||
exattribute &= 0x00ff;
|
||||
|
||||
tile |= (exattribute & 0x07) << 16;
|
||||
//blendlevel = 0x1f; // hack
|
||||
}
|
||||
else if ((ctrl & 2) == 0)
|
||||
{ // -(1) bld(1) flip(2) pal(4)
|
||||
|
||||
uint16_t exattribute = (ctrl & 0x0004) ? spc.read_word(exattributemap_rambase) : spc.read_word(exattributemap_rambase + tile_address / 2);
|
||||
if (realx0 & 1)
|
||||
exattribute >>= 8;
|
||||
else
|
||||
exattribute &= 0x00ff;
|
||||
|
||||
|
||||
tileattr &= ~0x000c;
|
||||
tileattr |= (exattribute >> 2) & 0x000c; // flip
|
||||
|
||||
tileattr &= ~0x0f00;
|
||||
tileattr |= (exattribute << 8) & 0x0f00; // palette
|
||||
|
||||
tilectrl &= ~0x0100;
|
||||
tilectrl |= (exattribute << 2) & 0x0100; // blend
|
||||
}
|
||||
|
||||
blend = ((tileattr & 0x4000 || tilectrl & 0x0100)) ? BlendOn : BlendOff;
|
||||
flip_x = (tileattr & 0x0004) ? FlipXOn : FlipXOff;
|
||||
flip_y = (tileattr & 0x0008);
|
||||
|
||||
palette_offset = (tileattr & 0x0f00) >> 4;
|
||||
// got tile info
|
||||
|
||||
if (1)
|
||||
{
|
||||
// HACKS
|
||||
// There must be a select bit for the tilemap palettes somewhere, but where?!
|
||||
// the different games in paccon also expect a variety of different configs here, maybe a good place to look
|
||||
if (palbank & 1) // this actually seems to be the sprite palette bank enable, but for myac220 / tkmag220 (where everything is from a single palette) it gives us an easy way to ignore the logic below
|
||||
{
|
||||
if (which == 0) // tilemap 0
|
||||
{
|
||||
if (ctrl & 0x0002) // RegSet:1
|
||||
{
|
||||
// smartfp has a conflict between the bootlogos and the first screen, it's in regset mode, no obvious difference in registers but needs palette from different places?
|
||||
// not even m_video_regs_7f changes here, which makes the m_video_regs_7f case specific hacks for jak_s500 below very unlikely to actually be related
|
||||
if ((bpp + 1) * 2 == 4)
|
||||
if (use_alt_tile_addressing == true)
|
||||
palette_offset |= 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
if (which == 1)
|
||||
{
|
||||
// can't do this for jak_s500 logos
|
||||
// jak_s500 also uses this tilemap in both 4 and 6bpp modes expecting the same palette base, so the hack used for smartfp on tilemap 0 is not applicable here
|
||||
|
||||
// m_video_regs_7f != 0x2d3 for jak_S500 main menu
|
||||
if ((m_video_regs_7f != 0x53) && (m_video_regs_7f != 0x63) && (m_video_regs_7f != 0x2d3))
|
||||
palette_offset |= 0x200;
|
||||
}
|
||||
|
||||
// jak_car2 screen transitions use layers 2 and 3 the same way, alternating each frame
|
||||
if (which == 2)
|
||||
{
|
||||
// jak_s500 title screen + loading screen before race
|
||||
if ((m_video_regs_7f == 0x2d3) || (m_video_regs_7f == 0x2db))
|
||||
palette_offset |= 0x200;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
palette_offset >>= nc_bpp;
|
||||
palette_offset <<= nc_bpp;
|
||||
|
||||
const int drawx = (x0 * tile_w) - (realxscroll & (tile_w-1));
|
||||
draw_tilestrip(blend,flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
const int drawx = (x0 * tile_w) - (realxscroll & (tile_w - 1));
|
||||
draw_tilestrip(read_from_csspace, screenwidth, drawwidthmask, blend, flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, tile_scanline, drawx, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
}
|
||||
|
||||
void spg_renderer_device::draw_sprite(const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t base_addr, address_space &spc, uint16_t* paletteram, uint16_t* spriteram)
|
||||
void spg_renderer_device::draw_sprite(bool read_from_csspace, bool has_extended_sprites, bool alt_extrasprite_hack, uint32_t palbank, bool highres, const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t spritegfxdata_addr, uint32_t base_addr, address_space &spc, uint16_t* paletteram, uint16_t* spriteram)
|
||||
{
|
||||
uint32_t tilegfxdata_addr = 0x40 * m_video_regs_22;
|
||||
uint16_t tile = spriteram[base_addr + 0];
|
||||
uint32_t tilegfxdata_addr = spritegfxdata_addr;
|
||||
uint32_t tile = spriteram[base_addr + 0];
|
||||
int16_t x = spriteram[base_addr + 1];
|
||||
int16_t y = spriteram[base_addr + 2];
|
||||
uint16_t attr = spriteram[base_addr + 3];
|
||||
@ -397,44 +592,108 @@ void spg_renderer_device::draw_sprite(const rectangle& cliprect, uint32_t* dst,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uint32_t screenwidth = 320;
|
||||
// uint32_t screenheight = 240;
|
||||
uint32_t screenheight = 256;
|
||||
uint32_t xmask = 0x1ff;
|
||||
uint32_t ymask = 0x1ff;
|
||||
|
||||
if (highres)
|
||||
{
|
||||
screenwidth = 640;
|
||||
// screenheight = 480;
|
||||
screenheight = 512;
|
||||
xmask = 0x3ff;
|
||||
}
|
||||
|
||||
const uint32_t tile_h = 8 << ((attr & 0x00c0) >> 6);
|
||||
const uint32_t tile_w = 8 << ((attr & 0x0030) >> 4);
|
||||
|
||||
if (!(m_video_regs_42 & 0x0002))
|
||||
{
|
||||
x = (160 + x) - tile_w / 2;
|
||||
y = (120 - y) - (tile_h / 2) + 8;
|
||||
x = ((screenwidth/2) + x) - tile_w / 2;
|
||||
// y = ((screenheight/2) - y) - (tile_h / 2) + 8;
|
||||
y = ((screenheight/2) - y) - (tile_h / 2);
|
||||
}
|
||||
|
||||
x &= 0x01ff;
|
||||
y &= 0x01ff;
|
||||
x &= xmask;
|
||||
y &= ymask;
|
||||
|
||||
int firstline = y;
|
||||
int lastline = y + (tile_h - 1);
|
||||
lastline &= 0x1ff;
|
||||
lastline &= ymask;
|
||||
|
||||
const spg_renderer_device::blend_enable_t blend = (attr & 0x4000) ? BlendOn : BlendOff;
|
||||
const spg_renderer_device::flipx_t flip_x = (attr & 0x0004) ? FlipXOn : FlipXOff;
|
||||
spg_renderer_device::flipx_t flip_x = (attr & 0x0004) ? FlipXOn : FlipXOff;
|
||||
const uint8_t bpp = attr & 0x0003;
|
||||
const uint32_t nc_bpp = ((bpp)+1) << 1;
|
||||
const uint32_t bits_per_row = nc_bpp * tile_w / 16;
|
||||
const uint32_t words_per_tile = bits_per_row * tile_h;
|
||||
uint8_t blendlevel = (m_video_regs_2a & 3) << 6;
|
||||
|
||||
uint32_t words_per_tile;
|
||||
|
||||
// good for gormiti, smartfp, wrlshunt, paccon, jak_totm, jak_s500, jak_gtg
|
||||
if (has_extended_sprites && ((m_video_regs_42 & 0x0010) == 0x10))
|
||||
{
|
||||
// paccon and smartfp use this mode
|
||||
words_per_tile = 8;
|
||||
|
||||
if (!alt_extrasprite_hack) // 1 extra word for each sprite
|
||||
{
|
||||
// before or after the 0 tile check?
|
||||
tile |= (spriteram[(base_addr / 4) + 0x400] & 0x01ff) << 16;
|
||||
blendlevel = ((spriteram[(base_addr / 4) + 0x400] & 0x3e00) >> 9) << 3;
|
||||
}
|
||||
else // jak_prft - no /4 to offset in this mode - 4 extra words per sprite instead ? (or is RAM content incorrect for one of these cases?)
|
||||
{
|
||||
tile |= spriteram[(base_addr) + 0x400] << 16;
|
||||
blendlevel = ((spriteram[(base_addr) + 0x400] & 0x3e00) >> 9) << 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
words_per_tile = bits_per_row * tile_h;
|
||||
}
|
||||
|
||||
|
||||
bool flip_y = (attr & 0x0008);
|
||||
|
||||
// various games don't want the flip bits in the usual place, wrlshunt for example, there's probably a bit to control this
|
||||
// and likewise these bits probably now have a different meaning, so this shouldn't be trusted
|
||||
if (has_extended_sprites)
|
||||
{
|
||||
if (highres || alt_extrasprite_hack)
|
||||
{
|
||||
flip_x = FlipXOff;
|
||||
flip_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t palette_offset = (attr & 0x0f00) >> 4;
|
||||
|
||||
if (has_extended_sprites)
|
||||
{
|
||||
// guess, tkmag220 / myac220 don't set this bit and expect all sprite palettes to be from the same bank as background palettes
|
||||
if (palbank & 1)
|
||||
palette_offset |= 0x100;
|
||||
|
||||
// many other gpl16250 sets have this bit set when they want the upper 256 colours on a per-sprite basis, seems like an extended feature
|
||||
if (attr & 0x8000)
|
||||
palette_offset |= 0x200;
|
||||
}
|
||||
|
||||
// the Circuit Racing game in PDC100 needs this or some graphics have bad colours at the edges when turning as it leaves stray lower bits set
|
||||
palette_offset >>= nc_bpp;
|
||||
palette_offset <<= nc_bpp;
|
||||
|
||||
|
||||
if (firstline < lastline)
|
||||
{
|
||||
int scanx = scanline - firstline;
|
||||
|
||||
if ((scanx >= 0) && (scanline <= lastline))
|
||||
{
|
||||
draw_tilestrip(blend, flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, scanx, x, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
draw_tilestrip(read_from_csspace, screenwidth, xmask, blend, flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, scanx, x, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -446,7 +705,7 @@ void spg_renderer_device::draw_sprite(const rectangle& cliprect, uint32_t* dst,
|
||||
|
||||
if ((scanx >= 0) && (scanline <= templastline))
|
||||
{
|
||||
draw_tilestrip(blend, flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, scanx, x, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
draw_tilestrip(read_from_csspace, screenwidth, xmask, blend, flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, scanx, x, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
// clipped against the bottom
|
||||
tempfirstline = firstline;
|
||||
@ -455,21 +714,29 @@ void spg_renderer_device::draw_sprite(const rectangle& cliprect, uint32_t* dst,
|
||||
|
||||
if ((scanx >= 0) && (scanline <= templastline))
|
||||
{
|
||||
draw_tilestrip(blend, flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, scanx, x, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram);
|
||||
draw_tilestrip(read_from_csspace, screenwidth, xmask, blend, flip_x, cliprect, dst, tile_h, tile_w, tilegfxdata_addr, tile, scanx, x, flip_y, palette_offset, nc_bpp, bits_per_row, words_per_tile, spc, paletteram, blendlevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void spg_renderer_device::draw_sprites(const rectangle &cliprect, uint32_t* dst, uint32_t scanline, int priority, address_space &spc, uint16_t* paletteram, uint16_t* spriteram, int sprlimit)
|
||||
void spg_renderer_device::draw_sprites(bool read_from_csspace, bool has_extended_sprites, bool alt_extrasprite_hack, uint32_t palbank, bool highres, const rectangle &cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t spritegfxdata_addr, address_space &spc, uint16_t* paletteram, uint16_t* spriteram, int sprlimit)
|
||||
{
|
||||
if (!(m_video_regs_42 & 0x0001))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// paccon suggests this, does older hardware have similar (if so, starting at what point?) or only GPL16250?
|
||||
if (sprlimit == -1)
|
||||
{
|
||||
sprlimit = (m_video_regs_42 & 0xff00) >> 8;
|
||||
if (sprlimit == 0)
|
||||
sprlimit = 0x100;
|
||||
}
|
||||
|
||||
for (uint32_t n = 0; n < sprlimit; n++)
|
||||
{
|
||||
draw_sprite(cliprect, dst, scanline, priority, 4 * n, spc, paletteram, spriteram);
|
||||
draw_sprite(read_from_csspace, has_extended_sprites, alt_extrasprite_hack, palbank, highres, cliprect, dst, scanline, priority, spritegfxdata_addr, 4 * n, spc, paletteram, spriteram);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,14 @@ public:
|
||||
spg_renderer_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
spg_renderer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void draw_sprites(const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, address_space& spc, uint16_t* paletteram, uint16_t* spriteram, int sprlimit);
|
||||
void draw_page(const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space& spc, uint16_t* paletteram, uint16_t* scrollram);
|
||||
void draw_sprites(bool read_from_csspace, bool has_extended_sprites, bool alt_extrasprite_hack, uint32_t palbank, bool highres, const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t spritegfxdata_addr, address_space& spc, uint16_t* paletteram, uint16_t* spriteram, int sprlimit);
|
||||
void draw_page(bool read_from_csspace, bool has_extended_tilemaps, bool use_alt_tile_addressing, uint32_t palbank, const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space& spc, uint16_t* paletteram, uint16_t* scrollram, uint32_t which);
|
||||
|
||||
void apply_saturation_and_fade(bitmap_rgb32& bitmap, const rectangle& cliprect, int scanline);
|
||||
|
||||
void set_video_reg_1c(uint16_t val) { m_video_regs_1c = val; update_vcmp_table(); }
|
||||
void set_video_reg_1d(uint16_t val) { m_video_regs_1d = val; update_vcmp_table(); }
|
||||
void set_video_reg_1e(uint16_t val) { m_video_regs_1e = val; update_vcmp_table(); }
|
||||
void set_video_reg_22(uint16_t val) { m_video_regs_22 = val; }
|
||||
void set_video_reg_2a(uint16_t val) { m_video_regs_2a = val; }
|
||||
void set_video_reg_30(uint16_t val) { m_video_regs_30 = val; }
|
||||
void set_video_reg_3c(uint16_t val) { m_video_regs_3c = val; }
|
||||
@ -30,12 +30,18 @@ public:
|
||||
uint16_t get_video_reg_1c(void) { return m_video_regs_1c; }
|
||||
uint16_t get_video_reg_1d(void) { return m_video_regs_1d; }
|
||||
uint16_t get_video_reg_1e(void) { return m_video_regs_1e; }
|
||||
uint16_t get_video_reg_22(void) { return m_video_regs_22; }
|
||||
uint16_t get_video_reg_2a(void) { return m_video_regs_2a; }
|
||||
uint16_t get_video_reg_30(void) { return m_video_regs_30; }
|
||||
uint16_t get_video_reg_3c(void) { return m_video_regs_3c; }
|
||||
uint16_t get_video_reg_42(void) { return m_video_regs_42; }
|
||||
|
||||
// used by some hack logic for the gpl16250 rendering for now
|
||||
void set_video_reg_7f(uint16_t val) { m_video_regs_7f = val; }
|
||||
uint16_t get_video_reg_7f(void) { return m_video_regs_7f; }
|
||||
|
||||
auto space_read_callback() { return m_space_read_cb.bind(); }
|
||||
void set_video_spaces(address_space* cpuspace, address_space* cs_space, int csbase) { m_cpuspace = cpuspace; m_cs_space = cs_space; m_csbase = csbase; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void device_start() override;
|
||||
@ -54,22 +60,21 @@ protected:
|
||||
};
|
||||
|
||||
template<spg_renderer_device::blend_enable_t Blend, spg_renderer_device::flipx_t FlipX>
|
||||
inline void draw_tilestrip(const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint16_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space &spc, uint16_t* palette);
|
||||
inline void draw_tilestrip(bool read_from_csspace, uint32_t screenwidth, uint32_t drawwidthmask, const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint32_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space &spc, uint16_t* palette, uint8_t blendlevel);
|
||||
|
||||
inline void draw_tilestrip(spg_renderer_device::blend_enable_t blend, spg_renderer_device::flipx_t flip_x, const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint16_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space& spc, uint16_t* paletteram);
|
||||
inline void draw_tilestrip(bool read_from_csspace, uint32_t screenwidth, uint32_t drawwidthmask, spg_renderer_device::blend_enable_t blend, spg_renderer_device::flipx_t flip_x, const rectangle& cliprect, uint32_t* dst, uint32_t tile_h, uint32_t tile_w, uint32_t tilegfxdata_addr, uint32_t tile, uint32_t tile_scanline, int drawx, bool flip_y, uint32_t palette_offset, const uint32_t nc_bpp, const uint32_t bits_per_row, const uint32_t words_per_tile, address_space& spc, uint16_t* paletteram, uint8_t blendlevel);
|
||||
|
||||
|
||||
void draw_sprite(const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t base_addr, address_space& spc, uint16_t* paletteram, uint16_t* spriteram);
|
||||
inline void draw_sprite(bool read_from_csspace, bool has_extended_sprites, bool alt_extrasprite_hack, uint32_t palbank, bool highres, const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t spritegfxdata_addr, uint32_t base_addr, address_space& spc, uint16_t* paletteram, uint16_t* spriteram);
|
||||
|
||||
inline bool get_tile_info(uint32_t tilemap_rambase, uint32_t palettemap_rambase, uint32_t x0, uint32_t y0, uint32_t tile_count_x, uint32_t ctrl, uint32_t attr, uint16_t& tile, spg_renderer_device::blend_enable_t& blend, spg_renderer_device::flipx_t& flip_x, bool& flip_y, uint32_t& palette_offset, address_space& spc);
|
||||
inline void draw_linemap(const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space& spc, uint16_t* paletteram);
|
||||
inline void draw_linemap(bool has_extended_tilemaps, const rectangle& cliprect, uint32_t* dst, uint32_t scanline, int priority, uint32_t tilegfxdata_addr, uint16_t* scrollregs, uint16_t* tilemapregs, address_space& spc, uint16_t* paletteram);
|
||||
|
||||
uint8_t mix_channel(uint8_t a, uint8_t b);
|
||||
inline uint8_t mix_channel(uint8_t a, uint8_t b, uint8_t alpha);
|
||||
|
||||
uint8_t m_rgb5_to_rgb8[32];
|
||||
uint32_t m_rgb555_to_rgb888[0x8000];
|
||||
|
||||
private:
|
||||
|
||||
void update_vcmp_table();
|
||||
|
||||
uint16_t m_video_regs_1c;
|
||||
@ -77,14 +82,20 @@ private:
|
||||
uint16_t m_video_regs_1e;
|
||||
|
||||
uint16_t m_video_regs_2a;
|
||||
uint16_t m_video_regs_22;
|
||||
uint16_t m_video_regs_42;
|
||||
|
||||
uint16_t m_video_regs_30;
|
||||
uint16_t m_video_regs_3c;
|
||||
|
||||
uint16_t m_video_regs_7f;
|
||||
|
||||
uint32_t m_ycmp_table[480];
|
||||
|
||||
devcb_read16 m_space_read_cb;
|
||||
|
||||
address_space* m_cpuspace;
|
||||
address_space* m_cs_space;
|
||||
int m_csbase;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SPG_RENDERER, spg_renderer_device)
|
||||
|
Loading…
Reference in New Issue
Block a user