mirror of
https://github.com/holub/mame
synced 2025-10-04 08:28:39 +03:00
short whatsnew: fixed some gfx bugs in midas.c "livequiz"
long wn: started converting neogeo video / sprite system to a device_reset created base device + number of derived classes NEOGEO_SPRITE_REGULAR is an reference implementation, drawing direct from NEOGEO_SPRITE_OPTIMZIED is a version with predecoded gfx (as we use now) this is the default used by the driver NEOGEO_SPRITE_MIDAS is a version supporting the changes needed by the MIDAS games (mainly 8bpp instead of 4bpp)
This commit is contained in:
parent
36ad612f60
commit
1a9ed9ebe8
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -7266,6 +7266,8 @@ src/mame/video/nbmj8991.c svneol=native#text/plain
|
||||
src/mame/video/nbmj9195.c svneol=native#text/plain
|
||||
src/mame/video/nemesis.c svneol=native#text/plain
|
||||
src/mame/video/neogeo.c svneol=native#text/plain
|
||||
src/mame/video/neogeo_spr.c svneol=native#text/plain
|
||||
src/mame/video/neogeo_spr.h svneol=native#text/plain
|
||||
src/mame/video/news.c svneol=native#text/plain
|
||||
src/mame/video/ninjakd2.c svneol=native#text/plain
|
||||
src/mame/video/ninjaw.c svneol=native#text/plain
|
||||
|
@ -7,7 +7,6 @@
|
||||
a reengineered Neo-Geo, with a few differences: no Z80, better sound chip, serial eeprom and 256 color tiles.
|
||||
Plus a PIC12C508A microcontroller, probably for the protection checks (I've patched them out for now).
|
||||
|
||||
This driver should be merged with neogeo.c
|
||||
Hardware description:
|
||||
|
||||
http://web.archive.org/web/20041018094226/http://www.andamiro.com/kor/business/hard_05.html
|
||||
@ -17,7 +16,7 @@
|
||||
VRAM 256kbyte (4Display/Access bank)
|
||||
|
||||
PaletteRAM 96kbyte
|
||||
|
||||
|
||||
Display 320(x)*224(y)
|
||||
|
||||
Sprite 16(x)*240(y(max))*380(max) (96 sprite/line(max))
|
||||
@ -55,22 +54,22 @@
|
||||
#include "sound/ymz280b.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "machine/ticket.h"
|
||||
|
||||
#include "includes/neogeo.h"
|
||||
|
||||
class midas_state : public driver_device
|
||||
{
|
||||
public:
|
||||
midas_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_gfxregs(*this, "gfxregs"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_eeprom(*this, "eeprom"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_palette(*this, "palette") { }
|
||||
m_palette(*this, "palette"),
|
||||
m_sprgen(*this, "spritegen"),
|
||||
m_screen(*this, "screen"),
|
||||
m_zoomram(*this, "zoomtable")
|
||||
{ }
|
||||
|
||||
UINT16 *m_gfxram;
|
||||
required_shared_ptr<UINT16> m_gfxregs;
|
||||
tilemap_t *m_tmap;
|
||||
DECLARE_READ16_MEMBER(ret_ffff);
|
||||
DECLARE_WRITE16_MEMBER(midas_gfxregs_w);
|
||||
DECLARE_WRITE16_MEMBER(livequiz_coin_w);
|
||||
@ -79,16 +78,25 @@ public:
|
||||
DECLARE_WRITE16_MEMBER(hammer_motor_w);
|
||||
DECLARE_WRITE16_MEMBER(hammer_led_w);
|
||||
DECLARE_WRITE16_MEMBER(midas_eeprom_w);
|
||||
DECLARE_WRITE16_MEMBER(midas_zoomtable_w);
|
||||
DECLARE_DRIVER_INIT(livequiz);
|
||||
TILE_GET_INFO_MEMBER(get_tile_info);
|
||||
virtual void video_start();
|
||||
UINT32 screen_update_midas(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
|
||||
|
||||
UINT32 screen_update_midas(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(livequiz_irqhandler);
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<neosprite_midas_device> m_sprgen;
|
||||
required_device<screen_device> m_screen;
|
||||
required_shared_ptr<UINT16> m_zoomram;
|
||||
|
||||
void screen_eof_midas(screen_device &screen, bool state);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -96,122 +104,18 @@ public:
|
||||
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(midas_state::get_tile_info)
|
||||
{
|
||||
UINT16 code = m_gfxram[ tile_index + 0x7000 ];
|
||||
SET_TILE_INFO_MEMBER(1, code & 0xfff, (code >> 12) & 0xf, TILE_FLIPXY( 0 ));
|
||||
}
|
||||
|
||||
void midas_state::video_start()
|
||||
{
|
||||
m_gfxram = auto_alloc_array(machine(), UINT16, 0x20000/2);
|
||||
|
||||
m_tmap = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(midas_state::get_tile_info),this), TILEMAP_SCAN_COLS,8,8,0x80,0x20);
|
||||
|
||||
m_tmap->set_transparent_pen(0);
|
||||
}
|
||||
|
||||
void midas_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
UINT32 midas_state::screen_update_midas(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
UINT16 *s = m_gfxram + 0x8000;
|
||||
UINT16 *codes = m_gfxram;
|
||||
// fill with background color first
|
||||
bitmap.fill(0x0, cliprect);
|
||||
|
||||
int sx_old = 0, sy_old = 0, ynum_old = 0, xzoom_old = 0;
|
||||
int xdim, ydim, xscale, yscale;
|
||||
int i,y;
|
||||
m_sprgen->draw_sprites(bitmap, cliprect.min_y);
|
||||
|
||||
for (i = 0; i < 0x180; i++,s++,codes+=0x40)
|
||||
{
|
||||
int zoom = s[0x000];
|
||||
int sy = s[0x200];
|
||||
int sx = s[0x400];
|
||||
|
||||
int xzoom = ((zoom >> 8) & 0x0f) + 1;
|
||||
int yzoom = ((zoom >> 0) & 0x7f) + 1;
|
||||
|
||||
int ynum;
|
||||
|
||||
if (sy & 0x40)
|
||||
{
|
||||
ynum = ynum_old;
|
||||
|
||||
sx = sx_old + xzoom_old;
|
||||
sy = sy_old;
|
||||
|
||||
if (sx >= 0x1f0)
|
||||
sx -= 0x200;
|
||||
}
|
||||
else
|
||||
{
|
||||
ynum = sy & 0x3f;
|
||||
|
||||
sx = (sx >> 7);
|
||||
sy = 0x200 - (sy >> 7);
|
||||
|
||||
if (sx >= 0x1f0)
|
||||
sx -= 0x200;
|
||||
|
||||
if (ynum > 0x20)
|
||||
ynum = 0x20;
|
||||
}
|
||||
|
||||
ynum_old = ynum;
|
||||
sx_old = sx;
|
||||
sy_old = sy;
|
||||
xzoom_old = xzoom;
|
||||
|
||||
// Use fixed point values (16.16), for accuracy
|
||||
|
||||
sx <<= 16;
|
||||
sy <<= 16;
|
||||
|
||||
xdim = ( xzoom << 16 ) * 16 / 16;
|
||||
ydim = ( yzoom << 16 ) * 16 / 0x80;
|
||||
|
||||
xscale = xdim / 16;
|
||||
yscale = ydim / 16;
|
||||
|
||||
// Let's approximate to the nearest greater integer value
|
||||
// to avoid holes in between tiles
|
||||
|
||||
if (xscale & 0xffff) xscale += (1<<16) / 16;
|
||||
if (yscale & 0xffff) yscale += (1<<16) / 16;
|
||||
|
||||
// Draw the tiles
|
||||
|
||||
for (y = 0; y < ynum; y++)
|
||||
{
|
||||
UINT16 code = codes[y*2];
|
||||
UINT16 attr = codes[y*2+1];
|
||||
|
||||
m_gfxdecode->gfx(0)->zoom_transpen(bitmap,cliprect,
|
||||
code,
|
||||
attr >> 8,
|
||||
attr & 1, attr & 2,
|
||||
sx / 0x10000, ((sy + y * ydim) / 0x10000)&0x1ff,
|
||||
xscale, yscale, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 midas_state::screen_update_midas(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int layers_ctrl = -1;
|
||||
|
||||
#ifdef MAME_DEBUG
|
||||
if ( machine().input().code_pressed(KEYCODE_Z) )
|
||||
{
|
||||
int msk = 0;
|
||||
if (machine().input().code_pressed(KEYCODE_Q)) msk |= 1 << 0; // for m_tmap
|
||||
if (machine().input().code_pressed(KEYCODE_A)) msk |= 1 << 1; // for sprites
|
||||
if (msk != 0) layers_ctrl &= msk;
|
||||
}
|
||||
#endif
|
||||
|
||||
bitmap.fill(4095, cliprect);
|
||||
|
||||
if (layers_ctrl & 2) draw_sprites(bitmap,cliprect);
|
||||
if (layers_ctrl & 1) m_tmap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
m_sprgen->draw_fixed_layer(bitmap, cliprect.min_y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -238,23 +142,34 @@ READ16_MEMBER(midas_state::ret_ffff)
|
||||
|
||||
WRITE16_MEMBER(midas_state::midas_gfxregs_w)
|
||||
{
|
||||
COMBINE_DATA( m_gfxregs + offset );
|
||||
|
||||
switch( offset )
|
||||
/* accessing the LSB only is not mapped */
|
||||
if (mem_mask != 0x00ff)
|
||||
{
|
||||
case 1:
|
||||
/* accessing the MSB only stores same data in MSB and LSB */
|
||||
if (mem_mask == 0xff00)
|
||||
data = (data & 0xff00) | (data >> 8);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
UINT16 addr = m_gfxregs[0];
|
||||
m_gfxram[addr] = data;
|
||||
m_gfxregs[0] += m_gfxregs[2];
|
||||
|
||||
if ( addr >= 0x7000 && addr <= 0x7fff ) m_tmap->mark_tile_dirty(addr - 0x7000);
|
||||
|
||||
break;
|
||||
case 0x00: m_sprgen->set_videoram_offset(data); break;
|
||||
case 0x01: m_sprgen->set_videoram_data(data); break;
|
||||
case 0x02: m_sprgen->set_videoram_modulo(data); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(midas_state::midas_zoomtable_w)
|
||||
{
|
||||
COMBINE_DATA(&m_zoomram[offset]);
|
||||
UINT8 *rgn = memregion("zoomy")->base();
|
||||
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
rgn[offset+0x00000] = data & 0xff;
|
||||
rgn[offset+0x10000] = data & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
/***************************************************************************************
|
||||
Live Quiz Show
|
||||
***************************************************************************************/
|
||||
@ -297,7 +212,7 @@ static ADDRESS_MAP_START( livequiz_map, AS_PROGRAM, 16, midas_state )
|
||||
AM_RANGE(0xba0000, 0xba0001) AM_READ_PORT("START3")
|
||||
AM_RANGE(0xbc0000, 0xbc0001) AM_READ_PORT("PLAYER3")
|
||||
|
||||
AM_RANGE(0xd00000, 0xd1ffff) AM_RAM // zoom table?
|
||||
AM_RANGE(0xd00000, 0xd1ffff) AM_RAM_WRITE(midas_zoomtable_w) AM_SHARE("zoomtable") // zoom table?
|
||||
|
||||
AM_RANGE(0xe00000, 0xe3ffff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
@ -361,7 +276,7 @@ static ADDRESS_MAP_START( hammer_map, AS_PROGRAM, 16, midas_state )
|
||||
|
||||
AM_RANGE(0x9a0000, 0x9a0001) AM_WRITE(midas_eeprom_w )
|
||||
|
||||
AM_RANGE(0x9c0000, 0x9c0005) AM_WRITE(midas_gfxregs_w ) AM_SHARE("gfxregs")
|
||||
AM_RANGE(0x9c0000, 0x9c0005) AM_WRITE(midas_gfxregs_w )
|
||||
|
||||
AM_RANGE(0xa00000, 0xa3ffff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
|
||||
AM_RANGE(0xa40000, 0xa7ffff) AM_RAM
|
||||
@ -380,7 +295,7 @@ static ADDRESS_MAP_START( hammer_map, AS_PROGRAM, 16, midas_state )
|
||||
|
||||
AM_RANGE(0xbc0004, 0xbc0005) AM_READ(hammer_sensor_r )
|
||||
|
||||
AM_RANGE(0xd00000, 0xd1ffff) AM_RAM // zoom table?
|
||||
AM_RANGE(0xd00000, 0xd1ffff) AM_RAM_WRITE(midas_zoomtable_w) AM_SHARE("zoomtable") // zoom table?
|
||||
|
||||
AM_RANGE(0xe00000, 0xe3ffff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
@ -389,17 +304,14 @@ ADDRESS_MAP_END
|
||||
static const gfx_layout layout16x16x8 =
|
||||
{
|
||||
16,16,
|
||||
RGN_FRAC(1,4),
|
||||
RGN_FRAC(1,1),
|
||||
8,
|
||||
{
|
||||
RGN_FRAC(3,4)+8,RGN_FRAC(3,4)+0,
|
||||
RGN_FRAC(2,4)+8,RGN_FRAC(2,4)+0,
|
||||
RGN_FRAC(1,4)+8,RGN_FRAC(1,4)+0,
|
||||
RGN_FRAC(0,4)+8,RGN_FRAC(0,4)+0
|
||||
56,48,40,32,24,16,8,0
|
||||
},
|
||||
{ STEP8(8*16*2+7,-1), STEP8(7,-1) },
|
||||
{ STEP16(0,8*2) },
|
||||
16*16*2
|
||||
{ 0,1,2,3,4,5,6,7, 16*64+0, 6*64+1, 6*64+2, 6*64+3, 6*64+4, 6*64+5, 6*64+6, 6*64+7, },
|
||||
{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
|
||||
16*128
|
||||
};
|
||||
|
||||
static const gfx_layout layout8x8x8_2 =
|
||||
@ -692,12 +604,35 @@ static INPUT_PORTS_START( hammer )
|
||||
|
||||
INPUT_PORTS_END
|
||||
|
||||
void midas_state::machine_start()
|
||||
{
|
||||
m_sprgen->set_pens((pen_t*)m_palette->pens());
|
||||
m_sprgen->set_screen(m_screen);
|
||||
m_sprgen->set_sprite_region(memregion("sprites"));
|
||||
m_sprgen->set_fixed_regions(memregion("tiles"), memregion("tiles"));
|
||||
}
|
||||
|
||||
void midas_state::machine_reset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(midas_state::livequiz_irqhandler)
|
||||
{
|
||||
logerror("YMZ280 is generating an interrupt. State=%08x\n",state);
|
||||
}
|
||||
|
||||
|
||||
void midas_state::screen_eof_midas(screen_device &screen, bool state)
|
||||
{
|
||||
m_sprgen->buffer_vram();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static MACHINE_CONFIG_START( livequiz, midas_state )
|
||||
|
||||
/* basic machine hardware */
|
||||
@ -709,12 +644,11 @@ static MACHINE_CONFIG_START( livequiz, midas_state )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
|
||||
MCFG_SCREEN_SIZE(320, 256)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 16, 256-16-1)
|
||||
MCFG_SCREEN_RAW_PARAMS(NEOGEO_PIXEL_CLOCK, NEOGEO_HTOTAL, NEOGEO_HBEND, NEOGEO_HBSTART, NEOGEO_VTOTAL, NEOGEO_VBEND, NEOGEO_VBSTART)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(midas_state, screen_update_midas)
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
MCFG_SCREEN_VBLANK_DRIVER(midas_state, screen_eof_midas)
|
||||
|
||||
MCFG_DEVICE_ADD("spritegen", NEOGEO_SPRITE_MIDAS, 0)
|
||||
|
||||
MCFG_GFXDECODE_ADD("gfxdecode", "palette", midas)
|
||||
MCFG_PALETTE_ADD("palette", 0x10000)
|
||||
@ -743,12 +677,11 @@ static MACHINE_CONFIG_START( hammer, midas_state )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
|
||||
MCFG_SCREEN_SIZE(320, 256)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 16, 256-16-1)
|
||||
MCFG_SCREEN_RAW_PARAMS(NEOGEO_PIXEL_CLOCK, NEOGEO_HTOTAL, NEOGEO_HBEND, NEOGEO_HBSTART, NEOGEO_VTOTAL, NEOGEO_VBEND, NEOGEO_VBSTART)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(midas_state, screen_update_midas)
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
MCFG_SCREEN_VBLANK_DRIVER(midas_state, screen_eof_midas)
|
||||
|
||||
MCFG_DEVICE_ADD("spritegen", NEOGEO_SPRITE_MIDAS, 0)
|
||||
|
||||
MCFG_GFXDECODE_ADD("gfxdecode", "palette", midas)
|
||||
MCFG_PALETTE_ADD("palette", 0x10000)
|
||||
@ -861,16 +794,19 @@ ROM_START( livequiz )
|
||||
ROM_LOAD( "sub_pic12c508a.u4", 0x000000, 0x000400, CRC(e52ebdc4) SHA1(0f3af66b5ea184e49188e74a873699324a3930f1) )
|
||||
|
||||
ROM_REGION( 0x800000, "sprites", 0 )
|
||||
ROM_LOAD( "flash.u15", 0x000000, 0x200000, CRC(d6eb56f1) SHA1(52d67bb25dd968c79eccb05159a578516b27e557) )
|
||||
ROM_LOAD( "flash.u19", 0x200000, 0x200000, CRC(daa81532) SHA1(9e66bb4639b92c3d76b7918535f55883f22f24b2) )
|
||||
ROM_LOAD( "flash.u16", 0x400000, 0x200000, CRC(4c9fd873) SHA1(6e185304ce29771265d3c48b0ef0e840d8bed02d) )
|
||||
ROM_LOAD( "flash.u20", 0x600000, 0x200000, CRC(b540a8c7) SHA1(25b9b30c7d5ff1e410ea30580017e45590542561) )
|
||||
ROM_LOAD32_BYTE( "flash.u15", 0x000000, 0x200000, CRC(d6eb56f1) SHA1(52d67bb25dd968c79eccb05159a578516b27e557) )
|
||||
ROM_LOAD32_BYTE( "flash.u19", 0x000001, 0x200000, CRC(daa81532) SHA1(9e66bb4639b92c3d76b7918535f55883f22f24b2) )
|
||||
ROM_LOAD32_BYTE( "flash.u16", 0x000002, 0x200000, CRC(4c9fd873) SHA1(6e185304ce29771265d3c48b0ef0e840d8bed02d) )
|
||||
ROM_LOAD32_BYTE( "flash.u20", 0x000003, 0x200000, CRC(b540a8c7) SHA1(25b9b30c7d5ff1e410ea30580017e45590542561) )
|
||||
|
||||
ROM_REGION( 0x080000, "tiles", 0 )
|
||||
ROM_LOAD( "27c4096.u23", 0x000000, 0x080000, CRC(25121de8) SHA1(edf24d87551639b871baf3243b452a4e2ba84107) )
|
||||
|
||||
ROM_REGION( 0x200000, "ymz", 0 )
|
||||
ROM_LOAD( "flash.u5", 0x000000, 0x200000, CRC(dc062792) SHA1(ec415c918c47ce9d181f014cde317af5717600e4) )
|
||||
|
||||
ROM_REGION( 0x20000, "zoomy", ROMREGION_ERASE00 )
|
||||
/* uploaded */
|
||||
ROM_END
|
||||
|
||||
DRIVER_INIT_MEMBER(midas_state,livequiz)
|
||||
@ -944,17 +880,17 @@ ROM_START( hammer )
|
||||
ROM_LOAD16_WORD_SWAP( "p.u22", 0x000000, 0x200000, CRC(687f1596) SHA1(3dc5fb0af1e8c4f3a42ce4aad39635b1111831d8) )
|
||||
|
||||
ROM_REGION( 0x1000000, "sprites", 0 )
|
||||
ROM_LOAD( "a0l.u44", 0x000000, 0x200000, CRC(b9cafd81) SHA1(24698970d1aea0907e2963c872ce61077f44c3af) )
|
||||
ROM_LOAD( "a0h.u46", 0x200000, 0x200000, CRC(f60f188b) SHA1(486f26c473b46efb402662b2f374e361cd7b4284) )
|
||||
ROM_LOAD32_BYTE( "a0l.u44", 0x000000, 0x200000, CRC(b9cafd81) SHA1(24698970d1aea0907e2963c872ce61077f44c3af) )
|
||||
ROM_LOAD32_BYTE( "a0h.u46", 0x800000, 0x200000, CRC(f60f188b) SHA1(486f26c473b46efb402662b2f374e361cd7b4284) )
|
||||
|
||||
ROM_LOAD( "a1l.u48", 0x400000, 0x200000, CRC(82129cf9) SHA1(6d68e943854bc9e8ea555bf03107dc9e836ca4d9) )
|
||||
ROM_LOAD( "a1h.u50", 0x600000, 0x200000, CRC(76897c90) SHA1(aded60d3db834598cd54ad9140eee7be4129cb27) )
|
||||
ROM_LOAD32_BYTE( "a1l.u48", 0x000001, 0x200000, CRC(82129cf9) SHA1(6d68e943854bc9e8ea555bf03107dc9e836ca4d9) )
|
||||
ROM_LOAD32_BYTE( "a1h.u50", 0x800001, 0x200000, CRC(76897c90) SHA1(aded60d3db834598cd54ad9140eee7be4129cb27) )
|
||||
|
||||
ROM_LOAD( "a2l.u45", 0x800000, 0x200000, CRC(d8086ee5) SHA1(9d5f2b3a0f903a69cfd1108ddf5ea61b571c3fe3) )
|
||||
ROM_LOAD( "a2h.u47", 0xa00000, 0x200000, CRC(a64aa2df) SHA1(7e4eb049cd6a5971a455488a484f225763921614) )
|
||||
ROM_LOAD32_BYTE( "a2l.u45", 0x000002, 0x200000, CRC(d8086ee5) SHA1(9d5f2b3a0f903a69cfd1108ddf5ea61b571c3fe3) )
|
||||
ROM_LOAD32_BYTE( "a2h.u47", 0x800002, 0x200000, CRC(a64aa2df) SHA1(7e4eb049cd6a5971a455488a484f225763921614) )
|
||||
|
||||
ROM_LOAD( "a3l.u49", 0xc00000, 0x200000, CRC(4e83cf00) SHA1(e66a0b4eae0f46bf36126be3795cfac3ad3d4282) )
|
||||
ROM_LOAD( "a3h.u51", 0xe00000, 0x200000, CRC(834de39f) SHA1(6e9867180ca20e64f60bad5cad82674ce8f45b7b) )
|
||||
ROM_LOAD32_BYTE( "a3l.u49", 0x000003, 0x200000, CRC(4e83cf00) SHA1(e66a0b4eae0f46bf36126be3795cfac3ad3d4282) )
|
||||
ROM_LOAD32_BYTE( "a3h.u51", 0x800003, 0x200000, CRC(834de39f) SHA1(6e9867180ca20e64f60bad5cad82674ce8f45b7b) )
|
||||
|
||||
ROM_REGION( 0x080000, "tiles", ROMREGION_ERASE )
|
||||
// Use the tiles rom from livequiz (not present in this set) to show some debug text
|
||||
@ -963,7 +899,10 @@ ROM_START( hammer )
|
||||
ROM_REGION( 0x400000, "ymz", 0 )
|
||||
ROM_LOAD( "s0.u25", 0x000000, 0x200000, CRC(c049a3e0) SHA1(0c7016c3128c170a84ad3f92fad1165775210e3d) )
|
||||
ROM_LOAD( "s1.u26", 0x200000, 0x200000, CRC(9cc4b3ec) SHA1(b91a8747074a1032eb7f70a015d394fe8e896d7e) )
|
||||
|
||||
ROM_REGION( 0x20000, "zoomy", ROMREGION_ERASE00 )
|
||||
/* uploaded */
|
||||
ROM_END
|
||||
|
||||
GAME( 1999, livequiz, 0, livequiz, livequiz, midas_state, livequiz, ROT0, "Andamiro", "Live Quiz Show", GAME_IMPERFECT_GRAPHICS )
|
||||
GAME( 1999, livequiz, 0, livequiz, livequiz, midas_state, livequiz, ROT0, "Andamiro", "Live Quiz Show", 0 )
|
||||
GAME( 2000, hammer, 0, hammer, hammer, driver_device, 0, ROT0, "Andamiro", "Hammer", 0 )
|
||||
|
@ -457,9 +457,7 @@
|
||||
*
|
||||
*************************************/
|
||||
|
||||
// On scanline 224, /VBLANK goes low 56 mclks (14 pixels) from the rising edge of /HSYNC.
|
||||
// Two mclks after /VBLANK goes low, the hardware sets a pending IRQ1 flip-flop.
|
||||
#define NEOGEO_VBLANK_IRQ_HTIM (attotime::from_ticks(56+2, NEOGEO_MASTER_CLOCK))
|
||||
|
||||
|
||||
// The display counter is automatically reloaded with the load register contents on scanline 224,
|
||||
// 1146 mclks from the rising edge of /HSYNC.
|
||||
@ -999,7 +997,7 @@ WRITE8_MEMBER(neogeo_state::system_control_w)
|
||||
case 0x05:
|
||||
if (m_type == NEOGEO_MVS)
|
||||
{
|
||||
neogeo_set_fixed_layer_source(bit);
|
||||
m_sprgen->neogeo_set_fixed_layer_source(bit);
|
||||
m_bank_audio_main->set_entry(bit);
|
||||
}
|
||||
break;
|
||||
@ -1088,7 +1086,7 @@ void neogeo_state::set_output_data( UINT8 data )
|
||||
|
||||
DRIVER_INIT_MEMBER(neogeo_state,neogeo)
|
||||
{
|
||||
m_fixed_layer_bank_type = 0;
|
||||
m_sprgen->m_fixed_layer_bank_type = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1143,6 +1141,12 @@ void neogeo_state::machine_start()
|
||||
save_item(NAME(m_led2_value));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(neogeo_state::neogeo_postload), this));
|
||||
|
||||
|
||||
m_sprgen->set_screen(m_screen);
|
||||
m_sprgen->set_sprite_region(m_region_sprites);
|
||||
m_sprgen->set_fixed_regions(m_region_fixed, m_region_fixedbios);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1787,6 +1791,8 @@ MACHINE_CONFIG_START( neogeo_base, neogeo_state )
|
||||
MCFG_SCREEN_RAW_PARAMS(NEOGEO_PIXEL_CLOCK, NEOGEO_HTOTAL, NEOGEO_HBEND, NEOGEO_HBSTART, NEOGEO_VTOTAL, NEOGEO_VBEND, NEOGEO_VBSTART)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(neogeo_state, screen_update_neogeo)
|
||||
|
||||
MCFG_DEVICE_ADD("spritegen", NEOGEO_SPRITE_OPTIMZIED, 0)
|
||||
|
||||
/* audio hardware */
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
|
||||
@ -10208,7 +10214,7 @@ DRIVER_INIT_MEMBER(neogeo_state,fatfury2)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,zupapa)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0xbd);
|
||||
}
|
||||
|
||||
@ -10229,7 +10235,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kof99)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
kof99_decrypt_68k();
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0x00);
|
||||
kof99_install_protection();
|
||||
}
|
||||
@ -10237,7 +10243,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kof99)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,kof99k)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0x00);
|
||||
}
|
||||
|
||||
@ -10245,7 +10251,7 @@ DRIVER_INIT_MEMBER(neogeo_state,garou)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
garou_decrypt_68k();
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0x06);
|
||||
garou_install_protection();
|
||||
}
|
||||
@ -10254,7 +10260,7 @@ DRIVER_INIT_MEMBER(neogeo_state,garouh)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
garouh_decrypt_68k();
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0x06);
|
||||
garouh_install_protection();
|
||||
}
|
||||
@ -10270,7 +10276,7 @@ DRIVER_INIT_MEMBER(neogeo_state,mslug3)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
mslug3_decrypt_68k();
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0xad);
|
||||
mslug3_install_protection();
|
||||
}
|
||||
@ -10278,7 +10284,7 @@ DRIVER_INIT_MEMBER(neogeo_state,mslug3)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,mslug3h)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0xad);
|
||||
}
|
||||
|
||||
@ -10293,7 +10299,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kof2000)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
kof2000_decrypt_68k();
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x00);
|
||||
kof2000_install_protection();
|
||||
@ -10302,7 +10308,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kof2000)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,kof2000n)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x00);
|
||||
}
|
||||
@ -10310,7 +10316,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kof2000n)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,kof2001)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof2000_neogeo_gfx_decrypt(0x1e);
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
}
|
||||
@ -10339,7 +10345,7 @@ DRIVER_INIT_MEMBER(neogeo_state,ct2k3sa)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,mslug4)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1; /* USA violent content screen is wrong -- not a bug, confirmed on real hardware! */
|
||||
m_sprgen->m_fixed_layer_bank_type = 1; /* USA violent content screen is wrong -- not a bug, confirmed on real hardware! */
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x31);
|
||||
neo_pcm2_snk_1999(8);
|
||||
@ -10356,42 +10362,42 @@ DRIVER_INIT_MEMBER(neogeo_state,ms4plus)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,ganryu)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0x07);
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(neogeo_state,s1945p)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0x05);
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(neogeo_state,preisle2)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0x9f);
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(neogeo_state,bangbead)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0xf8);
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(neogeo_state,nitd)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0xff);
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(neogeo_state,sengoku3)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
kof99_neogeo_gfx_decrypt(0xfe);
|
||||
}
|
||||
|
||||
@ -10399,7 +10405,7 @@ DRIVER_INIT_MEMBER(neogeo_state,rotd)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
neo_pcm2_snk_1999(16);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x3f);
|
||||
}
|
||||
@ -10483,7 +10489,7 @@ DRIVER_INIT_MEMBER(neogeo_state,matrim)
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
matrim_decrypt_68k();
|
||||
neo_pcm2_swap(1);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x6a);
|
||||
}
|
||||
@ -10492,7 +10498,7 @@ DRIVER_INIT_MEMBER(neogeo_state,matrimbl)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
matrim_decrypt_68k();
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
matrimbl_decrypt();
|
||||
neogeo_sfix_decrypt(); /* required for text layer */
|
||||
}
|
||||
@ -10501,7 +10507,7 @@ DRIVER_INIT_MEMBER(neogeo_state,pnyaa)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
neo_pcm2_snk_1999(4);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x2e);
|
||||
}
|
||||
@ -10511,7 +10517,7 @@ DRIVER_INIT_MEMBER(neogeo_state,mslug5)
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
mslug5_decrypt_68k();
|
||||
neo_pcm2_swap(2);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x19);
|
||||
install_pvc_protection();
|
||||
@ -10537,7 +10543,7 @@ DRIVER_INIT_MEMBER(neogeo_state,ms5pcb)
|
||||
svcpcb_gfx_decrypt();
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x19);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
svcpcb_s1data_decrypt();
|
||||
neo_pcm2_swap(2);
|
||||
install_pvc_protection();
|
||||
@ -10550,7 +10556,7 @@ DRIVER_INIT_MEMBER(neogeo_state,ms5plus)
|
||||
cmc50_neogeo_gfx_decrypt(0x19);
|
||||
neo_pcm2_swap(2);
|
||||
neogeo_bootleg_sx_decrypt(1);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
install_ms5plus_protection();
|
||||
}
|
||||
@ -10565,7 +10571,7 @@ DRIVER_INIT_MEMBER(neogeo_state,svcpcb)
|
||||
kof2000_neogeo_gfx_decrypt(0x57);
|
||||
svcpcb_s1data_decrypt();
|
||||
neo_pcm2_swap(3);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
install_pvc_protection();
|
||||
install_banked_bios();
|
||||
}
|
||||
@ -10575,7 +10581,7 @@ DRIVER_INIT_MEMBER(neogeo_state,svc)
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
svc_px_decrypt();
|
||||
neo_pcm2_swap(3);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x57);
|
||||
install_pvc_protection();
|
||||
@ -10621,7 +10627,7 @@ DRIVER_INIT_MEMBER(neogeo_state,samsho5)
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
samsho5_decrypt_68k();
|
||||
neo_pcm2_swap(4);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x0f);
|
||||
}
|
||||
@ -10658,7 +10664,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kf2k3pcb)
|
||||
kof2000_neogeo_gfx_decrypt(0x9d);
|
||||
kf2k3pcb_decrypt_s1data();
|
||||
neo_pcm2_swap(5);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
install_pvc_protection();
|
||||
m_maincpu->space(AS_PROGRAM).install_rom(0xc00000, 0xc7ffff, 0, 0x080000, memregion("mainbios")->base()); // 512k bios
|
||||
}
|
||||
@ -10668,7 +10674,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kof2003)
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
kof2003_decrypt_68k();
|
||||
neo_pcm2_swap(5);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x9d);
|
||||
install_pvc_protection();
|
||||
@ -10679,7 +10685,7 @@ DRIVER_INIT_MEMBER(neogeo_state,kof2003h)
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
kof2003h_decrypt_68k();
|
||||
neo_pcm2_swap(5);
|
||||
m_fixed_layer_bank_type = 2;
|
||||
m_sprgen->m_fixed_layer_bank_type = 2;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x9d);
|
||||
install_pvc_protection();
|
||||
@ -10719,7 +10725,7 @@ DRIVER_INIT_MEMBER(neogeo_state,samsh5sp)
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
samsh5sp_decrypt_68k();
|
||||
neo_pcm2_swap(6);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0x0d);
|
||||
}
|
||||
@ -10727,7 +10733,7 @@ DRIVER_INIT_MEMBER(neogeo_state,samsh5sp)
|
||||
DRIVER_INIT_MEMBER(neogeo_state,jockeygp)
|
||||
{
|
||||
DRIVER_INIT_CALL(neogeo);
|
||||
m_fixed_layer_bank_type = 1;
|
||||
m_sprgen->m_fixed_layer_bank_type = 1;
|
||||
neogeo_cmc50_m1_decrypt();
|
||||
kof2000_neogeo_gfx_decrypt(0xac);
|
||||
|
||||
|
@ -6,19 +6,11 @@
|
||||
|
||||
#include "machine/upd1990a.h"
|
||||
#include "machine/ng_memcard.h"
|
||||
#include "video/neogeo_spr.h"
|
||||
|
||||
#define NEOGEO_MASTER_CLOCK (24000000)
|
||||
#define NEOGEO_MAIN_CPU_CLOCK (NEOGEO_MASTER_CLOCK / 2)
|
||||
#define NEOGEO_AUDIO_CPU_CLOCK (NEOGEO_MASTER_CLOCK / 6)
|
||||
#define NEOGEO_YM2610_CLOCK (NEOGEO_MASTER_CLOCK / 3)
|
||||
#define NEOGEO_PIXEL_CLOCK (NEOGEO_MASTER_CLOCK / 4)
|
||||
#define NEOGEO_HTOTAL (0x180)
|
||||
#define NEOGEO_HBEND (0x01e) /* this should really be 29.5 */
|
||||
#define NEOGEO_HBSTART (0x15e) /* this should really be 349.5 */
|
||||
#define NEOGEO_VTOTAL (0x108)
|
||||
#define NEOGEO_VBEND (0x010)
|
||||
#define NEOGEO_VBSTART (0x0f0)
|
||||
#define NEOGEO_VSSTART (0x100)
|
||||
// On scanline 224, /VBLANK goes low 56 mclks (14 pixels) from the rising edge of /HSYNC.
|
||||
// Two mclks after /VBLANK goes low, the hardware sets a pending IRQ1 flip-flop.
|
||||
#define NEOGEO_VBLANK_IRQ_HTIM (attotime::from_ticks(56+2, NEOGEO_MASTER_CLOCK))
|
||||
|
||||
|
||||
class neogeo_state : public driver_device
|
||||
@ -39,7 +31,8 @@ public:
|
||||
m_save_ram(*this, "saveram"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_memcard(*this, "memcard")
|
||||
m_memcard(*this, "memcard"),
|
||||
m_sprgen(*this, "spritegen")
|
||||
{ }
|
||||
|
||||
DECLARE_WRITE8_MEMBER(io_control_w);
|
||||
@ -130,8 +123,7 @@ public:
|
||||
TIMER_CALLBACK_MEMBER(display_position_interrupt_callback);
|
||||
TIMER_CALLBACK_MEMBER(display_position_vblank_callback);
|
||||
TIMER_CALLBACK_MEMBER(vblank_interrupt_callback);
|
||||
TIMER_CALLBACK_MEMBER(auto_animation_timer_callback);
|
||||
TIMER_CALLBACK_MEMBER(sprite_line_timer_callback);
|
||||
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(neo_cartridge);
|
||||
|
||||
// MVS-specific
|
||||
@ -158,31 +150,17 @@ protected:
|
||||
void neogeo_set_display_counter_msb(UINT16 data);
|
||||
void neogeo_set_display_counter_lsb(UINT16 data);
|
||||
void set_video_control( UINT16 data );
|
||||
void optimize_sprite_data();
|
||||
void draw_fixed_layer( bitmap_rgb32 &bitmap, int scanline );
|
||||
void set_videoram_offset( UINT16 data );
|
||||
UINT16 get_videoram_data( );
|
||||
void set_videoram_data( UINT16 data);
|
||||
void set_videoram_modulo( UINT16 data);
|
||||
UINT16 get_videoram_modulo( );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void compute_rgb_weights( );
|
||||
void regenerate_pens();
|
||||
pen_t get_pen( UINT16 data );
|
||||
void neogeo_set_palette_bank( UINT8 data );
|
||||
void neogeo_set_screen_dark( UINT8 data );
|
||||
void set_auto_animation_speed( UINT8 data);
|
||||
void set_auto_animation_disabled( UINT8 data);
|
||||
UINT8 neogeo_get_auto_animation_counter( );
|
||||
void create_auto_animation_timer( );
|
||||
void start_auto_animation_timer( );
|
||||
void neogeo_set_fixed_layer_source( UINT8 data );
|
||||
inline int rows_to_height(int rows);
|
||||
inline int sprite_on_scanline(int scanline, int y, int rows);
|
||||
void draw_sprites( bitmap_rgb32 &bitmap, int scanline );
|
||||
void parse_sprites( int scanline );
|
||||
void create_sprite_line_timer( );
|
||||
void start_sprite_line_timer( );
|
||||
UINT16 get_video_control( );
|
||||
|
||||
void audio_cpu_check_nmi();
|
||||
void select_controller( UINT8 data );
|
||||
void set_save_ram_unlock( UINT8 data );
|
||||
@ -359,8 +337,6 @@ protected:
|
||||
emu_timer *m_display_position_interrupt_timer;
|
||||
emu_timer *m_display_position_vblank_timer;
|
||||
emu_timer *m_vblank_interrupt_timer;
|
||||
emu_timer *m_auto_animation_timer;
|
||||
emu_timer *m_sprite_line_timer;
|
||||
UINT32 m_display_counter;
|
||||
UINT8 m_vblank_interrupt_pending;
|
||||
UINT8 m_display_position_interrupt_pending;
|
||||
@ -369,23 +345,8 @@ protected:
|
||||
UINT8 m_vblank_level;
|
||||
UINT8 m_raster_level;
|
||||
|
||||
UINT16 *m_videoram;
|
||||
UINT16 m_vram_offset;
|
||||
UINT16 m_vram_read_buffer;
|
||||
UINT16 m_vram_modulo;
|
||||
|
||||
const UINT8 *m_region_zoomy;
|
||||
|
||||
dynamic_array<UINT8> m_sprite_gfx;
|
||||
UINT32 m_sprite_gfx_address_mask;
|
||||
|
||||
UINT8 m_auto_animation_speed;
|
||||
UINT8 m_auto_animation_disabled;
|
||||
UINT8 m_auto_animation_counter;
|
||||
UINT8 m_auto_animation_frame_counter;
|
||||
|
||||
UINT8 m_fixed_layer_source;
|
||||
UINT8 m_fixed_layer_bank_type;
|
||||
required_device<neosprite_optimized_device> m_sprgen;
|
||||
UINT16 get_video_control( );
|
||||
|
||||
// color/palette related
|
||||
// TODO: disentangle from the rest of the video emulation
|
||||
@ -416,6 +377,8 @@ protected:
|
||||
const UINT8 *address_0_7_xor;
|
||||
|
||||
UINT16 m_cartridge_ram[0x1000];
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1524,6 +1524,7 @@ $(MAMEOBJ)/nasco.a: \
|
||||
|
||||
$(MAMEOBJ)/neogeo.a: \
|
||||
$(DRIVERS)/neogeo.o $(VIDEO)/neogeo.o \
|
||||
$(VIDEO)/neogeo_spr.o \
|
||||
$(MACHINE)/neoboot.o \
|
||||
$(MACHINE)/neocrypt.o \
|
||||
$(MACHINE)/neoprot.o \
|
||||
|
@ -10,48 +10,6 @@
|
||||
|
||||
#define NUM_PENS (0x1000)
|
||||
|
||||
#define VERBOSE (0)
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video RAM access
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neogeo_state::set_videoram_offset( UINT16 data )
|
||||
{
|
||||
m_vram_offset = (data & 0x8000 ? data & 0x87ff : data);
|
||||
|
||||
/* the read happens right away */
|
||||
m_vram_read_buffer = m_videoram[m_vram_offset];
|
||||
}
|
||||
|
||||
|
||||
UINT16 neogeo_state::get_videoram_data( )
|
||||
{
|
||||
return m_vram_read_buffer;
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::set_videoram_data( UINT16 data)
|
||||
{
|
||||
m_videoram[m_vram_offset] = data;
|
||||
|
||||
/* auto increment/decrement the current offset - A15 is NOT affected */
|
||||
set_videoram_offset((m_vram_offset & 0x8000) | ((m_vram_offset + m_vram_modulo) & 0x7fff));
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::set_videoram_modulo( UINT16 data)
|
||||
{
|
||||
m_vram_modulo = data;
|
||||
}
|
||||
|
||||
|
||||
UINT16 neogeo_state::get_videoram_modulo( )
|
||||
{
|
||||
return m_vram_modulo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -185,519 +143,63 @@ WRITE16_MEMBER(neogeo_state::neogeo_paletteram_w)
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Auto animation
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neogeo_state::set_auto_animation_speed( UINT8 data)
|
||||
void neogeo_state::video_start()
|
||||
{
|
||||
m_auto_animation_speed = data;
|
||||
}
|
||||
/* allocate memory not directly mapped */
|
||||
m_palettes[0] = auto_alloc_array(machine(), UINT16, NUM_PENS);
|
||||
m_palettes[1] = auto_alloc_array(machine(), UINT16, NUM_PENS);
|
||||
m_pens = auto_alloc_array(machine(), pen_t, NUM_PENS);
|
||||
|
||||
compute_rgb_weights();
|
||||
|
||||
void neogeo_state::set_auto_animation_disabled( UINT8 data)
|
||||
{
|
||||
m_auto_animation_disabled = data;
|
||||
}
|
||||
memset(m_palettes[0], 0x00, NUM_PENS * sizeof(UINT16));
|
||||
memset(m_palettes[1], 0x00, NUM_PENS * sizeof(UINT16));
|
||||
memset(m_pens, 0x00, NUM_PENS * sizeof(pen_t));
|
||||
|
||||
save_pointer(NAME(m_palettes[0]), NUM_PENS);
|
||||
save_pointer(NAME(m_palettes[1]), NUM_PENS);
|
||||
save_item(NAME(m_screen_dark));
|
||||
save_item(NAME(m_palette_bank));
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(neogeo_state::regenerate_pens), this));
|
||||
|
||||
UINT8 neogeo_state::neogeo_get_auto_animation_counter( )
|
||||
{
|
||||
return m_auto_animation_counter;
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(neogeo_state::auto_animation_timer_callback)
|
||||
{
|
||||
if (m_auto_animation_frame_counter == 0)
|
||||
{
|
||||
m_auto_animation_frame_counter = m_auto_animation_speed;
|
||||
m_auto_animation_counter += 1;
|
||||
}
|
||||
else
|
||||
m_auto_animation_frame_counter = m_auto_animation_frame_counter - 1;
|
||||
|
||||
m_auto_animation_timer->adjust(m_screen->time_until_pos(NEOGEO_VSSTART));
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::create_auto_animation_timer( )
|
||||
{
|
||||
m_auto_animation_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(neogeo_state::auto_animation_timer_callback),this));
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::start_auto_animation_timer( )
|
||||
{
|
||||
m_auto_animation_timer->adjust(m_screen->time_until_pos(NEOGEO_VSSTART));
|
||||
m_sprgen->set_pens(m_pens);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Fixed layer
|
||||
* Video system reset
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neogeo_state::neogeo_set_fixed_layer_source( UINT8 data )
|
||||
void neogeo_state::video_reset()
|
||||
{
|
||||
m_fixed_layer_source = data;
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::draw_fixed_layer( bitmap_rgb32 &bitmap, int scanline )
|
||||
{
|
||||
int x;
|
||||
|
||||
UINT8* gfx_base = m_fixed_layer_source ? m_region_fixed->base() : m_region_fixedbios->base();
|
||||
UINT32 addr_mask = ( m_fixed_layer_source ? m_region_fixed->bytes() : m_region_fixedbios->bytes() ) - 1;
|
||||
UINT16 *video_data = &m_videoram[0x7000 | (scanline >> 3)];
|
||||
UINT32 *pixel_addr = &bitmap.pix32(scanline, NEOGEO_HBEND);
|
||||
|
||||
int garouoffsets[32];
|
||||
int banked = m_fixed_layer_source && (addr_mask > 0x1ffff);
|
||||
|
||||
/* thanks to Mr K for the garou & kof2000 banking info */
|
||||
/* Build line banking table for Garou & MS3 before starting render */
|
||||
if (banked && m_fixed_layer_bank_type == 1)
|
||||
{
|
||||
int garoubank = 0;
|
||||
int k = 0;
|
||||
int y = 0;
|
||||
while (y < 32)
|
||||
{
|
||||
if (m_videoram[0x7500 + k] == 0x0200 && (m_videoram[0x7580 + k] & 0xff00) == 0xff00)
|
||||
{
|
||||
garoubank = m_videoram[0x7580 + k] & 3;
|
||||
garouoffsets[y++] = garoubank;
|
||||
}
|
||||
garouoffsets[y++] = garoubank;
|
||||
k += 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < 40; x++)
|
||||
{
|
||||
UINT16 code_and_palette = *video_data;
|
||||
UINT16 code = code_and_palette & 0x0fff;
|
||||
|
||||
if (banked)
|
||||
{
|
||||
int y = scanline >> 3;
|
||||
switch (m_fixed_layer_bank_type)
|
||||
{
|
||||
case 1:
|
||||
/* Garou, MSlug 3 */
|
||||
code += 0x1000 * (garouoffsets[(y - 2) & 31] ^ 3);
|
||||
break;
|
||||
case 2:
|
||||
code += 0x1000 * (((m_videoram[0x7500 + ((y - 1) & 31) + 32 * (x / 6)] >> (5 - (x % 6)) * 2) & 3) ^ 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
UINT8 data;
|
||||
int i;
|
||||
|
||||
UINT8 *gfx = &gfx_base[((code << 5) | (scanline & 0x07)) & addr_mask];
|
||||
pen_t *char_pens = &m_pens[code_and_palette >> 12 << 4];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
static const UINT32 pix_offsets[] = { 0x10, 0x18, 0x00, 0x08 };
|
||||
|
||||
data = gfx[pix_offsets[i]];
|
||||
|
||||
if (data & 0x0f)
|
||||
*pixel_addr = char_pens[data & 0x0f];
|
||||
pixel_addr++;
|
||||
|
||||
if (data & 0xf0)
|
||||
*pixel_addr = char_pens[(data & 0xf0) >> 4];
|
||||
pixel_addr++;
|
||||
}
|
||||
}
|
||||
|
||||
video_data = video_data + 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Sprite hardware
|
||||
* Video update
|
||||
*
|
||||
*************************************/
|
||||
|
||||
#define MAX_SPRITES_PER_SCREEN (381)
|
||||
#define MAX_SPRITES_PER_LINE (96)
|
||||
|
||||
|
||||
/* horizontal zoom table - verified on real hardware */
|
||||
static const int zoom_x_tables[][16] =
|
||||
UINT32 neogeo_state::screen_update_neogeo(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
{ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 },
|
||||
{ 0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0 },
|
||||
{ 0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 },
|
||||
{ 0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0 },
|
||||
{ 0,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0 },
|
||||
{ 0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0 },
|
||||
{ 0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0 },
|
||||
{ 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0 },
|
||||
{ 1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0 },
|
||||
{ 1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0 },
|
||||
{ 1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1 },
|
||||
{ 1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,1 },
|
||||
{ 1,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1 },
|
||||
{ 1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1 },
|
||||
{ 1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1 },
|
||||
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }
|
||||
};
|
||||
// fill with background color first
|
||||
bitmap.fill(m_pens[0x0fff], cliprect);
|
||||
|
||||
m_sprgen->draw_sprites(bitmap, cliprect.min_y);
|
||||
|
||||
inline int neogeo_state::rows_to_height(int rows)
|
||||
{
|
||||
if ((rows == 0) || (rows > 0x20))
|
||||
rows = 0x20;
|
||||
m_sprgen->draw_fixed_layer(bitmap, cliprect.min_y);
|
||||
|
||||
return rows * 0x10;
|
||||
}
|
||||
|
||||
|
||||
inline int neogeo_state::sprite_on_scanline(int scanline, int y, int rows)
|
||||
{
|
||||
/* check if the current scanline falls inside this sprite,
|
||||
two possible scenerios, wrap around or not */
|
||||
int max_y = (y + rows_to_height(rows) - 1) & 0x1ff;
|
||||
|
||||
return (((max_y >= y) && (scanline >= y) && (scanline <= max_y)) ||
|
||||
((max_y < y) && ((scanline >= y) || (scanline <= max_y))));
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::draw_sprites( bitmap_rgb32 &bitmap, int scanline )
|
||||
{
|
||||
int sprite_index;
|
||||
int max_sprite_index;
|
||||
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
int rows = 0;
|
||||
int zoom_y = 0;
|
||||
int zoom_x = 0;
|
||||
UINT16 *sprite_list;
|
||||
|
||||
/* select the active list */
|
||||
if (scanline & 0x01)
|
||||
sprite_list = &m_videoram[0x8680];
|
||||
else
|
||||
sprite_list = &m_videoram[0x8600];
|
||||
|
||||
/* optimization -- find last non-zero entry and only draw that many +1
|
||||
sprite. This is not 100% correct as the hardware will keep drawing
|
||||
the #0 sprite over and over, but we need the speed */
|
||||
for (max_sprite_index = (MAX_SPRITES_PER_LINE - 1); max_sprite_index >= 0; max_sprite_index--)
|
||||
{
|
||||
if (sprite_list[max_sprite_index] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* add the +1 now, just in case the 0 at the end is real sprite */
|
||||
if (max_sprite_index != (MAX_SPRITES_PER_LINE - 1))
|
||||
max_sprite_index = max_sprite_index + 1;
|
||||
|
||||
for (sprite_index = 0; sprite_index <= max_sprite_index; sprite_index++)
|
||||
{
|
||||
UINT16 sprite_number = sprite_list[sprite_index] & 0x01ff;
|
||||
UINT16 y_control = m_videoram[0x8200 | sprite_number];
|
||||
UINT16 zoom_control = m_videoram[0x8000 | sprite_number];
|
||||
|
||||
/* if chained, go to next X coordinate and get new X zoom */
|
||||
if (y_control & 0x40)
|
||||
{
|
||||
x = (x + zoom_x + 1) & 0x01ff;
|
||||
zoom_x = (zoom_control >> 8) & 0x0f;
|
||||
}
|
||||
/* new block */
|
||||
else
|
||||
{
|
||||
y = 0x200 - (y_control >> 7);
|
||||
x = m_videoram[0x8400 | sprite_number] >> 7;
|
||||
zoom_y = zoom_control & 0xff;
|
||||
zoom_x = (zoom_control >> 8) & 0x0f;
|
||||
rows = y_control & 0x3f;
|
||||
}
|
||||
|
||||
/* skip if falls completely outside the screen */
|
||||
if ((x >= 0x140) && (x <= 0x1f0))
|
||||
continue;
|
||||
|
||||
/* double check the Y coordinate, in case somebody modified the sprite coordinate
|
||||
since we buffered it */
|
||||
if (sprite_on_scanline(scanline, y, rows))
|
||||
{
|
||||
int sprite_y;
|
||||
int tile;
|
||||
UINT8 sprite_y_and_tile;
|
||||
offs_t attr_and_code_offs;
|
||||
UINT16 attr;
|
||||
UINT32 code;
|
||||
const int *zoom_x_table;
|
||||
UINT8 *gfx;
|
||||
pen_t *line_pens;
|
||||
int x_inc;
|
||||
|
||||
int sprite_line = (scanline - y) & 0x1ff;
|
||||
int zoom_line = sprite_line & 0xff;
|
||||
int invert = sprite_line & 0x100;
|
||||
|
||||
if (invert)
|
||||
zoom_line ^= 0xff;
|
||||
|
||||
if (rows > 0x20)
|
||||
{
|
||||
zoom_line = zoom_line % ((zoom_y + 1) << 1);
|
||||
|
||||
if (zoom_line > zoom_y)
|
||||
{
|
||||
zoom_line = ((zoom_y + 1) << 1) - 1 - zoom_line;
|
||||
invert = !invert;
|
||||
}
|
||||
}
|
||||
|
||||
sprite_y_and_tile = m_region_zoomy[(zoom_y << 8) | zoom_line];
|
||||
sprite_y = sprite_y_and_tile & 0x0f;
|
||||
tile = sprite_y_and_tile >> 4;
|
||||
|
||||
if (invert)
|
||||
{
|
||||
sprite_y ^= 0x0f;
|
||||
tile ^= 0x1f;
|
||||
}
|
||||
|
||||
attr_and_code_offs = (sprite_number << 6) | (tile << 1);
|
||||
attr = m_videoram[attr_and_code_offs + 1];
|
||||
code = ((attr << 12) & 0x70000) | m_videoram[attr_and_code_offs];
|
||||
|
||||
/* substitute auto animation bits */
|
||||
if (!m_auto_animation_disabled)
|
||||
{
|
||||
if (attr & 0x0008)
|
||||
code = (code & ~0x07) | (m_auto_animation_counter & 0x07);
|
||||
else if (attr & 0x0004)
|
||||
code = (code & ~0x03) | (m_auto_animation_counter & 0x03);
|
||||
}
|
||||
|
||||
/* vertical flip? */
|
||||
if (attr & 0x0002)
|
||||
sprite_y ^= 0x0f;
|
||||
|
||||
zoom_x_table = zoom_x_tables[zoom_x];
|
||||
|
||||
/* compute offset in gfx ROM and mask it to the number of bits available */
|
||||
gfx = &m_sprite_gfx[((code << 8) | (sprite_y << 4)) & m_sprite_gfx_address_mask];
|
||||
|
||||
line_pens = &m_pens[attr >> 8 << 4];
|
||||
|
||||
/* horizontal flip? */
|
||||
if (attr & 0x0001)
|
||||
{
|
||||
gfx = gfx + 0x0f;
|
||||
x_inc = -1;
|
||||
}
|
||||
else
|
||||
x_inc = 1;
|
||||
|
||||
/* draw the line - no wrap-around */
|
||||
if (x <= 0x01f0)
|
||||
{
|
||||
int i;
|
||||
|
||||
UINT32 *pixel_addr = &bitmap.pix32(scanline, x + NEOGEO_HBEND);
|
||||
|
||||
for (i = 0; i < 0x10; i++)
|
||||
{
|
||||
if (*zoom_x_table)
|
||||
{
|
||||
if (*gfx)
|
||||
*pixel_addr = line_pens[*gfx];
|
||||
|
||||
pixel_addr++;
|
||||
}
|
||||
|
||||
zoom_x_table++;
|
||||
gfx += x_inc;
|
||||
}
|
||||
}
|
||||
/* wrap-around */
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
int x_save = x;
|
||||
UINT32 *pixel_addr = &bitmap.pix32(scanline, NEOGEO_HBEND);
|
||||
|
||||
for (i = 0; i < 0x10; i++)
|
||||
{
|
||||
if (*zoom_x_table)
|
||||
{
|
||||
if (x >= 0x200)
|
||||
{
|
||||
if (*gfx)
|
||||
*pixel_addr = line_pens[*gfx];
|
||||
|
||||
pixel_addr++;
|
||||
}
|
||||
|
||||
x++;
|
||||
}
|
||||
|
||||
zoom_x_table++;
|
||||
gfx += x_inc;
|
||||
}
|
||||
|
||||
x = x_save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::parse_sprites( int scanline )
|
||||
{
|
||||
UINT16 sprite_number;
|
||||
int y = 0;
|
||||
int rows = 0;
|
||||
UINT16 *sprite_list;
|
||||
|
||||
int active_sprite_count = 0;
|
||||
|
||||
/* select the active list */
|
||||
if (scanline & 0x01)
|
||||
sprite_list = &m_videoram[0x8680];
|
||||
else
|
||||
sprite_list = &m_videoram[0x8600];
|
||||
|
||||
/* scan all sprites */
|
||||
for (sprite_number = 0; sprite_number < MAX_SPRITES_PER_SCREEN; sprite_number++)
|
||||
{
|
||||
UINT16 y_control = m_videoram[0x8200 | sprite_number];
|
||||
|
||||
/* if not chained, get Y position and height, otherwise use previous values */
|
||||
if (~y_control & 0x40)
|
||||
{
|
||||
y = 0x200 - (y_control >> 7);
|
||||
rows = y_control & 0x3f;
|
||||
}
|
||||
|
||||
/* skip sprites with 0 rows */
|
||||
if (rows == 0)
|
||||
continue;
|
||||
|
||||
if (!sprite_on_scanline(scanline, y, rows))
|
||||
continue;
|
||||
|
||||
/* sprite is on this scanline, add it to active list */
|
||||
*sprite_list = sprite_number;
|
||||
|
||||
sprite_list++;
|
||||
|
||||
/* increment sprite count, and if we reached the max, bail out */
|
||||
active_sprite_count++;
|
||||
|
||||
if (active_sprite_count == MAX_SPRITES_PER_LINE)
|
||||
break;
|
||||
}
|
||||
|
||||
/* fill the rest of the sprite list with 0, including one extra entry */
|
||||
memset(sprite_list, 0, sizeof(sprite_list[0]) * (MAX_SPRITES_PER_LINE - active_sprite_count + 1));
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(neogeo_state::sprite_line_timer_callback)
|
||||
{
|
||||
int scanline = param;
|
||||
|
||||
/* we are at the beginning of a scanline -
|
||||
we need to draw the previous scanline and parse the sprites on the current one */
|
||||
if (scanline != 0)
|
||||
m_screen->update_partial(scanline - 1);
|
||||
|
||||
parse_sprites(scanline);
|
||||
|
||||
/* let's come back at the beginning of the next line */
|
||||
scanline = (scanline + 1) % NEOGEO_VTOTAL;
|
||||
|
||||
m_sprite_line_timer->adjust(m_screen->time_until_pos(scanline), scanline);
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::create_sprite_line_timer( )
|
||||
{
|
||||
m_sprite_line_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(neogeo_state::sprite_line_timer_callback),this));
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::start_sprite_line_timer( )
|
||||
{
|
||||
m_sprite_line_timer->adjust(m_screen->time_until_pos(0));
|
||||
}
|
||||
|
||||
|
||||
void neogeo_state::optimize_sprite_data()
|
||||
{
|
||||
/* convert the sprite graphics data into a format that
|
||||
allows faster blitting */
|
||||
UINT8 *src;
|
||||
UINT8 *dest;
|
||||
UINT32 mask;
|
||||
UINT32 len;
|
||||
UINT32 bit;
|
||||
|
||||
/* get mask based on the length rounded up to the nearest
|
||||
power of 2 */
|
||||
mask = 0xffffffff;
|
||||
|
||||
len = m_region_sprites->bytes();
|
||||
|
||||
for (bit = 0x80000000; bit != 0; bit >>= 1)
|
||||
{
|
||||
if ((len * 2 - 1) & bit)
|
||||
break;
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
m_sprite_gfx.resize(mask + 1);
|
||||
m_sprite_gfx_address_mask = mask;
|
||||
|
||||
src = m_region_sprites->base();
|
||||
dest = m_sprite_gfx;
|
||||
|
||||
for (unsigned i = 0; i < len; i += 0x80, src += 0x80)
|
||||
{
|
||||
for (unsigned y = 0; y < 0x10; y++)
|
||||
{
|
||||
for (unsigned x = 0; x < 8; x++)
|
||||
{
|
||||
*(dest++) = (((src[0x43 | (y << 2)] >> x) & 0x01) << 3) |
|
||||
(((src[0x41 | (y << 2)] >> x) & 0x01) << 2) |
|
||||
(((src[0x42 | (y << 2)] >> x) & 0x01) << 1) |
|
||||
(((src[0x40 | (y << 2)] >> x) & 0x01) << 0);
|
||||
}
|
||||
|
||||
for (unsigned x = 0; x < 8; x++)
|
||||
{
|
||||
*(dest++) = (((src[0x03 | (y << 2)] >> x) & 0x01) << 3) |
|
||||
(((src[0x01 | (y << 2)] >> x) & 0x01) << 2) |
|
||||
(((src[0x02 | (y << 2)] >> x) & 0x01) << 1) |
|
||||
(((src[0x00 | (y << 2)] >> x) & 0x01) << 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -740,7 +242,7 @@ UINT16 neogeo_state::get_video_control( )
|
||||
if (v_counter >= 0x200)
|
||||
v_counter = v_counter - NEOGEO_VTOTAL;
|
||||
|
||||
ret = (v_counter << 7) | (neogeo_get_auto_animation_counter() & 0x0007);
|
||||
ret = (v_counter << 7) | (m_sprgen->neogeo_get_auto_animation_counter() & 0x0007);
|
||||
|
||||
if (VERBOSE) logerror("%s: video_control read (%04x)\n", machine().describe_context(), ret);
|
||||
|
||||
@ -752,8 +254,8 @@ void neogeo_state::set_video_control( UINT16 data )
|
||||
{
|
||||
if (VERBOSE) logerror("%s: video control write %04x\n", machine().describe_context(), data);
|
||||
|
||||
set_auto_animation_speed(data >> 8);
|
||||
set_auto_animation_disabled(data & 0x0008);
|
||||
m_sprgen->set_auto_animation_speed(data >> 8);
|
||||
m_sprgen->set_auto_animation_disabled(data & 0x0008);
|
||||
|
||||
neogeo_set_display_position_interrupt_control(data & 0x00f0);
|
||||
}
|
||||
@ -772,8 +274,8 @@ READ16_MEMBER(neogeo_state::neogeo_video_register_r)
|
||||
{
|
||||
default:
|
||||
case 0x00:
|
||||
case 0x01: ret = get_videoram_data(); break;
|
||||
case 0x02: ret = get_videoram_modulo(); break;
|
||||
case 0x01: ret = m_sprgen->get_videoram_data(); break;
|
||||
case 0x02: ret = m_sprgen->get_videoram_modulo(); break;
|
||||
case 0x03: ret = get_video_control(); break;
|
||||
}
|
||||
}
|
||||
@ -793,9 +295,9 @@ WRITE16_MEMBER(neogeo_state::neogeo_video_register_w)
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: set_videoram_offset(data); break;
|
||||
case 0x01: set_videoram_data(data); break;
|
||||
case 0x02: set_videoram_modulo(data); break;
|
||||
case 0x00: m_sprgen->set_videoram_offset(data); break;
|
||||
case 0x01: m_sprgen->set_videoram_data(data); break;
|
||||
case 0x02: m_sprgen->set_videoram_modulo(data); break;
|
||||
case 0x03: set_video_control(data); break;
|
||||
case 0x04: neogeo_set_display_counter_msb(data); break;
|
||||
case 0x05: neogeo_set_display_counter_lsb(data); break;
|
||||
@ -806,93 +308,3 @@ WRITE16_MEMBER(neogeo_state::neogeo_video_register_w)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neogeo_state::video_start()
|
||||
{
|
||||
/* allocate memory not directly mapped */
|
||||
m_palettes[0] = auto_alloc_array(machine(), UINT16, NUM_PENS);
|
||||
m_palettes[1] = auto_alloc_array(machine(), UINT16, NUM_PENS);
|
||||
m_pens = auto_alloc_array(machine(), pen_t, NUM_PENS);
|
||||
m_videoram = auto_alloc_array(machine(), UINT16, 0x8000 + 0x800);
|
||||
|
||||
/* clear allocated memory */
|
||||
memset(m_palettes[0], 0x00, NUM_PENS * sizeof(UINT16));
|
||||
memset(m_palettes[1], 0x00, NUM_PENS * sizeof(UINT16));
|
||||
memset(m_pens, 0x00, NUM_PENS * sizeof(pen_t));
|
||||
memset(m_videoram, 0x00, (0x8000 + 0x800) * sizeof(UINT16));
|
||||
|
||||
compute_rgb_weights();
|
||||
create_sprite_line_timer();
|
||||
create_auto_animation_timer();
|
||||
|
||||
m_sprite_gfx_address_mask = 0;
|
||||
optimize_sprite_data();
|
||||
|
||||
/* initialize values that are not modified on a reset */
|
||||
m_vram_offset = 0;
|
||||
m_vram_read_buffer = 0;
|
||||
m_vram_modulo = 0;
|
||||
m_auto_animation_speed = 0;
|
||||
m_auto_animation_disabled = 0;
|
||||
m_auto_animation_counter = 0;
|
||||
m_auto_animation_frame_counter = 0;
|
||||
|
||||
/* register for state saving */
|
||||
save_pointer(NAME(m_palettes[0]), NUM_PENS);
|
||||
save_pointer(NAME(m_palettes[1]), NUM_PENS);
|
||||
save_pointer(NAME(m_videoram), 0x8000 + 0x800);
|
||||
save_item(NAME(m_vram_offset));
|
||||
save_item(NAME(m_vram_read_buffer));
|
||||
save_item(NAME(m_vram_modulo));
|
||||
save_item(NAME(m_fixed_layer_source));
|
||||
save_item(NAME(m_screen_dark));
|
||||
save_item(NAME(m_palette_bank));
|
||||
save_item(NAME(m_auto_animation_speed));
|
||||
save_item(NAME(m_auto_animation_disabled));
|
||||
save_item(NAME(m_auto_animation_counter));
|
||||
save_item(NAME(m_auto_animation_frame_counter));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(neogeo_state::regenerate_pens), this));
|
||||
|
||||
m_region_zoomy = memregion("zoomy")->base();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system reset
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neogeo_state::video_reset()
|
||||
{
|
||||
start_sprite_line_timer();
|
||||
start_auto_animation_timer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video update
|
||||
*
|
||||
*************************************/
|
||||
|
||||
UINT32 neogeo_state::screen_update_neogeo(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// fill with background color first
|
||||
bitmap.fill(m_pens[0x0fff], cliprect);
|
||||
|
||||
draw_sprites(bitmap, cliprect.min_y);
|
||||
|
||||
draw_fixed_layer(bitmap, cliprect.min_y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
838
src/mame/video/neogeo_spr.c
Normal file
838
src/mame/video/neogeo_spr.c
Normal file
@ -0,0 +1,838 @@
|
||||
/* NeoGeo sprites (and fixed text layer) */
|
||||
|
||||
#include "emu.h"
|
||||
#include "neogeo_spr.h"
|
||||
|
||||
|
||||
// pure virtual functions
|
||||
//const device_type NEOGEO_SPRITE_BASE = &device_creator<neosprite_base_device>;
|
||||
|
||||
/*
|
||||
neosprite_base_device::neosprite_base_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, NEOGEO_SPRITE_BASE, "Neogeo Sprites", tag, owner, clock, "neospritebase", __FILE__),
|
||||
m_bppshift(4)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
neosprite_base_device::neosprite_base_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, device_type type)
|
||||
: device_t(mconfig, type, "Neogeo Sprites", tag, owner, clock, "neosprite", __FILE__),
|
||||
m_bppshift(4)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void neosprite_base_device::device_start()
|
||||
{
|
||||
|
||||
m_videoram = auto_alloc_array(machine(), UINT16, 0x8000 + 0x800);
|
||||
m_videoram_drawsource = m_videoram;
|
||||
|
||||
/* clear allocated memory */
|
||||
memset(m_videoram, 0x00, (0x8000 + 0x800) * sizeof(UINT16));
|
||||
|
||||
create_sprite_line_timer();
|
||||
create_auto_animation_timer();
|
||||
|
||||
|
||||
|
||||
/* initialize values that are not modified on a reset */
|
||||
m_vram_offset = 0;
|
||||
m_vram_read_buffer = 0;
|
||||
m_vram_modulo = 0;
|
||||
m_auto_animation_speed = 0;
|
||||
m_auto_animation_disabled = 0;
|
||||
m_auto_animation_counter = 0;
|
||||
m_auto_animation_frame_counter = 0;
|
||||
|
||||
/* register for state saving */
|
||||
save_pointer(NAME(m_videoram), 0x8000 + 0x800);
|
||||
save_item(NAME(m_vram_offset));
|
||||
save_item(NAME(m_vram_read_buffer));
|
||||
save_item(NAME(m_vram_modulo));
|
||||
save_item(NAME(m_fixed_layer_source));
|
||||
|
||||
save_item(NAME(m_auto_animation_speed));
|
||||
save_item(NAME(m_auto_animation_disabled));
|
||||
save_item(NAME(m_auto_animation_counter));
|
||||
save_item(NAME(m_auto_animation_frame_counter));
|
||||
|
||||
|
||||
m_region_zoomy = memregion(":zoomy")->base();
|
||||
}
|
||||
|
||||
void neosprite_base_device::device_reset()
|
||||
{
|
||||
//m_sprite_gfx_address_mask = 0;
|
||||
optimize_sprite_data();
|
||||
|
||||
start_sprite_line_timer();
|
||||
start_auto_animation_timer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video RAM access
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neosprite_base_device::set_videoram_offset( UINT16 data )
|
||||
{
|
||||
m_vram_offset = (data & 0x8000 ? data & 0x87ff : data);
|
||||
|
||||
/* the read happens right away */
|
||||
m_vram_read_buffer = m_videoram[m_vram_offset];
|
||||
}
|
||||
|
||||
|
||||
UINT16 neosprite_base_device::get_videoram_data( )
|
||||
{
|
||||
return m_vram_read_buffer;
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::set_videoram_data( UINT16 data)
|
||||
{
|
||||
m_videoram[m_vram_offset] = data;
|
||||
|
||||
/* auto increment/decrement the current offset - A15 is NOT affected */
|
||||
set_videoram_offset((m_vram_offset & 0x8000) | ((m_vram_offset + m_vram_modulo) & 0x7fff));
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::set_videoram_modulo( UINT16 data)
|
||||
{
|
||||
m_vram_modulo = data;
|
||||
}
|
||||
|
||||
|
||||
UINT16 neosprite_base_device::get_videoram_modulo( )
|
||||
{
|
||||
return m_vram_modulo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Auto animation
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neosprite_base_device::set_auto_animation_speed( UINT8 data)
|
||||
{
|
||||
m_auto_animation_speed = data;
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::set_auto_animation_disabled( UINT8 data)
|
||||
{
|
||||
m_auto_animation_disabled = data;
|
||||
}
|
||||
|
||||
|
||||
UINT8 neosprite_base_device::neogeo_get_auto_animation_counter( )
|
||||
{
|
||||
return m_auto_animation_counter;
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(neosprite_base_device::auto_animation_timer_callback)
|
||||
{
|
||||
if (m_auto_animation_frame_counter == 0)
|
||||
{
|
||||
m_auto_animation_frame_counter = m_auto_animation_speed;
|
||||
m_auto_animation_counter += 1;
|
||||
}
|
||||
else
|
||||
m_auto_animation_frame_counter = m_auto_animation_frame_counter - 1;
|
||||
|
||||
m_auto_animation_timer->adjust(m_screen->time_until_pos(NEOGEO_VSSTART));
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::create_auto_animation_timer( )
|
||||
{
|
||||
m_auto_animation_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(neosprite_base_device::auto_animation_timer_callback),this));
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::start_auto_animation_timer( )
|
||||
{
|
||||
m_auto_animation_timer->adjust(m_screen->time_until_pos(NEOGEO_VSSTART));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Fixed layer
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void neosprite_base_device::neogeo_set_fixed_layer_source( UINT8 data )
|
||||
{
|
||||
m_fixed_layer_source = data;
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::draw_fixed_layer( bitmap_rgb32 &bitmap, int scanline )
|
||||
{
|
||||
int x;
|
||||
|
||||
UINT8* gfx_base = m_fixed_layer_source ? m_region_fixed->base() : m_region_fixedbios->base();
|
||||
UINT32 addr_mask = ( m_fixed_layer_source ? m_region_fixed->bytes() : m_region_fixedbios->bytes() ) - 1;
|
||||
UINT16 *video_data = &m_videoram_drawsource[0x7000 | (scanline >> 3)];
|
||||
UINT32 *pixel_addr = &bitmap.pix32(scanline, NEOGEO_HBEND);
|
||||
|
||||
int garouoffsets[32];
|
||||
int banked = m_fixed_layer_source && (addr_mask > 0x1ffff);
|
||||
|
||||
/* thanks to Mr K for the garou & kof2000 banking info */
|
||||
/* Build line banking table for Garou & MS3 before starting render */
|
||||
if (banked && m_fixed_layer_bank_type == 1)
|
||||
{
|
||||
int garoubank = 0;
|
||||
int k = 0;
|
||||
int y = 0;
|
||||
while (y < 32)
|
||||
{
|
||||
if (m_videoram_drawsource[0x7500 + k] == 0x0200 && (m_videoram_drawsource[0x7580 + k] & 0xff00) == 0xff00)
|
||||
{
|
||||
garoubank = m_videoram_drawsource[0x7580 + k] & 3;
|
||||
garouoffsets[y++] = garoubank;
|
||||
}
|
||||
garouoffsets[y++] = garoubank;
|
||||
k += 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < 40; x++)
|
||||
{
|
||||
UINT16 code_and_palette = *video_data;
|
||||
UINT16 code = code_and_palette & 0x0fff;
|
||||
|
||||
if (banked)
|
||||
{
|
||||
int y = scanline >> 3;
|
||||
switch (m_fixed_layer_bank_type)
|
||||
{
|
||||
case 1:
|
||||
/* Garou, MSlug 3 */
|
||||
code += 0x1000 * (garouoffsets[(y - 2) & 31] ^ 3);
|
||||
break;
|
||||
case 2:
|
||||
code += 0x1000 * (((m_videoram_drawsource[0x7500 + ((y - 1) & 31) + 32 * (x / 6)] >> (5 - (x % 6)) * 2) & 3) ^ 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
int gfx_offset = ((code << 5) | (scanline & 0x07)) & addr_mask;
|
||||
|
||||
pen_t *char_pens;
|
||||
|
||||
char_pens = &m_pens[code_and_palette >> 12 << m_bppshift];
|
||||
|
||||
|
||||
static const UINT32 pix_offsets[] = { 0x10, 0x18, 0x00, 0x08 };
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
draw_fixed_layer_2pixels(pixel_addr, gfx_offset + pix_offsets[i], gfx_base, char_pens);
|
||||
}
|
||||
}
|
||||
|
||||
video_data = video_data + 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void neosprite_base_device::draw_fixed_layer_2pixels(UINT32*&pixel_addr, int offset, UINT8* gfx_base, pen_t* char_pens)
|
||||
{
|
||||
UINT8 data = gfx_base[offset];
|
||||
|
||||
if (data & 0x0f)
|
||||
*pixel_addr = char_pens[data & 0x0f];
|
||||
pixel_addr++;
|
||||
|
||||
if (data & 0xf0)
|
||||
*pixel_addr = char_pens[(data & 0xf0) >> 4];
|
||||
pixel_addr++;
|
||||
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Sprite hardware
|
||||
*
|
||||
*************************************/
|
||||
|
||||
#define MAX_SPRITES_PER_SCREEN (381)
|
||||
#define MAX_SPRITES_PER_LINE (96)
|
||||
|
||||
|
||||
/* horizontal zoom table - verified on real hardware */
|
||||
static const int zoom_x_tables[][16] =
|
||||
{
|
||||
{ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 },
|
||||
{ 0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0 },
|
||||
{ 0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 },
|
||||
{ 0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0 },
|
||||
{ 0,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0 },
|
||||
{ 0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0 },
|
||||
{ 0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0 },
|
||||
{ 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0 },
|
||||
{ 1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0 },
|
||||
{ 1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0 },
|
||||
{ 1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1 },
|
||||
{ 1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,1 },
|
||||
{ 1,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1 },
|
||||
{ 1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1 },
|
||||
{ 1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1 },
|
||||
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }
|
||||
};
|
||||
|
||||
|
||||
inline int neosprite_base_device::rows_to_height(int rows)
|
||||
{
|
||||
if ((rows == 0) || (rows > 0x20))
|
||||
rows = 0x20;
|
||||
|
||||
return rows * 0x10;
|
||||
}
|
||||
|
||||
|
||||
inline int neosprite_base_device::sprite_on_scanline(int scanline, int y, int rows)
|
||||
{
|
||||
/* check if the current scanline falls inside this sprite,
|
||||
two possible scenerios, wrap around or not */
|
||||
int max_y = (y + rows_to_height(rows) - 1) & 0x1ff;
|
||||
|
||||
return (((max_y >= y) && (scanline >= y) && (scanline <= max_y)) ||
|
||||
((max_y < y) && ((scanline >= y) || (scanline <= max_y))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void neosprite_base_device::draw_sprites( bitmap_rgb32 &bitmap, int scanline )
|
||||
{
|
||||
int sprite_index;
|
||||
int max_sprite_index;
|
||||
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
int rows = 0;
|
||||
int zoom_y = 0;
|
||||
int zoom_x = 0;
|
||||
UINT16 *sprite_list;
|
||||
|
||||
/* select the active list */
|
||||
if (scanline & 0x01)
|
||||
sprite_list = &m_videoram_drawsource[0x8680];
|
||||
else
|
||||
sprite_list = &m_videoram_drawsource[0x8600];
|
||||
|
||||
/* optimization -- find last non-zero entry and only draw that many +1
|
||||
sprite. This is not 100% correct as the hardware will keep drawing
|
||||
the #0 sprite over and over, but we need the speed */
|
||||
for (max_sprite_index = (MAX_SPRITES_PER_LINE - 1); max_sprite_index >= 0; max_sprite_index--)
|
||||
{
|
||||
if (sprite_list[max_sprite_index] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* add the +1 now, just in case the 0 at the end is real sprite */
|
||||
if (max_sprite_index != (MAX_SPRITES_PER_LINE - 1))
|
||||
max_sprite_index = max_sprite_index + 1;
|
||||
|
||||
for (sprite_index = 0; sprite_index <= max_sprite_index; sprite_index++)
|
||||
{
|
||||
UINT16 sprite_number = sprite_list[sprite_index] & 0x01ff;
|
||||
UINT16 y_control = m_videoram_drawsource[0x8200 | sprite_number];
|
||||
UINT16 zoom_control = m_videoram_drawsource[0x8000 | sprite_number];
|
||||
|
||||
/* if chained, go to next X coordinate and get new X zoom */
|
||||
if (y_control & 0x40)
|
||||
{
|
||||
x = (x + zoom_x + 1) & 0x01ff;
|
||||
zoom_x = (zoom_control >> 8) & 0x0f;
|
||||
}
|
||||
/* new block */
|
||||
else
|
||||
{
|
||||
y = 0x200 - (y_control >> 7);
|
||||
x = m_videoram_drawsource[0x8400 | sprite_number] >> 7;
|
||||
|
||||
zoom_y = (zoom_control & 0xff);
|
||||
|
||||
zoom_x = (zoom_control >> 8) & 0x0f;
|
||||
rows = y_control & 0x3f;
|
||||
}
|
||||
|
||||
/* skip if falls completely outside the screen */
|
||||
if ((x >= 0x140) && (x <= 0x1f0))
|
||||
continue;
|
||||
|
||||
/* double check the Y coordinate, in case somebody modified the sprite coordinate
|
||||
since we buffered it */
|
||||
if (sprite_on_scanline(scanline, y, rows))
|
||||
{
|
||||
int sprite_y;
|
||||
int tile;
|
||||
UINT8 sprite_y_and_tile;
|
||||
offs_t attr_and_code_offs;
|
||||
UINT16 attr;
|
||||
UINT32 code;
|
||||
const int *zoom_x_table;
|
||||
pen_t *line_pens;
|
||||
int x_inc;
|
||||
|
||||
int sprite_line = (scanline - y) & 0x1ff;
|
||||
int zoom_line = sprite_line & 0xff;
|
||||
int invert = sprite_line & 0x100;
|
||||
|
||||
if (invert)
|
||||
zoom_line ^= 0xff;
|
||||
|
||||
if (rows > 0x20)
|
||||
{
|
||||
zoom_line = zoom_line % ((zoom_y + 1) << 1);
|
||||
|
||||
if (zoom_line > zoom_y)
|
||||
{
|
||||
zoom_line = ((zoom_y + 1) << 1) - 1 - zoom_line;
|
||||
invert = !invert;
|
||||
}
|
||||
}
|
||||
|
||||
sprite_y_and_tile = m_region_zoomy[(zoom_y << 8) | zoom_line];
|
||||
|
||||
sprite_y = sprite_y_and_tile & 0x0f;
|
||||
tile = sprite_y_and_tile >> 4;
|
||||
|
||||
if (invert)
|
||||
{
|
||||
sprite_y ^= 0x0f;
|
||||
tile ^= 0x1f;
|
||||
}
|
||||
|
||||
attr_and_code_offs = (sprite_number << 6) | (tile << 1);
|
||||
attr = m_videoram_drawsource[attr_and_code_offs + 1];
|
||||
code = ((attr << 12) & 0x70000) | m_videoram_drawsource[attr_and_code_offs];
|
||||
|
||||
/* substitute auto animation bits */
|
||||
if (!m_auto_animation_disabled)
|
||||
{
|
||||
if (attr & 0x0008)
|
||||
code = (code & ~0x07) | (m_auto_animation_counter & 0x07);
|
||||
else if (attr & 0x0004)
|
||||
code = (code & ~0x03) | (m_auto_animation_counter & 0x03);
|
||||
}
|
||||
|
||||
/* vertical flip? */
|
||||
if (attr & 0x0002)
|
||||
sprite_y ^= 0x0f;
|
||||
|
||||
zoom_x_table = zoom_x_tables[zoom_x];
|
||||
|
||||
/* compute offset in gfx ROM and mask it to the number of bits available */
|
||||
int gfx_base = ((code << 8) | (sprite_y << 4)) & m_sprite_gfx_address_mask;
|
||||
|
||||
|
||||
line_pens = &m_pens[attr >> 8 << m_bppshift];
|
||||
|
||||
|
||||
/* horizontal flip? */
|
||||
if (attr & 0x0001)
|
||||
{
|
||||
gfx_base = gfx_base + 0x0f;
|
||||
x_inc = -1;
|
||||
}
|
||||
else
|
||||
x_inc = 1;
|
||||
|
||||
/* draw the line - no wrap-around */
|
||||
if (x <= 0x01f0)
|
||||
{
|
||||
int i;
|
||||
|
||||
UINT32 *pixel_addr = &bitmap.pix32(scanline, x + NEOGEO_HBEND);
|
||||
|
||||
for (i = 0; i < 0x10; i++)
|
||||
{
|
||||
if (*zoom_x_table)
|
||||
{
|
||||
draw_pixel(gfx_base, pixel_addr, line_pens);
|
||||
|
||||
pixel_addr++;
|
||||
}
|
||||
|
||||
zoom_x_table++;
|
||||
gfx_base += x_inc;
|
||||
}
|
||||
}
|
||||
/* wrap-around */
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
int x_save = x;
|
||||
UINT32 *pixel_addr = &bitmap.pix32(scanline, NEOGEO_HBEND);
|
||||
|
||||
for (i = 0; i < 0x10; i++)
|
||||
{
|
||||
if (*zoom_x_table)
|
||||
{
|
||||
if (x >= 0x200)
|
||||
{
|
||||
draw_pixel(gfx_base, pixel_addr, line_pens);
|
||||
|
||||
pixel_addr++;
|
||||
}
|
||||
|
||||
x++;
|
||||
}
|
||||
|
||||
zoom_x_table++;
|
||||
gfx_base += x_inc;
|
||||
}
|
||||
|
||||
x = x_save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::parse_sprites( int scanline )
|
||||
{
|
||||
UINT16 sprite_number;
|
||||
int y = 0;
|
||||
int rows = 0;
|
||||
UINT16 *sprite_list;
|
||||
|
||||
int active_sprite_count = 0;
|
||||
|
||||
/* select the active list */
|
||||
if (scanline & 0x01)
|
||||
sprite_list = &m_videoram_drawsource[0x8680];
|
||||
else
|
||||
sprite_list = &m_videoram_drawsource[0x8600];
|
||||
|
||||
/* scan all sprites */
|
||||
for (sprite_number = 0; sprite_number < MAX_SPRITES_PER_SCREEN; sprite_number++)
|
||||
{
|
||||
UINT16 y_control = m_videoram_drawsource[0x8200 | sprite_number];
|
||||
|
||||
/* if not chained, get Y position and height, otherwise use previous values */
|
||||
if (~y_control & 0x40)
|
||||
{
|
||||
y = 0x200 - (y_control >> 7);
|
||||
rows = y_control & 0x3f;
|
||||
}
|
||||
|
||||
/* skip sprites with 0 rows */
|
||||
if (rows == 0)
|
||||
continue;
|
||||
|
||||
if (!sprite_on_scanline(scanline, y, rows))
|
||||
continue;
|
||||
|
||||
/* sprite is on this scanline, add it to active list */
|
||||
*sprite_list = sprite_number;
|
||||
|
||||
sprite_list++;
|
||||
|
||||
/* increment sprite count, and if we reached the max, bail out */
|
||||
active_sprite_count++;
|
||||
|
||||
if (active_sprite_count == MAX_SPRITES_PER_LINE)
|
||||
break;
|
||||
}
|
||||
|
||||
/* fill the rest of the sprite list with 0, including one extra entry */
|
||||
memset(sprite_list, 0, sizeof(sprite_list[0]) * (MAX_SPRITES_PER_LINE - active_sprite_count + 1));
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(neosprite_base_device::sprite_line_timer_callback)
|
||||
{
|
||||
int scanline = param;
|
||||
|
||||
/* we are at the beginning of a scanline -
|
||||
we need to draw the previous scanline and parse the sprites on the current one */
|
||||
if (scanline != 0)
|
||||
m_screen->update_partial(scanline - 1);
|
||||
|
||||
parse_sprites(scanline);
|
||||
|
||||
/* let's come back at the beginning of the next line */
|
||||
scanline = (scanline + 1) % NEOGEO_VTOTAL;
|
||||
|
||||
m_sprite_line_timer->adjust(m_screen->time_until_pos(scanline), scanline);
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::create_sprite_line_timer( )
|
||||
{
|
||||
m_sprite_line_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(neosprite_base_device::sprite_line_timer_callback),this));
|
||||
}
|
||||
|
||||
|
||||
void neosprite_base_device::start_sprite_line_timer( )
|
||||
{
|
||||
m_sprite_line_timer->adjust(m_screen->time_until_pos(0));
|
||||
}
|
||||
|
||||
|
||||
UINT32 neosprite_base_device::get_region_mask(memory_region* rgn)
|
||||
{
|
||||
/* convert the sprite graphics data into a format that
|
||||
allows faster blitting */
|
||||
UINT32 mask;
|
||||
UINT32 len;
|
||||
UINT32 bit;
|
||||
|
||||
/* get mask based on the length rounded up to the nearest
|
||||
power of 2 */
|
||||
mask = 0xffffffff;
|
||||
|
||||
len = rgn->bytes();
|
||||
|
||||
for (bit = 0x80000000; bit != 0; bit >>= 1)
|
||||
{
|
||||
if ((len * 2 - 1) & bit)
|
||||
break;
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
void neosprite_base_device::optimize_sprite_data()
|
||||
{
|
||||
// this does nothing in this implementation, it's used by neosprite_optimized_device
|
||||
// m_sprite_gfx_address_mask gets set when the GFX region is assigned
|
||||
return;
|
||||
}
|
||||
|
||||
// these are for passing in pointers from the main system
|
||||
void neosprite_base_device::set_sprite_region(memory_region* region_sprites)
|
||||
{
|
||||
m_region_sprites = region_sprites;
|
||||
}
|
||||
|
||||
void neosprite_base_device::set_fixed_regions(memory_region* fix_cart, memory_region* fix_bios)
|
||||
{
|
||||
m_region_fixed = fix_cart;
|
||||
m_region_fixedbios = fix_bios;
|
||||
}
|
||||
|
||||
void neosprite_base_device::set_screen(screen_device* screen)
|
||||
{
|
||||
m_screen = screen;
|
||||
}
|
||||
|
||||
void neosprite_base_device::set_pens(pen_t* pens)
|
||||
{
|
||||
m_pens = pens;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************************************************/
|
||||
/* Regular NeoGeo sprite handling - drawing directly from ROM (or RAM on NeoCD) */
|
||||
/* */
|
||||
/* note, we don't currently use this implementation, reference only */
|
||||
/* if we do it will be important to ensure that all sprite regions are ^2 sizes - the optimized routine automatically allocates */
|
||||
/* ^2 sized regions when pre-decoding, but obviously we don't here, so if we want to be safe we'll have to adjust the actual */
|
||||
/* regions (alternatively I could add an additional size check in the draw routine, but that would be slower) */
|
||||
/*********************************************************************************************************************************/
|
||||
|
||||
const device_type NEOGEO_SPRITE_REGULAR = &device_creator<neosprite_regular_device>;
|
||||
|
||||
neosprite_regular_device::neosprite_regular_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: neosprite_base_device(mconfig, tag, owner, clock, NEOGEO_SPRITE_REGULAR)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void neosprite_regular_device::set_sprite_region(memory_region* region_sprites)
|
||||
{
|
||||
m_region_sprites = region_sprites;
|
||||
|
||||
UINT32 mask = get_region_mask(m_region_sprites);
|
||||
UINT32 proper_size = (mask + 1) >>1;
|
||||
|
||||
printf("lengths %08x %08x m_region_sprites", m_region_sprites->bytes(), proper_size);
|
||||
|
||||
if (m_region_sprites->bytes() != proper_size)
|
||||
{
|
||||
fatalerror("please use power of 2 region sizes with neosprite_base_device to ensure masking works correctly");
|
||||
}
|
||||
|
||||
m_sprite_gfx_address_mask = mask;
|
||||
}
|
||||
|
||||
inline void neosprite_regular_device::draw_pixel(int romaddr, UINT32* dst, pen_t *line_pens)
|
||||
{
|
||||
const UINT8* src = m_region_sprites->base() + (((romaddr &~0xff)>>1) | (((romaddr&0x8)^0x8)<<3) | ((romaddr & 0xf0) >> 2));
|
||||
const int x = romaddr & 0x7;
|
||||
|
||||
const UINT8 gfx = (((src[0x3] >> x) & 0x01) << 3) |
|
||||
(((src[0x1] >> x) & 0x01) << 2) |
|
||||
(((src[0x2] >> x) & 0x01) << 1) |
|
||||
(((src[0x0] >> x) & 0x01) << 0);
|
||||
|
||||
if (gfx)
|
||||
*dst = line_pens[gfx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************************************************/
|
||||
/* Regular NeoGeo sprite handling with pre-decode optimization */
|
||||
/* */
|
||||
/* this is closer to the old MAME implementation where the 4bpp graphics have been expanded to an easier to draw 8bpp format */
|
||||
/* for additional speed */
|
||||
/*********************************************************************************************************************************/
|
||||
|
||||
const device_type NEOGEO_SPRITE_OPTIMZIED = &device_creator<neosprite_optimized_device>;
|
||||
|
||||
neosprite_optimized_device::neosprite_optimized_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: neosprite_base_device(mconfig, tag, owner, clock, NEOGEO_SPRITE_OPTIMZIED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void neosprite_optimized_device::optimize_sprite_data()
|
||||
{
|
||||
/* convert the sprite graphics data into a format that
|
||||
allows faster blitting */
|
||||
UINT8 *src;
|
||||
UINT8 *dest;
|
||||
|
||||
UINT32 mask = get_region_mask(m_region_sprites);
|
||||
|
||||
m_sprite_gfx.resize(mask + 1);
|
||||
m_sprite_gfx_address_mask = mask;
|
||||
|
||||
src = m_region_sprites->base();
|
||||
dest = m_sprite_gfx;
|
||||
|
||||
for (unsigned i = 0; i < m_region_sprites->bytes(); i += 0x80, src += 0x80)
|
||||
{
|
||||
for (unsigned y = 0; y < 0x10; y++)
|
||||
{
|
||||
for (unsigned x = 0; x < 8; x++)
|
||||
{
|
||||
*(dest++) = (((src[0x43 | (y << 2)] >> x) & 0x01) << 3) |
|
||||
(((src[0x41 | (y << 2)] >> x) & 0x01) << 2) |
|
||||
(((src[0x42 | (y << 2)] >> x) & 0x01) << 1) |
|
||||
(((src[0x40 | (y << 2)] >> x) & 0x01) << 0);
|
||||
}
|
||||
|
||||
for (unsigned x = 0; x < 8; x++)
|
||||
{
|
||||
*(dest++) = (((src[0x03 | (y << 2)] >> x) & 0x01) << 3) |
|
||||
(((src[0x01 | (y << 2)] >> x) & 0x01) << 2) |
|
||||
(((src[0x02 | (y << 2)] >> x) & 0x01) << 1) |
|
||||
(((src[0x00 | (y << 2)] >> x) & 0x01) << 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void neosprite_optimized_device::draw_pixel(int romaddr, UINT32* dst, pen_t *line_pens)
|
||||
{
|
||||
const UINT8 gfx = m_sprite_gfx[romaddr];
|
||||
|
||||
if (gfx)
|
||||
*dst = line_pens[gfx];
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************************************************/
|
||||
/* MIDAS specific sprite handling */
|
||||
/* */
|
||||
/* this is used by the midas.c hardware which is a reengineered NeoGeo, it has 8bbp tiles instead of 4bpp tiles */
|
||||
/* and uploads the zoom table. The additional videoram buffering is a guess because 'hammer' is very glitchy without it */
|
||||
/*********************************************************************************************************************************/
|
||||
|
||||
const device_type NEOGEO_SPRITE_MIDAS = &device_creator<neosprite_midas_device>;
|
||||
|
||||
|
||||
neosprite_midas_device::neosprite_midas_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: neosprite_base_device(mconfig, tag, owner, clock, NEOGEO_SPRITE_MIDAS)
|
||||
{
|
||||
m_bppshift = 8;
|
||||
}
|
||||
|
||||
|
||||
inline void neosprite_midas_device::draw_pixel(int romaddr, UINT32* dst, pen_t *line_pens)
|
||||
{
|
||||
const UINT8* src = m_region_sprites->base() + (((romaddr &~0xff)) | (((romaddr&0x8)^0x8)<<4) | ((romaddr & 0xf0) >> 1));
|
||||
const int x = romaddr & 0x7;
|
||||
|
||||
const UINT8 gfx =
|
||||
(((src[0x7] >> x) & 0x01) << 7) |
|
||||
(((src[0x3] >> x) & 0x01) << 6) |
|
||||
(((src[0x6] >> x) & 0x01) << 5) |
|
||||
(((src[0x2] >> x) & 0x01) << 4) |
|
||||
(((src[0x5] >> x) & 0x01) << 3) |
|
||||
(((src[0x1] >> x) & 0x01) << 2) |
|
||||
(((src[0x4] >> x) & 0x01) << 1) |
|
||||
(((src[0x0] >> x) & 0x01) << 0);
|
||||
|
||||
if (gfx)
|
||||
*dst = line_pens[gfx];
|
||||
}
|
||||
|
||||
|
||||
void neosprite_midas_device::device_start()
|
||||
{
|
||||
neosprite_base_device::device_start();
|
||||
|
||||
m_videoram_buffer = auto_alloc_array(machine(), UINT16, 0x8000 + 0x800);
|
||||
m_videoram_drawsource = m_videoram_buffer;
|
||||
|
||||
memset(m_videoram_buffer, 0x00, (0x8000 + 0x800) * sizeof(UINT16));
|
||||
|
||||
}
|
||||
|
||||
void neosprite_midas_device::buffer_vram()
|
||||
{
|
||||
memcpy(m_videoram_buffer, m_videoram, (0x8000 + 0x800) * sizeof(UINT16));
|
||||
}
|
||||
|
||||
inline void neosprite_midas_device::draw_fixed_layer_2pixels(UINT32*&pixel_addr, int offset, UINT8* gfx_base, pen_t* char_pens)
|
||||
{
|
||||
UINT8 data;
|
||||
|
||||
data = ((gfx_base[(offset * 2)+0] & 0x0f)<<0) | ((gfx_base[(offset * 2)+1] & 0x0f)<<4);
|
||||
if (data)
|
||||
*pixel_addr = char_pens[data];
|
||||
pixel_addr++;
|
||||
|
||||
data = ((gfx_base[(offset * 2)+0] & 0xf0)>>4) | ((gfx_base[(offset * 2)+1] & 0xf0)<<0);
|
||||
if (data)
|
||||
*pixel_addr = char_pens[data];
|
||||
pixel_addr++;
|
||||
}
|
||||
|
||||
void neosprite_midas_device::set_sprite_region(memory_region* region_sprites)
|
||||
{
|
||||
m_region_sprites = region_sprites;
|
||||
UINT32 mask = get_region_mask(m_region_sprites);
|
||||
m_sprite_gfx_address_mask = mask;
|
||||
}
|
||||
|
143
src/mame/video/neogeo_spr.h
Normal file
143
src/mame/video/neogeo_spr.h
Normal file
@ -0,0 +1,143 @@
|
||||
|
||||
#define VERBOSE (0)
|
||||
|
||||
// todo, move these back, currently the sprite code needs some of the values tho
|
||||
#define NEOGEO_MASTER_CLOCK (24000000)
|
||||
#define NEOGEO_MAIN_CPU_CLOCK (NEOGEO_MASTER_CLOCK / 2)
|
||||
#define NEOGEO_AUDIO_CPU_CLOCK (NEOGEO_MASTER_CLOCK / 6)
|
||||
#define NEOGEO_YM2610_CLOCK (NEOGEO_MASTER_CLOCK / 3)
|
||||
#define NEOGEO_PIXEL_CLOCK (NEOGEO_MASTER_CLOCK / 4)
|
||||
#define NEOGEO_HTOTAL (0x180)
|
||||
#define NEOGEO_HBEND (0x01e) /* this should really be 29.5 */
|
||||
#define NEOGEO_HBSTART (0x15e) /* this should really be 349.5 */
|
||||
#define NEOGEO_VTOTAL (0x108)
|
||||
#define NEOGEO_VBEND (0x010)
|
||||
#define NEOGEO_VBSTART (0x0f0)
|
||||
#define NEOGEO_VSSTART (0x100)
|
||||
|
||||
// todo, sort out what needs to be public and make the rest private/protected
|
||||
class neosprite_base_device : public device_t
|
||||
{
|
||||
public:
|
||||
neosprite_base_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, device_type type);
|
||||
// neosprite_base_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void optimize_sprite_data();
|
||||
virtual void draw_fixed_layer_2pixels(UINT32*&pixel_addr, int offset, UINT8* gfx_base, pen_t* char_pens);
|
||||
void draw_fixed_layer( bitmap_rgb32 &bitmap, int scanline );
|
||||
void set_videoram_offset( UINT16 data );
|
||||
UINT16 get_videoram_data( );
|
||||
void set_videoram_data( UINT16 data);
|
||||
void set_videoram_modulo( UINT16 data);
|
||||
UINT16 get_videoram_modulo( );
|
||||
void set_auto_animation_speed( UINT8 data);
|
||||
void set_auto_animation_disabled( UINT8 data);
|
||||
UINT8 neogeo_get_auto_animation_counter( );
|
||||
void create_auto_animation_timer( );
|
||||
void start_auto_animation_timer( );
|
||||
void neogeo_set_fixed_layer_source( UINT8 data );
|
||||
inline int rows_to_height(int rows);
|
||||
inline int sprite_on_scanline(int scanline, int y, int rows);
|
||||
virtual void draw_pixel(int romaddr, UINT32* dst, pen_t *line_pens) = 0;
|
||||
void draw_sprites( bitmap_rgb32 &bitmap, int scanline );
|
||||
void parse_sprites( int scanline );
|
||||
void create_sprite_line_timer( );
|
||||
void start_sprite_line_timer( );
|
||||
virtual void set_sprite_region(memory_region* region_sprites);
|
||||
void set_fixed_regions(memory_region* fix_cart, memory_region* fix_bios);
|
||||
void set_screen(screen_device* screen);
|
||||
void set_pens(pen_t* pens);
|
||||
|
||||
UINT16 *m_videoram;
|
||||
UINT16 *m_videoram_drawsource;
|
||||
|
||||
UINT16 m_vram_offset;
|
||||
UINT16 m_vram_read_buffer;
|
||||
UINT16 m_vram_modulo;
|
||||
|
||||
const UINT8 *m_region_zoomy;
|
||||
|
||||
UINT32 m_sprite_gfx_address_mask;
|
||||
|
||||
UINT8 m_auto_animation_speed;
|
||||
UINT8 m_auto_animation_disabled;
|
||||
UINT8 m_auto_animation_counter;
|
||||
UINT8 m_auto_animation_frame_counter;
|
||||
|
||||
UINT8 m_fixed_layer_source;
|
||||
UINT8 m_fixed_layer_bank_type;
|
||||
|
||||
emu_timer *m_auto_animation_timer;
|
||||
emu_timer *m_sprite_line_timer;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(auto_animation_timer_callback);
|
||||
TIMER_CALLBACK_MEMBER(sprite_line_timer_callback);
|
||||
|
||||
|
||||
int m_bppshift; // 4 for 4bpp gfx (NeoGeo) 8 for 8bpp gfx (Midas)
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
UINT32 get_region_mask(memory_region* rgn);
|
||||
memory_region* m_region_sprites;
|
||||
memory_region* m_region_fixed;
|
||||
memory_region* m_region_fixedbios;
|
||||
screen_device* m_screen;
|
||||
pen_t *m_pens;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//extern const device_type NEOGEO_SPRITE_BASE;
|
||||
|
||||
|
||||
class neosprite_regular_device : public neosprite_base_device
|
||||
{
|
||||
public:
|
||||
neosprite_regular_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual void draw_pixel(int romaddr, UINT32* dst, pen_t *line_pens);
|
||||
virtual void set_sprite_region(memory_region* region_sprites);
|
||||
|
||||
};
|
||||
|
||||
extern const device_type NEOGEO_SPRITE_REGULAR;
|
||||
|
||||
|
||||
class neosprite_optimized_device : public neosprite_base_device
|
||||
{
|
||||
public:
|
||||
neosprite_optimized_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual void optimize_sprite_data();
|
||||
virtual void draw_pixel(int romaddr, UINT32* dst, pen_t *line_pens);
|
||||
dynamic_array<UINT8> m_sprite_gfx;
|
||||
|
||||
};
|
||||
|
||||
extern const device_type NEOGEO_SPRITE_OPTIMZIED;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class neosprite_midas_device : public neosprite_base_device
|
||||
{
|
||||
public:
|
||||
neosprite_midas_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void draw_pixel(int romaddr, UINT32* dst, pen_t *line_pens);
|
||||
|
||||
UINT16* m_videoram_buffer;
|
||||
void buffer_vram();
|
||||
virtual void draw_fixed_layer_2pixels(UINT32*&pixel_addr, int offset, UINT8* gfx_base, pen_t* char_pens);
|
||||
virtual void set_sprite_region(memory_region* region_sprites);
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
|
||||
};
|
||||
|
||||
extern const device_type NEOGEO_SPRITE_MIDAS;
|
||||
|
||||
|
@ -375,7 +375,7 @@ WRITE16_MEMBER(ng_aes_state::neocd_control_w)
|
||||
case 0x0140:
|
||||
// bprintf(PRINT_NORMAL, _T(" - NGCD OBJ BUSREQ -> 0 (PC: 0x%06X)\n"), SekGetPC(-1));
|
||||
m_has_sprite_bus = true;
|
||||
optimize_sprite_data();
|
||||
m_sprgen->optimize_sprite_data();
|
||||
break;
|
||||
case 0x0142:
|
||||
// bprintf(PRINT_NORMAL, _T(" - NGCD PCM BUSREQ -> 0 (PC: 0x%06X)\n"), SekGetPC(-1));
|
||||
@ -1015,6 +1015,10 @@ void ng_aes_state::common_machine_start()
|
||||
save_item(NAME(m_main_cpu_bank_address));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(ng_aes_state::neogeo_postload), this));
|
||||
|
||||
m_sprgen->set_screen(m_screen);
|
||||
m_sprgen->set_sprite_region(m_region_sprites);
|
||||
m_sprgen->set_fixed_regions(m_region_fixed, m_region_fixedbios);
|
||||
}
|
||||
|
||||
MACHINE_START_MEMBER(ng_aes_state,neogeo)
|
||||
@ -1077,7 +1081,7 @@ MACHINE_RESET_MEMBER(ng_aes_state,neogeo)
|
||||
m_recurse = false;
|
||||
|
||||
/* AES has no SFIX ROM and always uses the cartridge's */
|
||||
neogeo_set_fixed_layer_source(1);
|
||||
m_sprgen->neogeo_set_fixed_layer_source(1);
|
||||
|
||||
NeoSpriteRAM = memregion("sprites")->base();
|
||||
YM2610ADPCMAROM = memregion("ymsnd")->base();
|
||||
@ -1453,9 +1457,9 @@ UINT32 ng_aes_state::screen_update_neocd(screen_device &screen, bitmap_rgb32 &bi
|
||||
// fill with background color first
|
||||
bitmap.fill(m_pens[0x0fff], cliprect);
|
||||
|
||||
if (m_has_sprite_bus) draw_sprites(bitmap, cliprect.min_y);
|
||||
if (m_has_sprite_bus) m_sprgen->draw_sprites(bitmap, cliprect.min_y);
|
||||
|
||||
if (m_has_text_bus) draw_fixed_layer(bitmap, cliprect.min_y);
|
||||
if (m_has_text_bus) m_sprgen->draw_fixed_layer(bitmap, cliprect.min_y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1771,6 +1771,7 @@ $(MESSOBJ)/snk.a: \
|
||||
$(MAME_MACHINE)/neocrypt.o \
|
||||
$(MAME_MACHINE)/neoprot.o \
|
||||
$(MAME_MACHINE)/neoboot.o \
|
||||
$(MAME_VIDEO)/neogeo_spr.o \
|
||||
$(MAME_DRIVERS)/neogeo.o \
|
||||
$(MESS_DRIVERS)/ngp.o \
|
||||
$(MESS_VIDEO)/k1ge.o \
|
||||
|
Loading…
Reference in New Issue
Block a user