/*************************************************************************** video.c Functions to emulate the video hardware of the machine. ***************************************************************************/ #include "emu.h" #include "machine/segacrpt.h" #include "includes/senjyo.h" /*************************************************************************** Callbacks for the TileMap code ***************************************************************************/ static TILE_GET_INFO( get_fg_tile_info ) { senjyo_state *state = machine.driver_data(); UINT8 attr = state->m_fgcolorram[tile_index]; int flags = (attr & 0x80) ? TILE_FLIPY : 0; if (state->m_is_senjyo && (tile_index & 0x1f) >= 32-8) flags |= TILE_FORCE_LAYER0; SET_TILE_INFO( 0, state->m_fgvideoram[tile_index] + ((attr & 0x10) << 4), attr & 0x07, flags); } static TILE_GET_INFO( senjyo_bg1_tile_info ) { senjyo_state *state = machine.driver_data(); UINT8 code = state->m_bg1videoram[tile_index]; SET_TILE_INFO( 1, code, (code & 0x70) >> 4, 0); } static TILE_GET_INFO( starforc_bg1_tile_info ) { /* Star Force has more tiles in bg1, so to get a uniform color code spread */ /* they wired bit 7 of the tile code in place of bit 4 to get the color code */ static const UINT8 colormap[8] = { 0, 2, 4, 6, 1, 3, 5, 7 }; senjyo_state *state = machine.driver_data(); UINT8 code = state->m_bg1videoram[tile_index]; SET_TILE_INFO( 1, code, colormap[(code & 0xe0) >> 5], 0); } static TILE_GET_INFO( get_bg2_tile_info ) { senjyo_state *state = machine.driver_data(); UINT8 code = state->m_bg2videoram[tile_index]; SET_TILE_INFO( 2, code, (code & 0xe0) >> 5, 0); } static TILE_GET_INFO( get_bg3_tile_info ) { senjyo_state *state = machine.driver_data(); UINT8 code = state->m_bg3videoram[tile_index]; SET_TILE_INFO( 3, code, (code & 0xe0) >> 5, 0); } /*************************************************************************** Start the video hardware emulation. ***************************************************************************/ VIDEO_START( senjyo ) { senjyo_state *state = machine.driver_data(); state->m_fg_tilemap = tilemap_create(machine, get_fg_tile_info, tilemap_scan_rows, 8, 8, 32, 32); if (state->m_is_senjyo) { state->m_bg1_tilemap = tilemap_create(machine, senjyo_bg1_tile_info, tilemap_scan_rows, 16, 16, 16, 32); state->m_bg2_tilemap = tilemap_create(machine, get_bg2_tile_info, tilemap_scan_rows, 16, 16, 16, 48); /* only 16x32 used by Star Force */ state->m_bg3_tilemap = tilemap_create(machine, get_bg3_tile_info, tilemap_scan_rows, 16, 16, 16, 56); /* only 16x32 used by Star Force */ } else { state->m_bg1_tilemap = tilemap_create(machine, starforc_bg1_tile_info, tilemap_scan_rows, 16, 16, 16, 32); state->m_bg2_tilemap = tilemap_create(machine, get_bg2_tile_info, tilemap_scan_rows, 16, 16, 16, 32); /* only 16x32 used by Star Force */ state->m_bg3_tilemap = tilemap_create(machine, get_bg3_tile_info, tilemap_scan_rows, 16, 16, 16, 32); /* only 16x32 used by Star Force */ } tilemap_set_transparent_pen(state->m_fg_tilemap, 0); tilemap_set_transparent_pen(state->m_bg1_tilemap, 0); tilemap_set_transparent_pen(state->m_bg2_tilemap, 0); tilemap_set_transparent_pen(state->m_bg3_tilemap, 0); tilemap_set_scroll_cols(state->m_fg_tilemap, 32); } /*************************************************************************** Memory handlers ***************************************************************************/ WRITE8_HANDLER( senjyo_fgvideoram_w ) { senjyo_state *state = space->machine().driver_data(); state->m_fgvideoram[offset] = data; tilemap_mark_tile_dirty(state->m_fg_tilemap, offset); } WRITE8_HANDLER( senjyo_fgcolorram_w ) { senjyo_state *state = space->machine().driver_data(); state->m_fgcolorram[offset] = data; tilemap_mark_tile_dirty(state->m_fg_tilemap, offset); } WRITE8_HANDLER( senjyo_bg1videoram_w ) { senjyo_state *state = space->machine().driver_data(); state->m_bg1videoram[offset] = data; tilemap_mark_tile_dirty(state->m_bg1_tilemap, offset); } WRITE8_HANDLER( senjyo_bg2videoram_w ) { senjyo_state *state = space->machine().driver_data(); state->m_bg2videoram[offset] = data; tilemap_mark_tile_dirty(state->m_bg2_tilemap, offset); } WRITE8_HANDLER( senjyo_bg3videoram_w ) { senjyo_state *state = space->machine().driver_data(); state->m_bg3videoram[offset] = data; tilemap_mark_tile_dirty(state->m_bg3_tilemap, offset); } WRITE8_HANDLER( senjyo_bgstripes_w ) { senjyo_state *state = space->machine().driver_data(); *state->m_bgstripesram = data; } /*************************************************************************** Display refresh ***************************************************************************/ static void draw_bgbitmap(running_machine &machine, bitmap_t *bitmap,const rectangle *cliprect) { senjyo_state *state = machine.driver_data(); int x,y,pen,strwid,count; if (state->m_bgstripes == 0xff) /* off */ bitmap_fill(bitmap,cliprect,0); else { int flip = flip_screen_get(machine); pen = 0; count = 0; strwid = state->m_bgstripes; if (strwid == 0) strwid = 0x100; if (flip) strwid ^= 0xff; for (x = 0;x < 256;x++) { if (flip) for (y = 0;y < 256;y++) *BITMAP_ADDR16(bitmap, y, 255 - x) = 384 + pen; else for (y = 0;y < 256;y++) *BITMAP_ADDR16(bitmap, y, x) = 384 + pen; count += 0x10; if (count >= strwid) { pen = (pen + 1) & 0x0f; count -= strwid; } } } } static void draw_radar(running_machine &machine,bitmap_t *bitmap,const rectangle *cliprect) { senjyo_state *state = machine.driver_data(); int offs,x; for (offs = 0;offs < 0x400;offs++) for (x = 0;x < 8;x++) if (state->m_radarram[offs] & (1 << x)) { int sx, sy; sx = (8 * (offs % 8) + x) + 256-64; sy = ((offs & 0x1ff) / 8) + 96; if (flip_screen_get(machine)) { sx = 255 - sx; sy = 255 - sy; } if (sy >= cliprect->min_y && sy <= cliprect->max_y && sx >= cliprect->min_x && sx <= cliprect->max_x) *BITMAP_ADDR16(bitmap, sy, sx) = offs < 0x200 ? 512 : 513; } } static void draw_sprites(running_machine &machine, bitmap_t *bitmap,const rectangle *cliprect,int priority) { senjyo_state *state = machine.driver_data(); UINT8 *spriteram = state->m_spriteram; int offs; for (offs = state->m_spriteram_size - 4; offs >= 0; offs -= 4) { int big,sx,sy,flipx,flipy; if (((spriteram[offs+1] & 0x30) >> 4) == priority) { if (state->m_is_senjyo) /* Senjyo */ big = (spriteram[offs] & 0x80); else /* Star Force */ big = ((spriteram[offs] & 0xc0) == 0xc0); sx = spriteram[offs+3]; if (big) sy = 224-spriteram[offs+2]; else sy = 240-spriteram[offs+2]; flipx = spriteram[offs+1] & 0x40; flipy = spriteram[offs+1] & 0x80; if (flip_screen_get(machine)) { flipx = !flipx; flipy = !flipy; if (big) { sx = 224 - sx; sy = 226 - sy; } else { sx = 240 - sx; sy = 242 - sy; } } drawgfx_transpen(bitmap,cliprect,machine.gfx[big ? 5 : 4], spriteram[offs], spriteram[offs + 1] & 0x07, flipx,flipy, sx,sy,0); } } } SCREEN_UPDATE( senjyo ) { senjyo_state *state = screen->machine().driver_data(); int i; /* two colors for the radar dots (verified on the real board) */ palette_set_color(screen->machine(),512,MAKE_RGB(0xff,0x00,0x00)); /* red for enemies */ palette_set_color(screen->machine(),513,MAKE_RGB(0xff,0xff,0x00)); /* yellow for player */ { int flip = flip_screen_get(screen->machine()); int scrollx,scrolly; for (i = 0;i < 32;i++) tilemap_set_scrolly(state->m_fg_tilemap, i, state->m_fgscroll[i]); scrollx = state->m_scrollx1[0]; scrolly = state->m_scrolly1[0] + 256 * state->m_scrolly1[1]; if (flip) scrollx = -scrollx; tilemap_set_scrollx(state->m_bg1_tilemap, 0, scrollx); tilemap_set_scrolly(state->m_bg1_tilemap, 0, scrolly); scrollx = state->m_scrollx2[0]; scrolly = state->m_scrolly2[0] + 256 * state->m_scrolly2[1]; if (state->m_scrollhack) /* Star Force, but NOT the encrypted version */ { scrollx = state->m_scrollx1[0]; scrolly = state->m_scrolly1[0] + 256 * state->m_scrolly1[1]; } if (flip) scrollx = -scrollx; tilemap_set_scrollx(state->m_bg2_tilemap, 0, scrollx); tilemap_set_scrolly(state->m_bg2_tilemap, 0, scrolly); scrollx = state->m_scrollx3[0]; scrolly = state->m_scrolly3[0] + 256 * state->m_scrolly3[1]; if (flip) scrollx = -scrollx; tilemap_set_scrollx(state->m_bg3_tilemap, 0, scrollx); tilemap_set_scrolly(state->m_bg3_tilemap, 0, scrolly); } draw_bgbitmap(screen->machine(), bitmap, cliprect); draw_sprites(screen->machine(), bitmap, cliprect, 0); tilemap_draw(bitmap, cliprect, state->m_bg3_tilemap, 0, 0); draw_sprites(screen->machine(), bitmap, cliprect, 1); tilemap_draw(bitmap, cliprect, state->m_bg2_tilemap, 0, 0); draw_sprites(screen->machine(), bitmap, cliprect, 2); tilemap_draw(bitmap, cliprect, state->m_bg1_tilemap, 0, 0); draw_sprites(screen->machine(), bitmap, cliprect, 3); tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 0); draw_radar(screen->machine(), bitmap, cliprect); #if 0 { char baf[80]; UINT8 *senjyo_scrolly3 = state->m_scrolly3; sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x", senjyo_scrolly3[0x00], senjyo_scrolly3[0x01], senjyo_scrolly3[0x02], senjyo_scrolly3[0x03], senjyo_scrolly3[0x04], senjyo_scrolly3[0x05], senjyo_scrolly3[0x06], senjyo_scrolly3[0x07]); ui_draw_text(baf,0,0); sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x", senjyo_scrolly3[0x08], senjyo_scrolly3[0x09], senjyo_scrolly3[0x0a], senjyo_scrolly3[0x0b], senjyo_scrolly3[0x0c], senjyo_scrolly3[0x0d], senjyo_scrolly3[0x0e], senjyo_scrolly3[0x0f]); ui_draw_text(baf,0,10); sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x", senjyo_scrolly3[0x10], senjyo_scrolly3[0x11], senjyo_scrolly3[0x12], senjyo_scrolly3[0x13], senjyo_scrolly3[0x14], senjyo_scrolly3[0x15], senjyo_scrolly3[0x16], senjyo_scrolly3[0x17]); ui_draw_text(baf,0,20); sprintf(baf,"%02x %02x %02x %02x %02x %02x %02x %02x", senjyo_scrolly3[0x18], senjyo_scrolly3[0x19], senjyo_scrolly3[0x1a], senjyo_scrolly3[0x1b], senjyo_scrolly3[0x1c], senjyo_scrolly3[0x1d], senjyo_scrolly3[0x1e], senjyo_scrolly3[0x1f]); ui_draw_text(baf,0,30); } #endif return 0; }