diff options
Diffstat (limited to 'src/mame/video/namco_c355spr.cpp')
-rw-r--r-- | src/mame/video/namco_c355spr.cpp | 291 |
1 files changed, 198 insertions, 93 deletions
diff --git a/src/mame/video/namco_c355spr.cpp b/src/mame/video/namco_c355spr.cpp index b5edea53ad7..f81ab57eccf 100644 --- a/src/mame/video/namco_c355spr.cpp +++ b/src/mame/video/namco_c355spr.cpp @@ -19,11 +19,12 @@ DEFINE_DEVICE_TYPE(NAMCO_C355SPR, namco_c355spr_device, "namco_c355spr", "Namco namco_c355spr_device::namco_c355spr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, NAMCO_C355SPR, tag, owner, clock), + device_video_interface(mconfig, *this), m_gfx_region(0), m_palxor(0), m_is_namcofl(false), - m_gfxdecode(*this, finder_base::DUMMY_TAG), - m_palette(*this, finder_base::DUMMY_TAG) + m_buffer(0), + m_gfxdecode(*this, finder_base::DUMMY_TAG) { } @@ -39,10 +40,11 @@ void namco_c355spr_device::zdrawgfxzoom( if (!scalex || !scaley) return; if (dest_bmp.bpp() == 16) { - if( gfx ) + if (gfx) { - int shadow_offset = (m_palette->shadows_enabled())?m_palette->entries():0; - const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors())); + device_palette_interface &palette = m_gfxdecode->palette(); + int shadow_offset = (palette.shadows_enabled())?palette.entries():0; + const pen_t *pal = &palette.pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors())); const uint8_t *source_base = gfx->get_data(code % gfx->elements()); int sprite_screen_height = (scaley*gfx->height()+0x8000)>>16; int sprite_screen_width = (scalex*gfx->width()+0x8000)>>16; @@ -58,7 +60,7 @@ void namco_c355spr_device::zdrawgfxzoom( int x_index_base; int y_index; - if( flipx ) + if (flipx) { x_index_base = (sprite_screen_width-1)*dx; dx = -dx; @@ -68,7 +70,7 @@ void namco_c355spr_device::zdrawgfxzoom( x_index_base = 0; } - if( flipy ) + if (flipy) { y_index = (sprite_screen_height-1)*dy; dy = -dy; @@ -78,51 +80,51 @@ void namco_c355spr_device::zdrawgfxzoom( y_index = 0; } - if( sx < clip.min_x) + if (sx < clip.min_x) { /* clip left */ int pixels = clip.min_x-sx; sx += pixels; x_index_base += pixels*dx; } - if( sy < clip.min_y ) + if (sy < clip.min_y) { /* clip top */ int pixels = clip.min_y-sy; sy += pixels; y_index += pixels*dy; } - if( ex > clip.max_x+1 ) + if (ex > clip.max_x+1) { /* clip right */ int pixels = ex-clip.max_x-1; ex -= pixels; } - if( ey > clip.max_y+1 ) + if (ey > clip.max_y+1) { /* clip bottom */ int pixels = ey-clip.max_y-1; ey -= pixels; } - if( ex>sx ) + if (ex>sx) { /* skip if inner loop doesn't draw anything */ int y; bitmap_ind8 &priority_bitmap = screen.priority(); - if( priority_bitmap.valid() ) + if (priority_bitmap.valid()) { - for( y=sy; y<ey; y++ ) + for (y = sy; y < ey; y++) { const uint8_t *source = source_base + (y_index>>16) * gfx->rowbytes(); uint16_t *dest = &dest_bmp.pix16(y); uint8_t *pri = &priority_bitmap.pix8(y); int x, x_index = x_index_base; - if( m_palxor ) + if (m_palxor) { - for( x=sx; x<ex; x++ ) + for (x = sx; x < ex; x++) { int c = source[x_index>>16]; - if( c != 0xff ) + if (c != 0xff) { - if( pri[x]<=zpos ) + if (pri[x] <= zpos) { - switch( c ) + switch (c) { case 0: dest[x] = 0x4000|(dest[x]&0x1fff); @@ -143,14 +145,14 @@ void namco_c355spr_device::zdrawgfxzoom( } else { - for( x=sx; x<ex; x++ ) + for (x = sx; x < ex; x++) { int c = source[x_index>>16]; - if( c != 0xff ) + if (c != 0xff) { - if( pri[x]<=zpos ) + if (pri[x] <= zpos ) { - if( color == 0xf && c==0xfe && shadow_offset ) + if (color == 0xf && c == 0xfe && shadow_offset) { dest[x] |= shadow_offset; } @@ -184,11 +186,15 @@ void namco_c355spr_device::zdrawgfxzoom( void namco_c355spr_device::device_start() { - //m_spriteram.resize(m_ramsize); - std::fill(std::begin(m_spriteram), std::end(m_spriteram), 0x0000); // needed for Nebulas Ray std::fill(std::begin(m_position), std::end(m_position), 0x0000); + for (int i = 0; i < 2; i++) + { + m_spritelist[i] = auto_alloc_array(machine(), struct c355_sprite, 0x100); + m_sprite_end[i] = m_spritelist[i]; + m_spriteram[i].resize(0x20000/2, 0); + save_item(NAME(m_spriteram[i]), i); + } - save_item(NAME(m_spriteram)); save_item(NAME(m_position)); } @@ -216,17 +222,15 @@ READ16_MEMBER( namco_c355spr_device::position_r ) * 0x10000 sprite attr (page1) * 0x14000 sprite list (page1) */ -template<class _BitmapClass> -void namco_c355spr_device::draw_sprite(screen_device &screen, _BitmapClass &bitmap, const rectangle &cliprect, const uint16_t *pSource, int pri, int zpos ) +void namco_c355spr_device::get_single_sprite(const uint16_t *pSource, struct c355_sprite *sprite_ptr) { - uint16_t *spriteram16 = m_spriteram; + uint16_t *spriteram16 = &m_spriteram[std::max(0, m_buffer - 1)][0]; unsigned screen_height_remaining, screen_width_remaining; unsigned source_height_remaining, source_width_remaining; int hpos,vpos; uint16_t hsize,vsize; uint16_t palette; uint16_t linkno; - uint16_t offset; uint16_t format; int tile_index; int num_cols,num_rows; @@ -239,7 +243,6 @@ void namco_c355spr_device::draw_sprite(screen_device &screen, _BitmapClass &bitm int tile_screen_height; const uint16_t *spriteformat16 = &spriteram16[0x4000/2]; const uint16_t *spritetile16 = &spriteram16[0x8000/2]; - int color; const uint16_t *pWinAttr; rectangle clip; int xscroll, yscroll; @@ -250,34 +253,35 @@ void namco_c355spr_device::draw_sprite(screen_device &screen, _BitmapClass &bitm * ------------xxxx palette select */ palette = pSource[6]; - if( pri != ((palette>>4)&0xf) ) - { - return; - } - - linkno = pSource[0]; /* LINKNO */ - offset = pSource[1]; /* OFFSET */ - hpos = pSource[2]; /* HPOS 0x000..0x7ff (signed) */ - vpos = pSource[3]; /* VPOS 0x000..0x7ff (signed) */ - hsize = pSource[4]; /* HSIZE max 0x3ff pixels */ - vsize = pSource[5]; /* VSIZE max 0x3ff pixels */ + sprite_ptr->pri = ((palette>>4)&0xf); + + linkno = pSource[0]; /* LINKNO */ + sprite_ptr->offset = pSource[1]; /* OFFSET */ + hpos = pSource[2]; /* HPOS 0x000..0x7ff (signed) */ + vpos = pSource[3]; /* VPOS 0x000..0x7ff (signed) */ + hsize = pSource[4]; /* HSIZE max 0x3ff pixels */ + vsize = pSource[5]; /* VSIZE max 0x3ff pixels */ /* pSource[6] contains priority/palette */ /* pSource[7] is used in Lucky & Wild, possibly for sprite-road priority */ - if( linkno*4>=0x4000/2 ) return; /* avoid garbage memory reads */ + if (linkno*4>=0x4000/2) /* avoid garbage memory reads */ + { + sprite_ptr->disable = true; + return; + } xscroll = (int16_t)m_position[1]; yscroll = (int16_t)m_position[0]; -// xscroll &= 0x3ff; if( xscroll & 0x200 ) xscroll |= ~0x3ff; - xscroll &= 0x1ff; if( xscroll & 0x100 ) xscroll |= ~0x1ff; - yscroll &= 0x1ff; if( yscroll & 0x100 ) yscroll |= ~0x1ff; +// xscroll &= 0x3ff; if (xscroll & 0x200 ) xscroll |= ~0x3ff; + xscroll &= 0x1ff; if (xscroll & 0x100 ) xscroll |= ~0x1ff; + yscroll &= 0x1ff; if (yscroll & 0x100 ) yscroll |= ~0x1ff; - if( bitmap.width() > 384 ) + if (screen().height() > 384) { /* Medium Resolution: System21 adjust */ xscroll = (int16_t)m_position[1]; - xscroll &= 0x3ff; if( xscroll & 0x200 ) xscroll |= ~0x3ff; - if( yscroll<0 ) + xscroll &= 0x3ff; if (xscroll & 0x200) xscroll |= ~0x3ff; + if (yscroll<0) { /* solvalou */ yscroll += 0x20; } @@ -299,9 +303,9 @@ void namco_c355spr_device::draw_sprite(screen_device &screen, _BitmapClass &bitm vpos -= yscroll; pWinAttr = &spriteram16[0x2400/2+((palette>>8)&0xf)*4]; clip.set(pWinAttr[0] - xscroll, pWinAttr[1] - xscroll, pWinAttr[2] - yscroll, pWinAttr[3] - yscroll); - clip &= cliprect; - hpos&=0x7ff; if( hpos&0x400 ) hpos |= ~0x7ff; /* sign extend */ - vpos&=0x7ff; if( vpos&0x400 ) vpos |= ~0x7ff; /* sign extend */ + sprite_ptr->clip = clip; + hpos&=0x7ff; if (hpos&0x400 ) hpos |= ~0x7ff; /* sign extend */ + vpos&=0x7ff; if (vpos&0x400 ) vpos |= ~0x7ff; /* sign extend */ tile_index = spriteformat16[linkno*4+0]; format = spriteformat16[linkno*4+1]; @@ -310,13 +314,17 @@ void namco_c355spr_device::draw_sprite(screen_device &screen, _BitmapClass &bitm num_cols = (format>>4)&0xf; num_rows = (format)&0xf; - if( num_cols == 0 ) num_cols = 0x10; + if (num_cols == 0) num_cols = 0x10; flipx = (hsize&0x8000)?1:0; hsize &= 0x3ff;//0x1ff; - if( hsize == 0 ) return; + if (hsize == 0) + { + sprite_ptr->disable = true; + return; + } zoomx = (hsize<<16)/(num_cols*16); dx = (dx*zoomx+0x8000)>>16; - if( flipx ) + if (flipx) { hpos += dx; } @@ -325,13 +333,17 @@ void namco_c355spr_device::draw_sprite(screen_device &screen, _BitmapClass &bitm hpos -= dx; } - if( num_rows == 0 ) num_rows = 0x10; + if (num_rows == 0) num_rows = 0x10; flipy = (vsize&0x8000)?1:0; vsize &= 0x3ff; - if( vsize == 0 ) return; + if (vsize == 0) + { + sprite_ptr->disable = true; + return; + } zoomy = (vsize<<16)/(num_rows*16); dy = (dy*zoomy+0x8000)>>16; - if( flipy ) + if (flipy) { vpos += dy; } @@ -340,52 +352,52 @@ void namco_c355spr_device::draw_sprite(screen_device &screen, _BitmapClass &bitm vpos -= dy; } - color = (palette&0xf)^m_palxor; + sprite_ptr->flipx = flipx; + sprite_ptr->flipy = flipy; + sprite_ptr->size = num_rows * num_cols; + sprite_ptr->color = (palette&0xf)^m_palxor; source_height_remaining = num_rows*16; screen_height_remaining = vsize; sy = vpos; - for( row=0; row<num_rows; row++ ) + int ind = 0; + for (row = 0; row < num_rows; row++) { tile_screen_height = 16*screen_height_remaining/source_height_remaining; zoomy = (screen_height_remaining<<16)/source_height_remaining; - if( flipy ) + if (flipy) { sy -= tile_screen_height; } source_width_remaining = num_cols*16; screen_width_remaining = hsize; sx = hpos; - for( col=0; col<num_cols; col++ ) + for (col = 0; col < num_cols; col++) { tile_screen_width = 16*screen_width_remaining/source_width_remaining; zoomx = (screen_width_remaining<<16)/source_width_remaining; - if( flipx ) + if (flipx) { sx -= tile_screen_width; } tile = spritetile16[tile_index++]; - if( (tile&0x8000)==0 ) + sprite_ptr->tile[ind] = tile; + if ((tile&0x8000)==0) { - zdrawgfxzoom( - screen, - bitmap, - clip, - m_gfxdecode->gfx(m_gfx_region), - m_code2tile(tile) + offset, - color, - flipx,flipy, - sx,sy, - zoomx, zoomy, zpos ); + sprite_ptr->x[ind] = sx; + sprite_ptr->y[ind] = sy; + sprite_ptr->zoomx[ind] = zoomx; + sprite_ptr->zoomy[ind] = zoomy; } - if( !flipx ) + if (!flipx) { sx += tile_screen_width; } screen_width_remaining -= tile_screen_width; source_width_remaining -= 16; + ind++; } /* next col */ - if( !flipy ) + if (!flipy) { sy += tile_screen_height; } @@ -400,51 +412,144 @@ int namco_c355spr_device::default_code2tile(int code) return code; } -template<class _BitmapClass> -void namco_c355spr_device::draw_list(screen_device &screen, _BitmapClass &bitmap, const rectangle &cliprect, int pri, const uint16_t *pSpriteList16, const uint16_t *pSpriteTable) +void namco_c355spr_device::get_list(int no, const uint16_t *pSpriteList16, const uint16_t *pSpriteTable) { - int i; /* draw the sprites */ - for( i=0; i<256; i++ ) + struct c355_sprite *sprite_ptr = m_spritelist[no]; + for (int i = 0; i < 256; i++) { + sprite_ptr->disable = false; uint16_t which = pSpriteList16[i]; - draw_sprite(screen, bitmap, cliprect, &pSpriteTable[(which&0xff)*8], pri, i ); - if( which&0x100 ) break; + get_single_sprite(&pSpriteTable[(which&0xff)*8], sprite_ptr); + sprite_ptr++; + if (which&0x100) break; } + m_sprite_end[no] = sprite_ptr; } -void namco_c355spr_device::draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri) +void namco_c355spr_device::get_sprites() { + int buffer = std::max(0, m_buffer - 1); // int offs = spriteram16[0x18000/2]; /* end-of-sprite-list */ - if (pri == 0) - screen.priority().fill(0, cliprect); // if (offs == 0) // boot // TODO: solvalou service mode wants 0x14000/2 & 0x00000/2 - draw_list(screen, bitmap, cliprect, pri, &m_spriteram[0x02000/2], &m_spriteram[0x00000/2]); + get_list(0, &m_spriteram[buffer][0x02000/2], &m_spriteram[buffer][0x00000/2]); // else - draw_list(screen, bitmap, cliprect, pri, &m_spriteram[0x14000/2], &m_spriteram[0x10000/2]); + get_list(1, &m_spriteram[buffer][0x14000/2], &m_spriteram[buffer][0x10000/2]); +} + +void namco_c355spr_device::draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri) +{ +// int offs = spriteram16[0x18000/2]; /* end-of-sprite-list */ + if (pri == 0) + { + screen.priority().fill(0, cliprect); + if (m_buffer == 0) // not buffered sprites + get_sprites(); + } + + for (int no = 0; no < 2; no++) + { + //if (offs == no) + { + int i = 0; + struct c355_sprite *sprite_ptr = m_spritelist[no]; + + while (sprite_ptr != m_sprite_end[no]) + { + if ((sprite_ptr->pri == pri) && (sprite_ptr->disable == false)) + { + rectangle clip = sprite_ptr->clip; + clip &= cliprect; + for (int ind = 0; ind < sprite_ptr->size; ind++) + { + if ((sprite_ptr->tile[ind] & 0x8000) == 0) + { + zdrawgfxzoom( + screen, + bitmap, + clip, + m_gfxdecode->gfx(m_gfx_region), + m_code2tile(sprite_ptr->tile[ind]) + sprite_ptr->offset, + sprite_ptr->color, + sprite_ptr->flipx, sprite_ptr->flipy, + sprite_ptr->x[ind], sprite_ptr->y[ind], + sprite_ptr->zoomx[ind], sprite_ptr->zoomy[ind], i); + } + } + } + i++; + sprite_ptr++; + } + } + } } void namco_c355spr_device::draw(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri) { // int offs = spriteram16[0x18000/2]; /* end-of-sprite-list */ if (pri == 0) + { screen.priority().fill(0, cliprect); + if (m_buffer == 0) // not buffered sprites + get_sprites(); + } -// if (offs == 0) // boot - draw_list(screen, bitmap, cliprect, pri, &m_spriteram[0x02000/2], &m_spriteram[0x00000/2]); -// else - draw_list(screen, bitmap, cliprect, pri, &m_spriteram[0x14000/2], &m_spriteram[0x10000/2]); + for (int no = 0; no < 2; no++) + { + //if (offs == no) + { + int i = 0; + struct c355_sprite *sprite_ptr = m_spritelist[no]; + + while (sprite_ptr != m_sprite_end[no]) + { + if (sprite_ptr->pri == pri) + { + sprite_ptr->clip &= cliprect; + for (int ind = 0; ind < sprite_ptr->size; ind++) + { + if ((sprite_ptr->tile[ind] & 0x8000) == 0) + { + zdrawgfxzoom( + screen, + bitmap, + sprite_ptr->clip, + m_gfxdecode->gfx(m_gfx_region), + m_code2tile(sprite_ptr->tile[ind]) + sprite_ptr->offset, + sprite_ptr->color, + sprite_ptr->flipx,sprite_ptr->flipy, + sprite_ptr->x[ind],sprite_ptr->y[ind], + sprite_ptr->zoomx[ind], sprite_ptr->zoomy[ind], i ); + } + } + } + sprite_ptr++; + } + } + } } WRITE16_MEMBER( namco_c355spr_device::spriteram_w ) { - COMBINE_DATA(&m_spriteram[offset]); + COMBINE_DATA(&m_spriteram[0][offset]); } READ16_MEMBER( namco_c355spr_device::spriteram_r ) { - return m_spriteram[offset]; + return m_spriteram[0][offset]; +} + +WRITE_LINE_MEMBER( namco_c355spr_device::vblank ) +{ + if (state) + { + if (m_buffer > 0) + get_sprites(); + + if (m_buffer > 1) + std::copy(m_spriteram[0].begin(), m_spriteram[0].end(), m_spriteram[1].begin()); + } } |