// license:BSD-3-Clause // copyright-holders:Chris Hardy /*************************************************************************** warpwarp.c Functions to emulate the video hardware of the machine. ***************************************************************************/ #include "emu.h" #include "video/resnet.h" #include "includes/warpwarp.h" static constexpr rgb_t geebee_pens[] = { rgb_t(0x00,0x00,0x00), /* black */ rgb_t(0xff,0xff,0xff), /* white */ rgb_t(0x7f,0x7f,0x7f) /* grey */ }; void warpwarp_state::geebee_palette(palette_device &palette) const { palette.set_pen_color(0, geebee_pens[0]); palette.set_pen_color(1, geebee_pens[1]); palette.set_pen_color(2, geebee_pens[1]); palette.set_pen_color(3, geebee_pens[0]); palette.set_pen_color(4, geebee_pens[0]); palette.set_pen_color(5, geebee_pens[2]); palette.set_pen_color(6, geebee_pens[2]); palette.set_pen_color(7, geebee_pens[0]); } void warpwarp_state::navarone_palette(palette_device &palette) const { palette.set_pen_color(0, geebee_pens[0]); palette.set_pen_color(1, geebee_pens[1]); palette.set_pen_color(2, geebee_pens[1]); palette.set_pen_color(3, geebee_pens[0]); } MACHINE_RESET_MEMBER(warpwarp_state,kaitei) { // Some PCB videos/images shows a b&w arrangement, others a full colorized one. // This is due of the monitor type used, cfr. http://news.livedoor.com/article/detail/5604337/ // We change color palette at reset time, according to the configuration switch. if (m_in_config->read() & 1) // color { m_palette->set_pen_color(0, rgb_t(0x00,0x00,0x00)); m_palette->set_pen_color(1, rgb_t(0x00,0xff,0xff)); m_palette->set_pen_color(2, rgb_t(0x00,0xff,0xff)); m_palette->set_pen_color(3, rgb_t(0x00,0x00,0x00)); m_palette->set_pen_color(4, rgb_t(0x00,0x00,0x00)); m_palette->set_pen_color(5, rgb_t(0x00,0xff,0x00)); m_palette->set_pen_color(6, rgb_t(0x00,0xff,0x00)); m_palette->set_pen_color(7, rgb_t(0x00,0x00,0x00)); m_palette->set_pen_color(8, rgb_t(0xff,0x00,0x00)); // ball pen } else // b & w { m_palette->set_pen_color(0, geebee_pens[0]); m_palette->set_pen_color(1, geebee_pens[1]); m_palette->set_pen_color(2, geebee_pens[1]); m_palette->set_pen_color(3, geebee_pens[0]); m_palette->set_pen_color(4, geebee_pens[0]); m_palette->set_pen_color(5, geebee_pens[1]); m_palette->set_pen_color(6, geebee_pens[1]); m_palette->set_pen_color(7, geebee_pens[0]); m_palette->set_pen_color(8, geebee_pens[1]); // ball pen } } /*************************************************************************** Warp Warp doesn't use PROMs - the 8-bit code is directly converted into a color. The color RAM is connected to the RGB output this way: bit 7 -- 390 ohm resistor -- BLUE -- 820 ohm resistor -- BLUE -- 390 ohm resistor -- GREEN -- 820 ohm resistor -- GREEN -- 1.6kohm resistor -- GREEN -- 390 ohm resistor -- RED -- 820 ohm resistor -- RED bit 0 -- 1.6kohm resistor -- RED Moreover, the bullet is pure white, obtained with three 220 ohm resistors. ***************************************************************************/ void warpwarp_state::warpwarp_palette(palette_device &palette) const { static constexpr int resistances_tiles_rg[] = { 1600, 820, 390 }; static constexpr int resistances_tiles_b[] = { 820, 390 }; static constexpr int resistance_ball[] = { 220 }; double weights_tiles_rg[3], weights_tiles_b[2], weight_ball[1]; compute_resistor_weights(0, 0xff, -1.0, 3, resistances_tiles_rg, weights_tiles_rg, 150, 0, 2, resistances_tiles_b, weights_tiles_b, 150, 0, 1, resistance_ball, weight_ball, 150, 0); for (int i = 0; i < 0x100; i++) { int bit0, bit1, bit2; // red component bit0 = BIT(i, 0); bit1 = BIT(i, 1); bit2 = BIT(i, 2); int const r = combine_weights(weights_tiles_rg, bit0, bit1, bit2); // green component bit0 = BIT(i, 3); bit1 = BIT(i, 4); bit2 = BIT(i, 5); int const g = combine_weights(weights_tiles_rg, bit0, bit1, bit2); // blue component bit0 = BIT(i, 6); bit1 = BIT(i, 7); int const b = combine_weights(weights_tiles_b, bit0, bit1); palette.set_pen_color((i << 1) | 0, rgb_t::black()); palette.set_pen_color((i << 1) | 1, rgb_t(r, g, b)); } palette.set_pen_color(0x200, rgb_t(weight_ball[0], weight_ball[0], weight_ball[0])); } /*************************************************************************** Callbacks for the TileMap code ***************************************************************************/ /* convert from 32x32 to 34x28 */ TILEMAP_MAPPER_MEMBER(warpwarp_state::tilemap_scan) { int offs; row += 2; col--; if (col & 0x20) offs = row + ((col & 1) << 5); else offs = col + (row << 5); return offs; } TILE_GET_INFO_MEMBER(warpwarp_state::geebee_get_tile_info) { int code = m_geebee_videoram[tile_index]; int color = (m_geebee_bgw & 1) | ((code & 0x80) >> 6); SET_TILE_INFO_MEMBER(0, code, color, 0); } TILE_GET_INFO_MEMBER(warpwarp_state::navarone_get_tile_info) { int code = m_geebee_videoram[tile_index]; int color = m_geebee_bgw & 1; SET_TILE_INFO_MEMBER(0, code, color, 0); } TILE_GET_INFO_MEMBER(warpwarp_state::warpwarp_get_tile_info) { SET_TILE_INFO_MEMBER(0, m_videoram[tile_index], m_videoram[tile_index + 0x400], 0); } /*************************************************************************** Start the video hardware emulation. ***************************************************************************/ VIDEO_START_MEMBER(warpwarp_state,geebee) { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(warpwarp_state::geebee_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(warpwarp_state::tilemap_scan)), 8,8, 34,28); } VIDEO_START_MEMBER(warpwarp_state,navarone) { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(warpwarp_state::navarone_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(warpwarp_state::tilemap_scan)), 8,8, 34,28); } VIDEO_START_MEMBER(warpwarp_state,warpwarp) { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(warpwarp_state::warpwarp_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(warpwarp_state::tilemap_scan)), 8,8, 34,28); } /*************************************************************************** Memory handlers ***************************************************************************/ WRITE8_MEMBER(warpwarp_state::geebee_videoram_w) { m_geebee_videoram[offset] = data; m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); } WRITE8_MEMBER(warpwarp_state::warpwarp_videoram_w) { m_videoram[offset] = data; m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); } /*************************************************************************** Display refresh ***************************************************************************/ inline void warpwarp_state::plot(bitmap_ind16 &bitmap, const rectangle &cliprect, int x, int y, pen_t pen) { if (cliprect.contains(x, y)) bitmap.pix16(y, x) = pen; } void warpwarp_state::draw_ball(bitmap_ind16 &bitmap, const rectangle &cliprect,pen_t pen) { if (m_ball_on) { int x,y,i,j; x = 264 - m_ball_h; y = 240 - m_ball_v; for (i = m_ball_sizey;i > 0;i--) for (j = m_ball_sizex;j > 0;j--) plot(bitmap, cliprect, x-j, y-i, pen); } } uint32_t warpwarp_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0); draw_ball(bitmap, cliprect, m_ball_pen); return 0; }