// 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;
}