summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/crbaloon.cpp
blob: 1078215e3bbf48c8cea3d6e130a15f887271cabd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
/***************************************************************************

  video.c

  Functions to emulate the video hardware of the machine.

***************************************************************************/

#include "emu.h"
#include "includes/crbaloon.h"


/***************************************************************************

  Convert the color PROMs into a more useable format.

  Crazy Balloon has no PROMs, the color code directly maps to a color:
  all bits are inverted
  bit 3 HALF (intensity)
  bit 2 BLUE
  bit 1 GREEN
  bit 0 RED

***************************************************************************/

void crbaloon_state::crbaloon_palette(palette_device &palette) const
{
	for (int i = 0; i < palette.entries(); i++)
	{
		uint8_t const pen = BIT(i, 0) ? (i >> 1) : 0x0f;

		int const h = BIT(~pen, 3) ? 0xff : 0x55;
		int const r = h * BIT(~pen, 0);
		int const g = h * BIT(~pen, 1);
		int const b = h * BIT(~pen, 2);

		palette.set_pen_color(i, rgb_t(r, g, b));
	}
}


WRITE8_MEMBER(crbaloon_state::crbaloon_videoram_w)
{
	m_videoram[offset] = data;
	m_bg_tilemap->mark_tile_dirty(offset);
}

WRITE8_MEMBER(crbaloon_state::crbaloon_colorram_w)
{
	m_colorram[offset] = data;
	m_bg_tilemap->mark_tile_dirty(offset);
}

TILE_GET_INFO_MEMBER(crbaloon_state::get_bg_tile_info)
{
	int code = m_videoram[tile_index];
	int color = m_colorram[tile_index] & 0x0f;

	SET_TILE_INFO_MEMBER(0, code, color, 0);
}

void crbaloon_state::video_start()
{
	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(crbaloon_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS_FLIP_XY,  8, 8, 32, 32);

	save_item(NAME(m_collision_address));
	save_item(NAME(m_collision_address_clear));
}


uint16_t crbaloon_state::crbaloon_get_collision_address()
{
	return m_collision_address_clear ? 0xffff : m_collision_address;
}


void crbaloon_state::crbaloon_set_clear_collision_address(int _crbaloon_collision_address_clear)
{
	m_collision_address_clear = !_crbaloon_collision_address_clear; /* active LO */
}



void crbaloon_state::draw_sprite_and_check_collision(bitmap_ind16 &bitmap)
{
	int y;
	uint8_t code = m_spriteram[0] & 0x0f;
	uint8_t color = m_spriteram[0] >> 4;
	uint8_t sy = m_spriteram[2] - 32;

	uint8_t *gfx = memregion("gfx2")->base() + (code << 7);


	if (flip_screen())
		sy += 32;

	/* assume no collision */
	m_collision_address = 0xffff;

	for (y = 0x1f; y >= 0; y--)
	{
		int x;
		uint8_t data = 0;
		uint8_t sx = m_spriteram[1];

		for (x = 0x1f; x >= 0; x--)
		{
			int bit;

			if ((x & 0x07) == 0x07)
				/* get next byte to draw, but no drawing in VBLANK */
				data = (sy >= 0xe0) ? 0 : gfx[((x >> 3) << 5) | y];

			bit = data & 0x80;

			/* draw the current pixel, but check collision first */
			if (bit)
			{
				if (bitmap.pix16(sy, sx) & 0x01)
					/* compute the collision address -- the +1 is via observation
					   of the game code, probably wrong for cocktail mode */
					m_collision_address = ((((sy ^ 0xff) >> 3) << 5) | ((sx ^ 0xff) >> 3)) + 1;

				bitmap.pix16(sy, sx) = (color << 1) | 1;
			}

			sx = sx + 1;
			data = data << 1;
		}

		sy = sy + 1;
	}
}


uint32_t crbaloon_state::screen_update_crbaloon(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);

	draw_sprite_and_check_collision(bitmap);

	return 0;
}