/* notes... drawing sprites in a single pass with pdrawgfx breaks Thunder Dragon 2, which seems to expect the sprite priority values to affect sprite-sprite priority. Thunder Dragon 2 also breaks if you support sprite flipping, the collectible point score / power up names appear flipped.. */ #include "emu.h" #include "includes/nmk16.h" // the larger tilemaps on macross2, rapid hero and thunder dragon 2 appear to act like 4 'banks' // of the smaller tilemaps, rather than being able to scroll into each other (not verified on real hw, // but see raphero intro / 1st level cases) /*************************************************************************** Callbacks for the TileMap code ***************************************************************************/ #define TILES_PER_PAGE_X (0x10) #define TILES_PER_PAGE_Y (0x10) #define PAGES_PER_TMAP_X (0x10) #define PAGES_PER_TMAP_Y (0x02) static TILEMAP_MAPPER( afega_tilemap_scan_pages ) { return (row / TILES_PER_PAGE_Y) * TILES_PER_PAGE_X * TILES_PER_PAGE_Y * PAGES_PER_TMAP_X + (row % TILES_PER_PAGE_Y) + (col / TILES_PER_PAGE_X) * TILES_PER_PAGE_X * TILES_PER_PAGE_Y + (col % TILES_PER_PAGE_X) * TILES_PER_PAGE_Y; } static TILE_GET_INFO( macross_get_bg0_tile_info ) { nmk16_state *state = machine.driver_data(); int code = state->m_nmk_bgvideoram0[tile_index]; SET_TILE_INFO(1,(code & 0xfff) + (state->m_bgbank << 12),code >> 12,0); } static TILE_GET_INFO( macross_get_bg1_tile_info ) { nmk16_state *state = machine.driver_data(); int code = state->m_nmk_bgvideoram1[tile_index]; SET_TILE_INFO(1,(code & 0xfff) + (state->m_bgbank << 12),code >> 12,0); } static TILE_GET_INFO( macross_get_bg2_tile_info ) { nmk16_state *state = machine.driver_data(); int code = state->m_nmk_bgvideoram2[tile_index]; SET_TILE_INFO(1,(code & 0xfff) + (state->m_bgbank << 12),code >> 12,0); } static TILE_GET_INFO( macross_get_bg3_tile_info ) { nmk16_state *state = machine.driver_data(); int code = state->m_nmk_bgvideoram3[tile_index]; SET_TILE_INFO(1,(code & 0xfff) + (state->m_bgbank << 12),code >> 12,0); } static TILE_GET_INFO( strahl_get_fg_tile_info ) { nmk16_state *state = machine.driver_data(); int code = state->m_nmk_fgvideoram[tile_index]; SET_TILE_INFO( 3, (code & 0xfff), code >> 12, 0); } static TILE_GET_INFO( macross_get_tx_tile_info ) { nmk16_state *state = machine.driver_data(); int code = state->m_nmk_txvideoram[tile_index]; SET_TILE_INFO( 0, code & 0xfff, code >> 12, 0); } static TILE_GET_INFO( bjtwin_get_bg_tile_info ) { nmk16_state *state = machine.driver_data(); int code = state->m_nmk_bgvideoram0[tile_index]; int bank = (code & 0x800) ? 1 : 0; SET_TILE_INFO( bank, (code & 0x7ff) + ((bank) ? (state->m_bgbank << 11) : 0), code >> 12, 0); } static TILE_GET_INFO( get_tile_info_0_8bit ) { nmk16_state *state = machine.driver_data(); UINT16 code = state->m_nmk_bgvideoram0[tile_index]; SET_TILE_INFO( 1, code, 0, 0); } /*************************************************************************** Start the video hardware emulation. ***************************************************************************/ static void nmk16_video_init(running_machine &machine) { nmk16_state *state = machine.driver_data(); state->m_spriteram_old = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_spriteram_old2 = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_videoshift = 0; /* 256x224 screen, no shift */ state->m_background_bitmap = NULL; state->m_simple_scroll = 1; } VIDEO_START( bioship ) { nmk16_state *state = machine.driver_data(); state->m_bg_tilemap0 = tilemap_create(machine, macross_get_bg0_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create(machine, macross_get_tx_tile_info,tilemap_scan_cols,8,8,32,32); tilemap_set_transparent_pen(state->m_bg_tilemap0,15); tilemap_set_transparent_pen(state->m_tx_tilemap,15); nmk16_video_init(machine); state->m_background_bitmap = auto_bitmap_alloc(machine,8192,512,machine.primary_screen->format()); state->m_bioship_background_bank=0; state->m_redraw_bitmap = 1; } VIDEO_START( strahl ) { nmk16_state *state = machine.driver_data(); state->m_bg_tilemap0 = tilemap_create(machine, macross_get_bg0_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_fg_tilemap = tilemap_create(machine, strahl_get_fg_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create(machine, macross_get_tx_tile_info,tilemap_scan_cols,8,8,32,32); tilemap_set_transparent_pen(state->m_fg_tilemap,15); tilemap_set_transparent_pen(state->m_tx_tilemap,15); nmk16_video_init(machine); } VIDEO_START( macross ) { nmk16_state *state = machine.driver_data(); state->m_bg_tilemap0 = tilemap_create(machine, macross_get_bg0_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create(machine, macross_get_tx_tile_info,tilemap_scan_cols,8,8,32,32); tilemap_set_transparent_pen(state->m_tx_tilemap,15); nmk16_video_init(machine); } VIDEO_START( gunnail ) { nmk16_state *state = machine.driver_data(); state->m_bg_tilemap0 = tilemap_create(machine, macross_get_bg0_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create(machine, macross_get_tx_tile_info,tilemap_scan_cols,8,8,64,32); tilemap_set_transparent_pen(state->m_tx_tilemap,15); tilemap_set_scroll_rows(state->m_bg_tilemap0,512); nmk16_video_init(machine); state->m_videoshift = 64; /* 384x224 screen, leftmost 64 pixels have to be retrieved */ /* from the other side of the tilemap (!) */ state->m_simple_scroll = 0; } VIDEO_START( macross2 ) { nmk16_state *state = machine.driver_data(); state->m_bg_tilemap0 = tilemap_create(machine, macross_get_bg0_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_bg_tilemap1 = tilemap_create(machine, macross_get_bg1_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_bg_tilemap2 = tilemap_create(machine, macross_get_bg2_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_bg_tilemap3 = tilemap_create(machine, macross_get_bg3_tile_info, afega_tilemap_scan_pages,16,16,TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create(machine, macross_get_tx_tile_info,tilemap_scan_cols,8,8,64,32); tilemap_set_transparent_pen(state->m_tx_tilemap,15); nmk16_video_init(machine); state->m_videoshift = 64; /* 384x224 screen, leftmost 64 pixels have to be retrieved */ /* from the other side of the tilemap (!) */ } VIDEO_START( raphero ) { nmk16_state *state = machine.driver_data(); VIDEO_START_CALL( macross2 ); state->m_simple_scroll = 0; } VIDEO_START( bjtwin ) { nmk16_state *state = machine.driver_data(); state->m_bg_tilemap0 = tilemap_create(machine, bjtwin_get_bg_tile_info,tilemap_scan_cols,8,8,64,32); nmk16_video_init(machine); state->m_videoshift = 64; /* 384x224 screen, leftmost 64 pixels have to be retrieved */ /* from the other side of the tilemap (!) */ } /*************************************************************************** Memory handlers ***************************************************************************/ WRITE16_HANDLER( nmk_bgvideoram0_w ) { nmk16_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_nmk_bgvideoram0[offset]); tilemap_mark_tile_dirty(state->m_bg_tilemap0,offset); } WRITE16_HANDLER( nmk_bgvideoram1_w ) { nmk16_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_nmk_bgvideoram1[offset]); tilemap_mark_tile_dirty(state->m_bg_tilemap1,offset); } WRITE16_HANDLER( nmk_bgvideoram2_w ) { nmk16_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_nmk_bgvideoram2[offset]); tilemap_mark_tile_dirty(state->m_bg_tilemap2,offset); } WRITE16_HANDLER( nmk_bgvideoram3_w ) { nmk16_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_nmk_bgvideoram3[offset]); tilemap_mark_tile_dirty(state->m_bg_tilemap3,offset); } WRITE16_HANDLER( nmk_fgvideoram_w ) { nmk16_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_nmk_fgvideoram[offset]); tilemap_mark_tile_dirty(state->m_fg_tilemap,offset); } WRITE16_HANDLER( nmk_txvideoram_w ) { nmk16_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_nmk_txvideoram[offset]); tilemap_mark_tile_dirty(state->m_tx_tilemap,offset); } WRITE16_HANDLER( mustang_scroll_w ) { nmk16_state *state = space->machine().driver_data(); // mame_printf_debug("mustang %04x %04x %04x\n",offset,data,mem_mask); switch (data & 0xff00) { case 0x0000: state->m_mustang_bg_xscroll = (state->m_mustang_bg_xscroll & 0x00ff) | ((data & 0x00ff)<<8); break; case 0x0100: state->m_mustang_bg_xscroll = (state->m_mustang_bg_xscroll & 0xff00) | (data & 0x00ff); break; case 0x0200: break; case 0x0300: break; default: break; } tilemap_set_scrollx(state->m_bg_tilemap0,0,state->m_mustang_bg_xscroll - state->m_videoshift); } WRITE16_HANDLER( bioshipbg_scroll_w ) { nmk16_state *state = space->machine().driver_data(); if (ACCESSING_BITS_8_15) { state->m_scroll[offset] = (data >> 8) & 0xff; if (offset & 2) tilemap_set_scrolly(state->m_bg_tilemap0,0,state->m_scroll[2] * 256 + state->m_scroll[3]); else tilemap_set_scrollx(state->m_bg_tilemap0,0,state->m_scroll[0] * 256 + state->m_scroll[1] - state->m_videoshift); } } WRITE16_HANDLER( nmk_scroll_w ) { nmk16_state *state = space->machine().driver_data(); if (ACCESSING_BITS_0_7) { state->m_scroll[offset] = data & 0xff; if (offset & 2) tilemap_set_scrolly(state->m_bg_tilemap0,0,state->m_scroll[2] * 256 + state->m_scroll[3]); else tilemap_set_scrollx(state->m_bg_tilemap0,0,state->m_scroll[0] * 256 + state->m_scroll[1] - state->m_videoshift); } } WRITE16_HANDLER( nmk_scroll_2_w ) { nmk16_state *state = space->machine().driver_data(); if (ACCESSING_BITS_0_7) { state->m_scroll_2[offset] = data & 0xff; if (offset & 2) tilemap_set_scrolly(state->m_fg_tilemap,0,state->m_scroll_2[2] * 256 + state->m_scroll_2[3]); else tilemap_set_scrollx(state->m_fg_tilemap,0,state->m_scroll_2[0] * 256 + state->m_scroll_2[1] - state->m_videoshift); } } WRITE16_HANDLER( vandyke_scroll_w ) { nmk16_state *state = space->machine().driver_data(); state->m_vscroll[offset] = data; tilemap_set_scrollx(state->m_bg_tilemap0,0,state->m_vscroll[0] * 256 + (state->m_vscroll[1] >> 8)); tilemap_set_scrolly(state->m_bg_tilemap0,0,state->m_vscroll[2] * 256 + (state->m_vscroll[3] >> 8)); } WRITE16_HANDLER( vandykeb_scroll_w ) { nmk16_state *state = space->machine().driver_data(); switch (offset) { case 0: COMBINE_DATA(&state->m_vscroll[3]); break; case 1: COMBINE_DATA(&state->m_vscroll[2]); break; case 5: COMBINE_DATA(&state->m_vscroll[1]); break; case 6: COMBINE_DATA(&state->m_vscroll[0]); break; } tilemap_set_scrollx(state->m_bg_tilemap0,0,state->m_vscroll[0] * 256 + (state->m_vscroll[1] >> 8)); tilemap_set_scrolly(state->m_bg_tilemap0,0,state->m_vscroll[2] * 256 + (state->m_vscroll[3] >> 8)); } WRITE16_HANDLER( manybloc_scroll_w ) { nmk16_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_gunnail_scrollram[offset]); tilemap_set_scrollx(state->m_bg_tilemap0,0,state->m_gunnail_scrollram[0x82/2]-state->m_videoshift); tilemap_set_scrolly(state->m_bg_tilemap0,0,state->m_gunnail_scrollram[0xc2/2]); } WRITE16_HANDLER( nmk_flipscreen_w ) { if (ACCESSING_BITS_0_7) flip_screen_set(space->machine(), data & 0x01); } WRITE16_HANDLER( nmk_tilebank_w ) { nmk16_state *state = space->machine().driver_data(); if (ACCESSING_BITS_0_7) { if (state->m_bgbank != (data & 0xff)) { state->m_bgbank = data & 0xff; tilemap_mark_all_tiles_dirty(state->m_bg_tilemap0); } } } WRITE16_HANDLER( bioship_scroll_w ) { nmk16_state *state = space->machine().driver_data(); if (ACCESSING_BITS_8_15) state->m_bioship_scroll[offset]=data>>8; } WRITE16_HANDLER( bioship_bank_w ) { nmk16_state *state = space->machine().driver_data(); if (ACCESSING_BITS_0_7) { if (state->m_bioship_background_bank != data) { state->m_bioship_background_bank = data; state->m_redraw_bitmap=1; } } } /*************************************************************************** Display refresh ***************************************************************************/ // manybloc uses extra flip bits on the sprites, but these break other games static void nmk16_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int priority) { nmk16_state *state = machine.driver_data(); int offs; for (offs = 0;offs < 0x1000/2;offs += 8) { if ((state->m_spriteram_old2[offs] & 0x0001)) { int sx = (state->m_spriteram_old2[offs+4] & 0x1ff) + state->m_videoshift; int sy = (state->m_spriteram_old2[offs+6] & 0x1ff); int code = state->m_spriteram_old2[offs+3]; int color = state->m_spriteram_old2[offs+7]; int w = (state->m_spriteram_old2[offs+1] & 0x0f); int h = ((state->m_spriteram_old2[offs+1] & 0xf0) >> 4); int pri = (state->m_spriteram_old2[offs] & 0xc0) >> 6; int xx,yy,x; int delta = 16; if(pri != priority) continue; if (flip_screen_get(machine)) { sx = 368 - sx; sy = 240 - sy; delta = -16; } yy = h; do { x = sx; xx = w; do { drawgfx_transpen(bitmap,cliprect,machine.gfx[2], code, color, flip_screen_get(machine), flip_screen_get(machine), ((x + 16) & 0x1ff) - 16,sy & 0x1ff,15); code++; x += delta; } while (--xx >= 0); sy += delta; } while (--yy >= 0); } } } static void nmk16_draw_sprites_flipsupported(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int priority) { nmk16_state *state = machine.driver_data(); int offs; for (offs = 0;offs < 0x1000/2;offs += 8) { if (state->m_spriteram_old2[offs] & 0x0001) { int sx = (state->m_spriteram_old2[offs+4] & 0x1ff) + state->m_videoshift; int sy = (state->m_spriteram_old2[offs+6] & 0x1ff); int code = state->m_spriteram_old2[offs+3]; int color = state->m_spriteram_old2[offs+7]; int w = (state->m_spriteram_old2[offs+1] & 0x0f); int h = ((state->m_spriteram_old2[offs+1] & 0xf0) >> 4); int pri = (state->m_spriteram_old2[offs] & 0xc0) >> 6; int flipy= ((state->m_spriteram_old2[offs+1] & 0x0200) >> 9); int flipx = ((state->m_spriteram_old2[offs+1] & 0x0100) >> 8); int xx,yy,x; int delta = 16; if(pri != priority) continue; flipx ^= flip_screen_get(machine); flipy ^= flip_screen_get(machine); if (flip_screen_get(machine)) { sx = 368 - sx; sy = 240 - sy; delta = -16; } yy = h; sy+=flipy?(delta*h):0; do { x = sx+(flipx?(delta*w):0); xx = w; do { drawgfx_transpen(bitmap,cliprect,machine.gfx[2], code, color, flipx, flipy, ((x + 16) & 0x1ff) - 16,sy & 0x1ff,15); code++; x +=delta * ( flipx?-1:1 ); } while (--xx >= 0); sy += delta * ( flipy?-1:1); } while (--yy >= 0); } } } SCREEN_UPDATE( macross ) { nmk16_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( tdragon ) { nmk16_state *state = screen->machine().driver_data(); // mcu_run(screen->machine(), 1); tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( hachamf ) { nmk16_state *state = screen->machine().driver_data(); // mcu_run(screen->machine(), 0); tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( manybloc ) { nmk16_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( tharrier ) { nmk16_state *state = screen->machine().driver_data(); /* I think the protection device probably copies this to the regs... */ UINT16 tharrier_scroll = state->m_mainram[0x9f00/2]; tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); tilemap_set_scrollx(state->m_bg_tilemap0,0,tharrier_scroll); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( gunnail ) { nmk16_state *state = screen->machine().driver_data(); int y1; int i=16; rectangle bgclip = *cliprect; // the hardware supports per-scanline X *and* Y scroll which isn't // supported by tilemaps so we have to draw the tilemap one line at a time y1 = cliprect->min_y; if (!state->m_simple_scroll) { while (y1 <= cliprect->max_y) { int const yscroll = state->m_gunnail_scrollramy[0] + state->m_gunnail_scrollramy[y1]; int tilemap_bank_select; tilemap_t* bg_tilemap = state->m_bg_tilemap0; bgclip.min_y = y1; bgclip.max_y = y1; tilemap_bank_select = (state->m_gunnail_scrollram[0]&0x3000)>>12; switch (tilemap_bank_select) { case 0: if (state->m_bg_tilemap0) bg_tilemap = state->m_bg_tilemap0; break; case 1: if (state->m_bg_tilemap1) bg_tilemap = state->m_bg_tilemap1; break; case 2: if (state->m_bg_tilemap2) bg_tilemap = state->m_bg_tilemap2; break; case 3: if (state->m_bg_tilemap3) bg_tilemap = state->m_bg_tilemap3; break; } tilemap_set_scroll_rows(bg_tilemap,512); tilemap_set_scrolly(bg_tilemap, 0, yscroll); tilemap_set_scrollx(bg_tilemap,(i + yscroll) & 0x1ff, state->m_gunnail_scrollram[0] + state->m_gunnail_scrollram[i] - state->m_videoshift); tilemap_draw(bitmap,&bgclip,bg_tilemap,0,0); y1++; i++; } } else { UINT16 yscroll = ((state->m_gunnail_scrollram[2]&0xff)<<8) | ((state->m_gunnail_scrollram[3]&0xff)<<0); UINT16 xscroll = ((state->m_gunnail_scrollram[0]&0xff)<<8) | ((state->m_gunnail_scrollram[1]&0xff)<<0); int tilemap_bank_select; tilemap_t* bg_tilemap = state->m_bg_tilemap0; //popmessage( "scroll %04x, %04x", yscroll,xscroll); tilemap_bank_select = (xscroll&0x3000)>>12; switch (tilemap_bank_select) { case 0: if (state->m_bg_tilemap0) bg_tilemap = state->m_bg_tilemap0; break; case 1: if (state->m_bg_tilemap1) bg_tilemap = state->m_bg_tilemap1; break; case 2: if (state->m_bg_tilemap2) bg_tilemap = state->m_bg_tilemap2; break; case 3: if (state->m_bg_tilemap3) bg_tilemap = state->m_bg_tilemap3; break; } tilemap_set_scroll_rows(bg_tilemap,1); tilemap_set_scrolly(bg_tilemap, 0, yscroll); tilemap_set_scrollx(bg_tilemap, 0, xscroll - state->m_videoshift); tilemap_draw(bitmap,cliprect,bg_tilemap,0,0); } nmk16_draw_sprites(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,0); tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( bioship ) { nmk16_state *state = screen->machine().driver_data(); UINT16 *tilerom = (UINT16 *)screen->machine().region("gfx5")->base(); int scrollx=-(state->m_bioship_scroll[1] + state->m_bioship_scroll[0]*256); int scrolly=-(state->m_bioship_scroll[3] + state->m_bioship_scroll[2]*256); tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); if (state->m_redraw_bitmap) { int bank = state->m_bioship_background_bank * 0x2000; int sx=0, sy=0, offs; state->m_redraw_bitmap=0; /* Draw background from tile rom */ for (offs = 0;offs <0x1000;offs++) { UINT16 data = tilerom[offs+bank]; int numtile = data&0xfff; int color = (data&0xf000)>>12; drawgfx_opaque(state->m_background_bitmap,0,screen->machine().gfx[3], numtile, color, 0,0, /* no flip */ 16*sx,16*sy); data = tilerom[offs+0x1000+bank]; numtile = data&0xfff; color = (data&0xf000)>>12; drawgfx_opaque(state->m_background_bitmap,0,screen->machine().gfx[3], numtile, color, 0,0, /* no flip */ 16*sx,(16*sy)+256); sy++; if (sy==16) {sy=0; sx++;} } } copyscrollbitmap(bitmap,state->m_background_bitmap,1,&scrollx,1,&scrolly,cliprect); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( strahl ) { nmk16_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_tx_tilemap,0,-state->m_videoshift); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); tilemap_draw(bitmap,cliprect,state->m_fg_tilemap,0,0); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; } SCREEN_UPDATE( bjtwin ) { nmk16_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_bg_tilemap0,0,-state->m_videoshift); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites(screen->machine(), bitmap,cliprect,0); return 0; } SCREEN_EOF( nmk ) { nmk16_state *state = machine.driver_data(); /* sprites are DMA'd from Main RAM to a private buffer automatically (or at least this is how I interpret the datasheet) */ /* -- I actually see little evidence to support this, sprite lag in some games should be checked on real boards */ // memcpy(state->m_spriteram_old2,state->m_spriteram_old,0x1000); memcpy(state->m_spriteram_old2,state->m_mainram+0x8000/2,0x1000); } SCREEN_EOF( strahl ) { nmk16_state *state = machine.driver_data(); /* sprites are DMA'd from Main RAM to a private buffer automatically (or at least this is how I interpret the datasheet) */ /* -- I actually see little evidence to support this, sprite lag in some games should be checked on real boards */ /* strahl sprites are allocated in memory range FF000-FFFFF */ memcpy(state->m_spriteram_old2,state->m_mainram+0xF000/2,0x1000); } /*************************************************************************** Video Hardware Init ***************************************************************************/ VIDEO_START( afega ) { nmk16_state *state = machine.driver_data(); state->m_spriteram_old = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_spriteram_old2 = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_bg_tilemap0 = tilemap_create( machine, macross_get_bg0_tile_info, afega_tilemap_scan_pages, 16,16, TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create( machine, macross_get_tx_tile_info, tilemap_scan_cols, 8,8, 32,32); tilemap_set_transparent_pen(state->m_tx_tilemap,0xf); } VIDEO_START( grdnstrm ) { nmk16_state *state = machine.driver_data(); state->m_spriteram_old = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_spriteram_old2 = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_bg_tilemap0 = tilemap_create( machine, get_tile_info_0_8bit, afega_tilemap_scan_pages, 16,16, TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create( machine, macross_get_tx_tile_info, tilemap_scan_cols, 8,8, 32,32); tilemap_set_transparent_pen(state->m_tx_tilemap,0xf); } VIDEO_START( firehawk ) { nmk16_state *state = machine.driver_data(); state->m_spriteram_old = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_spriteram_old2 = auto_alloc_array_clear(machine, UINT16, 0x1000/2); state->m_bg_tilemap0 = tilemap_create( machine, get_tile_info_0_8bit, afega_tilemap_scan_pages, 16,16, TILES_PER_PAGE_X*PAGES_PER_TMAP_X,TILES_PER_PAGE_Y*PAGES_PER_TMAP_Y); state->m_tx_tilemap = tilemap_create( machine, macross_get_tx_tile_info, tilemap_scan_cols, 8,8, 32,32); tilemap_set_transparent_pen(state->m_tx_tilemap,0xf); } /*************************************************************************** Screen Drawing ***************************************************************************/ static void video_update(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int dsw_flipscreen, // 1 = Horizontal and vertical screen flip are hardwired to 2 dip switches int xoffset, int yoffset, // bg_tilemap0 offsets int attr_mask // "sprite active" mask ) { nmk16_state *state = machine.driver_data(); if (dsw_flipscreen) { flip_screen_x_set(machine, ~input_port_read(machine, "DSW1") & 0x0100); flip_screen_y_set(machine, ~input_port_read(machine, "DSW1") & 0x0200); } tilemap_set_scrollx(state->m_bg_tilemap0, 0, state->m_afega_scroll_0[1] + xoffset); tilemap_set_scrolly(state->m_bg_tilemap0, 0, state->m_afega_scroll_0[0] + yoffset); tilemap_set_scrollx(state->m_tx_tilemap, 0, state->m_afega_scroll_1[1]); tilemap_set_scrolly(state->m_tx_tilemap, 0, state->m_afega_scroll_1[0]); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,3); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,2); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,1); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); } static void redhawki_video_update(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect ) { nmk16_state *state = machine.driver_data(); tilemap_set_scrollx(state->m_bg_tilemap0, 0, state->m_afega_scroll_1[0]&0xff); tilemap_set_scrolly(state->m_bg_tilemap0, 0, state->m_afega_scroll_1[1]&0xff); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,3); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,2); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,1); nmk16_draw_sprites_flipsupported(machine, bitmap,cliprect,0); } SCREEN_UPDATE( afega ) { video_update(screen->machine(),bitmap,cliprect, 1, -0x100,+0x000, 0x0001); return 0; } SCREEN_UPDATE( bubl2000 ) { video_update(screen->machine(),bitmap,cliprect, 0, -0x100,+0x000, 0x0001); return 0; } // no flipscreen support, I really would confirmation from the schematics SCREEN_UPDATE( redhawkb ) { video_update(screen->machine(),bitmap,cliprect, 0, +0x000,+0x100, 0x0001); return 0; } SCREEN_UPDATE( redhawki ) { redhawki_video_update(screen->machine(),bitmap,cliprect); return 0;} // strange scroll regs SCREEN_UPDATE( firehawk ) { nmk16_state *state = screen->machine().driver_data(); tilemap_set_scrolly(state->m_bg_tilemap0, 0, state->m_afega_scroll_1[1] + 0x100); tilemap_set_scrollx(state->m_bg_tilemap0, 0, state->m_afega_scroll_1[0]); tilemap_draw(bitmap,cliprect,state->m_bg_tilemap0,0,0); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,3); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,2); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,1); nmk16_draw_sprites_flipsupported(screen->machine(), bitmap,cliprect,0); tilemap_draw(bitmap,cliprect,state->m_tx_tilemap,0,0); return 0; }