/***************************************************************************** B-Wings (c) 1984 Data East Corporation Zaviga (c) 1984 Data East Corporation drivers by Acho A. Tang *****************************************************************************/ // Directives #include "emu.h" #include "includes/bwing.h" #define BW_DEBUG 0 #define BW_NTILES_L2 7 #define BW_NTILES (1<machine().driver_data(); state->m_spriteram[offset] = data; } WRITE8_HANDLER( bwing_videoram_w ) { bwing_state *state = space->machine().driver_data(); state->m_videoram[offset] = data; tilemap_mark_tile_dirty(state->m_charmap, offset); } READ8_HANDLER ( bwing_scrollram_r ) { bwing_state *state = space->machine().driver_data(); int offs; if (!state->m_srbank) offs = state->m_srxlat[offset]; else offs = offset; return ((state->m_srbase[state->m_srbank])[offs]); } WRITE8_HANDLER( bwing_scrollram_w ) { bwing_state *state = space->machine().driver_data(); int offs; if (!state->m_srbank) { offs = state->m_srxlat[offset]; if (offs >> 12) tilemap_mark_tile_dirty(state->m_bgmap, offs & 0xfff); else tilemap_mark_tile_dirty(state->m_fgmap, offs & 0xfff); } else { offs = offset; if (offset < 0x1000) gfx_element_mark_dirty(space->machine().gfx[2], offset / 32); else gfx_element_mark_dirty(space->machine().gfx[3], offset / 32); } (state->m_srbase[state->m_srbank])[offs] = data; } WRITE8_HANDLER( bwing_scrollreg_w ) { bwing_state *state = space->machine().driver_data(); state->m_sreg[offset] = data; switch (offset) { case 6: state->m_palatch = data; break; // one of the palette components is latched through I/O(yike) case 7: // tile graphics are decoded in RAM on the fly and tile codes are banked + interleaved(ouch) state->m_mapmask = data; state->m_srbank = data >> 6; #if BW_DEBUG logerror("(%s)%04x: w=%02x a=%04x f=%d\n", space->device().tag, cpu_get_pc(&space->device()), data, 0x1b00 + offset, space->machine().primary_screen->frame_number()); #endif break; } #if BW_DEBUG (space->machine().region(REGION_CPU1)->base())[0x1b10 + offset] = data; #endif } WRITE8_HANDLER( bwing_paletteram_w ) { bwing_state *state = space->machine().driver_data(); static const float rgb[4][3] = { {0.85f, 0.95f, 1.00f}, {0.90f, 1.00f, 1.00f}, {0.80f, 1.00f, 1.00f}, {0.75f, 0.90f, 1.10f} }; int r, g, b, i; state->m_paletteram[offset] = data; r = ~data & 7; g = ~(data >> 4) & 7; b = ~state->m_palatch & 7; r = ((r << 5) + (r << 2) + (r >> 1)); g = ((g << 5) + (g << 2) + (g >> 1)); b = ((b << 5) + (b << 2) + (b >> 1)); if ((i = input_port_read(space->machine(), "EXTRA")) < 4) { r = (float)r * rgb[i][0]; g = (float)g * rgb[i][1]; b = (float)b * rgb[i][2]; if (r > 0xff) r = 0xff; if (g > 0xff) g = 0xff; if (b > 0xff) b = 0xff; } palette_set_color(space->machine(), offset, MAKE_RGB(r, g, b)); #if BW_DEBUG state->m_paletteram[offset + 0x40] = state->m_palatch; #endif } //**************************************************************************** // Initializations static TILE_GET_INFO( get_fgtileinfo ) { bwing_state *state = machine.driver_data(); tileinfo->pen_data = gfx_element_get_data(machine.gfx[2], state->m_fgdata[tile_index] & (BW_NTILES - 1)); tileinfo->palette_base = machine.gfx[2]->color_base + ((state->m_fgdata[tile_index] >> 7) << 3); } static TILE_GET_INFO( get_bgtileinfo ) { bwing_state *state = machine.driver_data(); tileinfo->pen_data = gfx_element_get_data(machine.gfx[3], state->m_bgdata[tile_index] & (BW_NTILES - 1)); tileinfo->palette_base = machine.gfx[3]->color_base + ((state->m_bgdata[tile_index] >> 7) << 3); } static TILE_GET_INFO( get_charinfo ) { bwing_state *state = machine.driver_data(); SET_TILE_INFO(0, state->m_videoram[tile_index], 0, 0); } static TILEMAP_MAPPER( bwing_scan_cols ) { return ((col << 6) + row); } VIDEO_START( bwing ) { bwing_state *state = machine.driver_data(); UINT32 *dwptr; int i; state->m_charmap = tilemap_create(machine, get_charinfo, tilemap_scan_cols, 8, 8, 32, 32); state->m_fgmap = tilemap_create(machine, get_fgtileinfo, bwing_scan_cols, 16, 16, 64, 64); state->m_bgmap = tilemap_create(machine, get_bgtileinfo, bwing_scan_cols, 16, 16, 64, 64); tilemap_set_transparent_pen(state->m_charmap, 0); tilemap_set_transparent_pen(state->m_fgmap, 0); state->m_srxlat = auto_alloc_array(machine, int, 0x2000); state->save_pointer(NAME(state->m_srxlat), 0x2000); fill_srxlat(state->m_srxlat); state->m_fgdata = machine.region("gpu")->base(); state->m_bgdata = state->m_fgdata + 0x1000; for (i = 0; i < 4; i++) state->m_srbase[i] = state->m_fgdata + i * 0x2000; for (i = 0; i < 8; i++) state->m_sreg[i] = 0; // state->m_fgfx = machine.gfx[2]; gfx_element_set_source(machine.gfx[2], state->m_srbase[1]); // state->m_bgfx = machine.gfx[3]; gfx_element_set_source(machine.gfx[3], state->m_srbase[1] + 0x1000); dwptr = machine.gfx[2]->pen_usage; if (dwptr) { dwptr[0] = 0; for(i = 1; i < BW_NTILES; i++) dwptr[i] = -1; } } //**************************************************************************** // Realtime static void draw_sprites( running_machine &machine, bitmap_t *bmp, const rectangle *clip, UINT8 *ram, int pri ) { bwing_state *state = machine.driver_data(); int attrib, fx, fy, code, x, y, color, i; gfx_element *gfx = machine.gfx[1]; for (i = 0; i < 0x200; i += 4) { attrib = ram[i]; code = ram[i + 1]; y = ram[i + 2]; x = ram[i + 3]; color = (attrib >> 3) & 1; if (!(attrib & 1) || color != pri) continue; code += (attrib << 3) & 0x100; y -= (attrib << 1) & 0x100; x -= (attrib << 2) & 0x100; fx = attrib & 0x04; fy = ~attrib & 0x02; // normal/cocktail if (state->m_mapmask & 0x20) { fx = !fx; fy = !fy; x = 240 - x; y = 240 - y; } // single/double if (!(attrib & 0x10)) drawgfx_transpen(bmp, clip, gfx, code, color, fx, fy, x, y, 0); else drawgfxzoom_transpen(bmp, clip, gfx, code, color, fx, fy, x, y, 1<<16, 2<<16, 0); } } SCREEN_UPDATE( bwing ) { bwing_state *state = screen->machine().driver_data(); unsigned x, y, shiftx; if (state->m_mapmask & 0x20) { state->m_mapflip = TILEMAP_FLIPX; shiftx = -8; } else { state->m_mapflip = TILEMAP_FLIPY; shiftx = 8; } // draw background if (!(state->m_mapmask & 1)) { tilemap_set_flip(state->m_bgmap, state->m_mapflip); x = ((state->m_sreg[1]<<2 & 0x300) + state->m_sreg[2] + shiftx) & 0x3ff; tilemap_set_scrollx(state->m_bgmap, 0, x); y = (state->m_sreg[1]<<4 & 0x300) + state->m_sreg[3]; tilemap_set_scrolly(state->m_bgmap, 0, y); tilemap_draw(bitmap, cliprect, state->m_bgmap, 0, 0); } else bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine())); // draw low priority sprites draw_sprites(screen->machine(), bitmap, cliprect, state->m_spriteram, 0); // draw foreground if (!(state->m_mapmask & 2)) { tilemap_set_flip(state->m_fgmap, state->m_mapflip); x = ((state->m_sreg[1] << 6 & 0x300) + state->m_sreg[4] + shiftx) & 0x3ff; tilemap_set_scrollx(state->m_fgmap, 0, x); y = (state->m_sreg[1] << 8 & 0x300) + state->m_sreg[5]; tilemap_set_scrolly(state->m_fgmap, 0, y); tilemap_draw(bitmap, cliprect, state->m_fgmap, 0, 0); } // draw high priority sprites draw_sprites(screen->machine(), bitmap, cliprect, state->m_spriteram, 1); // draw text layer // if (state->m_mapmask & 4) { tilemap_set_flip(state->m_charmap, state->m_mapflip); tilemap_draw(bitmap, cliprect, state->m_charmap, 0, 0); } return 0; }