/* video/shangkid */ #include "emu.h" #include "cpu/z80/z80.h" #include "includes/shangkid.h" static TILE_GET_INFO( get_bg_tile_info ){ shangkid_state *state = machine.driver_data(); UINT8 *videoram = state->m_videoram; int attributes = videoram[tile_index+0x800]; int tile_number = videoram[tile_index]+0x100*(attributes&0x3); int color; if( state->m_gfx_type==1 ) { /* Shanghai Kid: ------xx bank -----x-- flipx xxxxx--- color */ color = attributes>>3; color = (color&0x03)|((color&0x1c)<<1); SET_TILE_INFO( 0, tile_number, color, (attributes&0x04)?TILE_FLIPX:0); } else { /* Chinese Hero: ------xx bank -xxxxx-- color x------- flipx? */ color = (attributes>>2)&0x1f; SET_TILE_INFO( 0, tile_number, color, (attributes&0x80)?TILE_FLIPX:0); } tileinfo->category = (machine.region( "proms" )->base()[0x800+color*4]==2)?1:0; } VIDEO_START( shangkid ) { shangkid_state *state = machine.driver_data(); state->m_background = tilemap_create(machine, get_bg_tile_info,tilemap_scan_rows,8,8,64,32); } WRITE8_HANDLER( shangkid_videoram_w ) { shangkid_state *state = space->machine().driver_data(); UINT8 *videoram = state->m_videoram; videoram[offset] = data; tilemap_mark_tile_dirty( state->m_background, offset&0x7ff ); } static void draw_sprite(running_machine &machine, const UINT8 *source, bitmap_t *bitmap, const rectangle *cliprect) { shangkid_state *state = machine.driver_data(); const gfx_element *gfx; int transparent_pen; int bank_index; int c,r; int width,height; int sx,sy; int ypos = 209 - source[0]; int tile = source[1]&0x3f; int xflip = (source[1]&0x40)?1:0; int yflip = (source[1]&0x80)?1:0; int bank = source[2]&0x3f; int xsize = (source[2]&0x40)?1:0; int ysize = (source[2]&0x80)?1:0; int yscale = source[3]&0x07; /* 0x0 = smallest; 0x7 = biggest */ int xpos = ((source[4]+source[5]*255)&0x1ff)-23; int color = source[6]&0x3f; int xscale = source[7]&0x07; /* 0x0 = smallest; 0x7 = biggest */ /* adjust placement for small sprites */ if( xsize==0 && xflip ) xpos -= 16; if( ysize==0 && yflip==0 ) ypos += 16; if( state->m_gfx_type == 1 ) { /* Shanghai Kid */ switch( bank&0x30 ) { case 0x00: case 0x10: tile += 0x40*(bank&0xf); break; case 0x20: tile += 0x40*((bank&0x3)|0x10); break; case 0x30: tile += 0x40*((bank&0x3)|0x14); break; } bank_index = 0; transparent_pen = 3; } else { /* Chinese Hero */ color >>= 1; // It's needed in level 7 to hide "bogus" sprites. Is it a sprite disable flag or an end sprite list flag? if(color == 0) return; switch( bank>>2 ) { case 0x0: bank_index = 0; break; case 0x9: bank_index = 1; break; case 0x6: bank_index = 2; break; case 0xf: bank_index = 3; break; default: bank_index = 0; break; } if( bank&0x01 ) tile += 0x40; transparent_pen = 7; } gfx = machine.gfx[1+bank_index]; width = (xscale+1)*2; height = (yscale+1)*2; /* center zoomed sprites */ xpos += (16-width)*(xsize+1)/2; ypos += (16-height)*(ysize+1)/2; for( r=0; r<=ysize; r++ ) { for( c=0; c<=xsize; c++ ) { sx = xpos+(c^xflip)*width; sy = ypos+(r^yflip)*height; drawgfxzoom_transpen( bitmap, cliprect, gfx, tile+c*8+r, color, xflip,yflip, sx,sy, (width<<16)/16, (height<<16)/16,transparent_pen ); // wrap around y drawgfxzoom_transpen( bitmap, cliprect, gfx, tile+c*8+r, color, xflip,yflip, sx,sy+256, (width<<16)/16, (height<<16)/16,transparent_pen ); } } } static void shangkid_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect) { shangkid_state *state = machine.driver_data(); const UINT8 *source, *finish; finish = state->m_spriteram; source = state->m_spriteram+0x200; while( source>finish ){ source -= 8; draw_sprite(machine, source, bitmap,cliprect ); } } SCREEN_UPDATE( shangkid ) { shangkid_state *state = screen->machine().driver_data(); int flipscreen = state->m_videoreg[1]&0x80; tilemap_set_flip( state->m_background, flipscreen?(TILEMAP_FLIPX|TILEMAP_FLIPY):0 ); tilemap_set_scrollx( state->m_background,0,state->m_videoreg[0]-40 ); tilemap_set_scrolly( state->m_background,0,state->m_videoreg[2]+0x10 ); tilemap_draw( bitmap,cliprect,state->m_background,0,0 ); shangkid_draw_sprites(screen->machine(), bitmap,cliprect ); tilemap_draw( bitmap,cliprect,state->m_background,1,0 ); /* high priority tiles */ return 0; } PALETTE_INIT( dynamski ) { int i; /* allocate the colortable */ machine.colortable = colortable_alloc(machine, 0x20); /* create a lookup table for the palette */ for (i = 0; i < 0x20; i++) { UINT16 data = (color_prom[i | 0x20] << 8) | color_prom[i]; rgb_t color = MAKE_RGB(pal5bit(data >> 1), pal5bit(data >> 6), pal5bit(data >> 11)); colortable_palette_set_color(machine.colortable, i, color); } /* color_prom now points to the beginning of the lookup table */ color_prom += 0x40; /* characters */ for (i = 0; i < 0x40; i++) { UINT8 ctabentry = color_prom[i] & 0x0f; colortable_entry_set_value(machine.colortable, i, ctabentry); } /* sprites */ for (i = 0x40; i < 0x80; i++) { UINT8 ctabentry = (color_prom[(i - 0x40) + 0x100] & 0x0f) | 0x10; colortable_entry_set_value(machine.colortable, i, ctabentry); } } static void dynamski_draw_background(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int pri ) { shangkid_state *state = machine.driver_data(); UINT8 *videoram = state->m_videoram; int i; int sx,sy; int tile; int attr; int temp; for( i=0; i<0x400; i++ ) { sx = (i%32)*8; sy = (i/32)*8; if( sy<16 ) { temp = sx; sx = sy+256+16; sy = temp; } else if( sy>=256-16 ) { temp = sx; sx = sy-256+16; sy = temp; } else { sx+=16; } tile = videoram[i]; attr = videoram[i+0x400]; /* x---.---- priority? -xx-.---- bank */ if( pri==0 || (attr>>7)==pri ) { tile += ((attr>>5)&0x3)*256; drawgfx_transpen( bitmap, cliprect, machine.gfx[0], tile, attr & 0x0f, 0,0,//xflip,yflip, sx,sy, pri?3:-1 ); } } } static void dynamski_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect ) { shangkid_state *state = machine.driver_data(); UINT8 *videoram = state->m_videoram; int i; int sx,sy; int tile; int bank; int attr; int color; for( i=0x7e; i>=0x00; i-=2 ) { bank = videoram[0x1b80+i]; attr = videoram[0x1b81+i]; tile = videoram[0xb80+i]; color = videoram[0xb81+i]; sy = 240-videoram[0x1380+i]; sx = videoram[0x1381+i]-64+8+16; if( attr&1 ) sx += 0x100; drawgfx_transpen( bitmap, cliprect, machine.gfx[1], bank*0x40 + (tile&0x3f), color, tile&0x80,tile&0x40, /* flipx,flipy */ sx,sy,3 ); } } SCREEN_UPDATE( dynamski ) { dynamski_draw_background(screen->machine(), bitmap,cliprect, 0 ); dynamski_draw_sprites(screen->machine(), bitmap,cliprect ); dynamski_draw_background(screen->machine(), bitmap,cliprect, 1 ); return 0; }