diff options
Diffstat (limited to 'src/mame/video/deco_mlc.cpp')
-rw-r--r-- | src/mame/video/deco_mlc.cpp | 128 |
1 files changed, 59 insertions, 69 deletions
diff --git a/src/mame/video/deco_mlc.cpp b/src/mame/video/deco_mlc.cpp index a97b1c2e10d..85f066de120 100644 --- a/src/mame/video/deco_mlc.cpp +++ b/src/mame/video/deco_mlc.cpp @@ -13,27 +13,24 @@ #include "emu.h" #include "includes/deco_mlc.h" +#include <algorithm> + /******************************************************************************/ VIDEO_START_MEMBER(deco_mlc_state,mlc) { - if (m_gfxdecode->gfx(0)->granularity()==16) - m_colour_mask=0x7f; - else if (m_gfxdecode->gfx(0)->granularity()==32) - m_colour_mask=0x3f; - else - m_colour_mask=0x1f; + int max_color = (0x800 / m_gfxdecode->gfx(0)->granularity()); + m_colour_mask=max_color - 1; + m_shadow_mask=max_color << 1; // temp_bitmap = std::make_unique<bitmap_rgb32>(512, 512 ); - m_mlc_buffered_spriteram = std::make_unique<uint16_t[]>(0x3000/2); - m_mlc_spriteram_spare = std::make_unique<uint16_t[]>(0x3000/2); - m_mlc_spriteram = std::make_unique<uint16_t[]>(0x3000/2); - - - save_pointer(NAME(m_mlc_spriteram.get()), 0x3000/2); - save_pointer(NAME(m_mlc_spriteram_spare.get()), 0x3000/2); - save_pointer(NAME(m_mlc_buffered_spriteram.get()), 0x3000/2); + m_buffered_spriteram = std::make_unique<uint16_t[]>(0x3000/4); + m_spriteram_spare = std::make_unique<uint16_t[]>(0x3000/4); + m_spriteram = std::make_unique<uint16_t[]>(0x3000/4); + save_pointer(NAME(m_spriteram.get()), 0x3000/4); + save_pointer(NAME(m_spriteram_spare.get()), 0x3000/4); + save_pointer(NAME(m_buffered_spriteram.get()), 0x3000/4); } @@ -41,9 +38,10 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, uint32_t* dest,const rectangle &clip,gfx_element *gfx, uint32_t code1,uint32_t code2, uint32_t color,int flipx,int sx, int transparent_color,int use8bpp, - int scalex, int alpha, int srcline ) + int scalex, int alpha, int srcline, int shadowMode, int alphaMode ) { if (!scalex) return; + uint32_t shadowval = shadowMode ? 0xffffffff : 0; /* scalex and scaley are 16.16 fixed point numbers @@ -55,7 +53,6 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, /* KW 991012 -- Added code to force clip to bitmap boundary */ - int sprite_screen_width = (scalex*16+(sx&0xffff))>>16; sx>>=16; @@ -78,8 +75,6 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, x_index_base = 0; } - - if( sx < clip.min_x) { /* clip left */ int pixels = clip.min_x-sx; @@ -97,14 +92,12 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, { /* skip if inner loop doesn't draw anything */ const pen_t *pal = &state->m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors())); const uint8_t *code_base1 = gfx->get_data(code1 % gfx->elements()); - + const uint8_t *code_base2 = gfx->get_data(code2 % gfx->elements()); + const uint8_t *source1 = code_base1 + (srcline) * gfx->rowbytes(); + const uint8_t *source2 = code_base2 + (srcline) * gfx->rowbytes(); /* no alpha */ - if (alpha == 0xff) + if ((alpha == 0xff) && (!shadowMode)) { - const uint8_t *code_base2 = gfx->get_data(code2 % gfx->elements()); - const uint8_t *source1 = code_base1 + (srcline) * gfx->rowbytes(); - const uint8_t *source2 = code_base2 + (srcline) * gfx->rowbytes(); - int x, x_index = x_index_base; for( x=sx; x<ex; x++ ) @@ -119,14 +112,16 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, } } else - { - const uint8_t *source = code_base1 + (srcline) * gfx->rowbytes(); - + { /* TODO : 8bpp and alpha can use simultaneously? */ int x, x_index = x_index_base; for( x=sx; x<ex; x++ ) { - int c = source[x_index>>16]; - if( c != transparent_color ) dest[x] = alpha_blend_r32(dest[x], 0, alpha); //pal[c]); + int c = source1[x_index>>16]; + if (use8bpp) + c=(c<<4)|source2[x_index>>16]; + + // alphaMode & 0xc0 = 0xc0 : Shadow, 0 : Alpha, Other bits unknown + if( c != transparent_color ) dest[x] = alpha_blend_r32(dest[x], (alphaMode & 0xc0) ? shadowval : pal[c], shadowMode ? 0x80 : alpha); x_index += dx; } } @@ -150,18 +145,19 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint int hibits=0; int tileFormat=0; int rasterMode=0; + int shadowMode=0; int clipper=0; rectangle user_clip; - uint16_t* mlc_spriteram=m_mlc_buffered_spriteram.get(); // spriteram32 + uint16_t* spriteram=m_buffered_spriteram.get(); //printf("%d - (%08x %08x %08x) (%08x %08x %08x) (%08x %08x %08x)\n", scanline, m_irq_ram[6], m_irq_ram[7], m_irq_ram[8], m_irq_ram[9], m_irq_ram[10], m_irq_ram[11] , m_irq_ram[12] , m_irq_ram[13] , m_irq_ram[14]); for (offs = (0x3000/4)-8; offs>=0; offs-=8) { - if ((mlc_spriteram[offs+0]&0x8000)==0) + if ((spriteram[offs+0]&0x8000)==0) continue; - if ((mlc_spriteram[offs+1]&0x2000) && (m_screen->frame_number() & 1)) + if ((spriteram[offs+1]&0x2000) && (m_screen->frame_number() & 1)) continue; /* @@ -203,17 +199,17 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint Word 3: 0xffff - Low-bits of tile index */ - y = mlc_spriteram[offs+2]&0x7ff; - x = mlc_spriteram[offs+3]&0x7ff; + y = spriteram[offs+2]&0x7ff; + x = spriteram[offs+3]&0x7ff; if (x&0x400) x=-(0x400-(x&0x3ff)); if (y&0x400) y=-(0x400-(y&0x3ff)); - fx = mlc_spriteram[offs+1]&0x8000; - fy = mlc_spriteram[offs+1]&0x4000; - color = mlc_spriteram[offs+1]&0xff; + fx = spriteram[offs+1]&0x8000; + fy = spriteram[offs+1]&0x4000; + color = spriteram[offs+1]&0xff; - int raster_select = (mlc_spriteram[offs+1]&0x0180)>>7; + int raster_select = (spriteram[offs+1]&0x0180)>>7; // there are 3 different sets of raster values, must be a way to selects @@ -225,17 +221,14 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint // have the scroll effect applied to them. all clip windows are the same // so there is no reason to select a clip window other than to be using it // to select a set of raster-set scroll regs? - rasterMode = (mlc_spriteram[offs+1]>>10)&0x1; - - + rasterMode = (spriteram[offs+1]>>10)&0x1; + clipper = (spriteram[offs+1]>>8)&0x3; - clipper = (mlc_spriteram[offs+1]>>8)&0x3; - - indx = mlc_spriteram[offs+0]&0x3fff; - yscale = mlc_spriteram[offs+4]&0x3ff; - xscale = mlc_spriteram[offs+5]&0x3ff; + indx = spriteram[offs+0]&0x3fff; + yscale = spriteram[offs+4]&0x3ff; + xscale = spriteram[offs+5]&0x3ff; colorOffset = 0; /* Clip windows - this mapping seems odd, but is correct for Skull Fang and StadHr96, @@ -243,17 +236,15 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint clipper=((clipper&2)>>1)|((clipper&1)<<1); // Swap low two bits - - int upperclip = (mlc_spriteram[offs+1]>>10)&0x2; + int upperclip = (spriteram[offs+1]>>10)&0x2; // this is used on some ingame gfx in stadhr96 // to clip the images of your guys on the bases if (upperclip) clipper |= 0x4; - - int min_y = m_mlc_clip_ram[(clipper*4)+0]; - int max_y = m_mlc_clip_ram[(clipper*4)+1]; + int min_y = m_clip_ram[(clipper*4)+0]; + int max_y = m_clip_ram[(clipper*4)+1]; if (scanline<min_y) continue; @@ -262,31 +253,33 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint continue; - user_clip.min_x=m_mlc_clip_ram[(clipper*4)+2]; - user_clip.max_x=m_mlc_clip_ram[(clipper*4)+3]; + user_clip.min_x=m_clip_ram[(clipper*4)+2]; + user_clip.max_x=m_clip_ram[(clipper*4)+3]; user_clip &= cliprect; /* Any colours out of range (for the bpp value) trigger 'shadow' mode */ - if (color & (m_colour_mask+1)) + shadowMode = (color & (m_shadow_mask)) ? 1 : 0; // shadow mode (OK for skullfng) + if ((color & (m_colour_mask+1)) || (shadowMode)) alpha=0x80; else alpha=0xff; + color&=m_colour_mask; /* If this bit is set, combine this block with the next one */ - if (mlc_spriteram[offs+1]&0x1000) { + if (spriteram[offs+1]&0x1000) { use8bppMode=1; /* In 8bpp the palette base is stored in the next block */ if (offs-8>=0) { - color = (mlc_spriteram[offs+1-8]&0x7f); - indx2 = mlc_spriteram[offs+0-8]&0x3fff; + color = (spriteram[offs+1-8]&0x7f); + indx2 = spriteram[offs+0-8]&0x3fff; } } else use8bppMode=0; /* Lookup tiles/size in sprite index ram OR in the lookup rom */ - if (mlc_spriteram[offs+0]&0x4000) { + if (spriteram[offs+0]&0x4000) { index_ptr8=rom + indx*8; /* Byte ptr */ h=(index_ptr8[1]>>0)&0xf; w=(index_ptr8[3]>>0)&0xf; @@ -319,7 +312,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint } else { indx&=0x1fff; - index_ptr=m_mlc_vram + indx*4; + index_ptr=m_vram + indx*4; h=(index_ptr[0]>>8)&0xf; w=(index_ptr[1]>>8)&0xf; @@ -327,7 +320,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint if (!w) w=16; if (use8bppMode) { - uint32_t* index_ptr2=m_mlc_vram + ((indx2*4)&0x7fff); + uint32_t* index_ptr2=m_vram + ((indx2*4)&0x7fff); sprite2=((index_ptr2[2]&0x3)<<16) | (index_ptr2[3]&0xffff); } @@ -373,6 +366,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint if (raster_select==1 || raster_select==2 || raster_select==3) { + shadowMode = 0; // TODO : Raster enable and shadow mode can't use simultaneously? int irq_base_reg; /* 6, 9, 12 are possible */ if (raster_select== 1) irq_base_reg = 6; // OK upper screen.. left? else if (raster_select== 2) irq_base_reg = 9; // OK upper screen.. main / center @@ -393,7 +387,6 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint { // possibly disabled? } - } xscale *= extra_x_scale; @@ -505,7 +498,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint } else { - const uint32_t* ptr=m_mlc_vram + ((tile)&0x7fff); + const uint32_t* ptr=m_vram + ((tile)&0x7fff); tile=(*ptr)&0xffff; if (tileFormat) @@ -528,7 +521,8 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint tile,tile2, color + colorOffset,fx,realxbase, 0, - use8bppMode,(xscale),alpha, srcline); + use8bppMode,(xscale),alpha, srcline, + shadowMode, m_irq_ram[0x04/4]); } @@ -547,19 +541,15 @@ WRITE_LINE_MEMBER(deco_mlc_state::screen_vblank_mlc) lookup table. Without buffering incorrect one frame glitches are seen in several places, especially in Hoops. */ - memcpy(m_mlc_buffered_spriteram.get(), m_mlc_spriteram.get(), 0x3000/2); + std::copy(&m_spriteram[0], &m_spriteram[0x3000/4], &m_buffered_spriteram[0]); } } -uint32_t deco_mlc_state::screen_update_mlc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t deco_mlc_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { // temp_bitmap->fill(0, cliprect); bitmap.fill(m_palette->pen(0), cliprect); /* Pen 0 fill colour confirmed from Skull Fang level 2 */ - - - - for (int i=cliprect.min_y;i<=cliprect.max_y;i++) { uint32_t *dest = &bitmap.pix32(i); |