1 // license:BSD-3-Clause
2 // copyright-holders:Manuel Abadia
3 /***************************************************************************
4 
5   Gaelco Type 1 Video Hardware
6 
7   Functions to emulate the video hardware of the machine
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "includes/gaelco.h"
13 #include "screen.h"
14 
15 /***************************************************************************
16 
17     Callbacks for the TileMap code
18 
19 ***************************************************************************/
20 
21 /*
22     Tile format
23     -----------
24 
25     Screen 0 & 1: (32*32, 16x16 tiles)
26 
27     Word | Bit(s)            | Description
28     -----+-FEDCBA98-76543210-+--------------------------
29       0  | -------- -------x | flip x
30       0  | -------- ------x- | flip y
31       0  | xxxxxxxx xxxxxx-- | code
32       1  | -------- --xxxxxx | color
33       1  | -------- xx------ | priority
34       1  | xxxxxxxx -------- | not used
35 */
36 
37 template<int Layer>
TILE_GET_INFO_MEMBER(gaelco_state::get_tile_info)38 TILE_GET_INFO_MEMBER(gaelco_state::get_tile_info)
39 {
40 	int data = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1)];
41 	int data2 = m_videoram[(Layer * 0x1000 / 2) + (tile_index << 1) + 1];
42 	int code = ((data & 0xfffc) >> 2);
43 
44 	tileinfo.category = (data2 >> 6) & 0x03;
45 
46 	tileinfo.set(1, 0x4000 + code, data2 & 0x3f, TILE_FLIPYX(data & 0x03));
47 }
48 
49 /***************************************************************************
50 
51     Memory Handlers
52 
53 ***************************************************************************/
54 
vram_w(offs_t offset,u16 data,u16 mem_mask)55 void gaelco_state::vram_w(offs_t offset, u16 data, u16 mem_mask)
56 {
57 	uint16_t old = m_videoram[offset];
58 	COMBINE_DATA(&m_videoram[offset]);
59 	if (old != m_videoram[offset])
60 		m_tilemap[offset >> 11]->mark_tile_dirty(((offset << 1) & 0x0fff) >> 2);
61 }
62 
63 /***************************************************************************
64 
65     Start/Stop the video hardware emulation.
66 
67 ***************************************************************************/
68 
VIDEO_START_MEMBER(gaelco_state,bigkarnk)69 VIDEO_START_MEMBER(gaelco_state,bigkarnk)
70 {
71 	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
72 	m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
73 
74 	m_tilemap[0]->set_transmask(0, 0xff01, 0x00ff); // pens 1-7 opaque, pens 0, 8-15 transparent
75 	m_tilemap[1]->set_transmask(0, 0xff01, 0x00ff); // pens 1-7 opaque, pens 0, 8-15 transparent
76 }
77 
VIDEO_START_MEMBER(gaelco_state,maniacsq)78 VIDEO_START_MEMBER(gaelco_state,maniacsq)
79 {
80 	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
81 	m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
82 
83 	m_tilemap[0]->set_transparent_pen(0);
84 	m_tilemap[1]->set_transparent_pen(0);
85 }
86 
87 
88 /***************************************************************************
89 
90     Sprites
91 
92 ***************************************************************************/
93 
94 /*
95     Sprite Format
96     -------------
97 
98     Word | Bit(s)            | Description
99     -----+-FEDCBA98-76543210-+--------------------------
100       0  | -------- xxxxxxxx | y position
101       0  | -----xxx -------- | not used
102       0  | ----x--- -------- | sprite size
103       0  | --xx---- -------- | sprite priority
104       0  | -x------ -------- | flipx
105       0  | x------- -------- | flipy
106       1  | xxxxxxxx xxxxxxxx | not used
107       2  | -------x xxxxxxxx | x position
108       2  | -xxxxxx- -------- | sprite color
109       3  | -------- ------xx | sprite code (8x8 quadrant)
110       3  | xxxxxxxx xxxxxx-- | sprite code
111 */
112 
draw_sprites(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)113 void gaelco_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
114 {
115 	int i, x, y, ex, ey;
116 	gfx_element *gfx = m_gfxdecode->gfx(0);
117 
118 	static const int x_offset[2] = {0x0,0x2};
119 	static const int y_offset[2] = {0x0,0x1};
120 
121 	for (i = 0x800 - 4 - 1; i >= 3; i -= 4)
122 	{
123 		int sx = m_spriteram[i + 2] & 0x01ff;
124 		int sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
125 		int number = m_spriteram[i + 3];
126 		int color = (m_spriteram[i + 2] & 0x7e00) >> 9;
127 		int attr = (m_spriteram[i] & 0xfe00) >> 9;
128 		int priority = (m_spriteram[i] & 0x3000) >> 12;
129 
130 		int xflip = attr & 0x20;
131 		int yflip = attr & 0x40;
132 		int spr_size, pri_mask;
133 
134 		/* palettes 0x38-0x3f are used for high priority sprites in Big Karnak */
135 		if (color >= 0x38)
136 			priority = 4;
137 
138 		switch (priority)
139 		{
140 			case 0: pri_mask = 0xff00; break;
141 			case 1: pri_mask = 0xff00 | 0xf0f0; break;
142 			case 2: pri_mask = 0xff00 | 0xf0f0 | 0xcccc; break;
143 			case 3: pri_mask = 0xff00 | 0xf0f0 | 0xcccc | 0xaaaa; break;
144 			default:
145 			case 4: pri_mask = 0; break;
146 		}
147 
148 		if (attr & 0x04)
149 			spr_size = 1;
150 		else
151 		{
152 			spr_size = 2;
153 			number &= (~3);
154 		}
155 
156 		for (y = 0; y < spr_size; y++)
157 		{
158 			for (x = 0; x < spr_size; x++)
159 			{
160 				ex = xflip ? (spr_size - 1 - x) : x;
161 				ey = yflip ? (spr_size - 1 - y) : y;
162 
163 				gfx->prio_transpen(bitmap,cliprect,number + x_offset[ex] + y_offset[ey],
164 						color,xflip,yflip,
165 						sx-0x0f+x*8,sy+y*8,
166 						screen.priority(),pri_mask,0);
167 			}
168 		}
169 	}
170 }
171 
172 /***************************************************************************
173 
174     Display Refresh
175 
176 ***************************************************************************/
177 
screen_update_maniacsq(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)178 uint32_t gaelco_state::screen_update_maniacsq(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
179 {
180 	/* set scroll registers */
181 	m_tilemap[0]->set_scrolly(0, m_vregs[0]);
182 	m_tilemap[0]->set_scrollx(0, m_vregs[1] + 4);
183 	m_tilemap[1]->set_scrolly(0, m_vregs[2]);
184 	m_tilemap[1]->set_scrollx(0, m_vregs[3]);
185 
186 	screen.priority().fill(0, cliprect);
187 	bitmap.fill(0, cliprect);
188 
189 	m_tilemap[1]->draw(screen, bitmap, cliprect, 3, 0);
190 	m_tilemap[0]->draw(screen, bitmap, cliprect, 3, 0);
191 
192 	m_tilemap[1]->draw(screen, bitmap, cliprect, 2, 1);
193 	m_tilemap[0]->draw(screen, bitmap, cliprect, 2, 1);
194 
195 	m_tilemap[1]->draw(screen, bitmap, cliprect, 1, 2);
196 	m_tilemap[0]->draw(screen, bitmap, cliprect, 1, 2);
197 
198 	m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 4);
199 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 4);
200 
201 	draw_sprites(screen, bitmap, cliprect);
202 	return 0;
203 }
204 
screen_update_bigkarnk(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)205 uint32_t gaelco_state::screen_update_bigkarnk(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
206 {
207 	/* set scroll registers */
208 	m_tilemap[0]->set_scrolly(0, m_vregs[0]);
209 	m_tilemap[0]->set_scrollx(0, m_vregs[1] + 4);
210 	m_tilemap[1]->set_scrolly(0, m_vregs[2]);
211 	m_tilemap[1]->set_scrollx(0, m_vregs[3]);
212 
213 	screen.priority().fill(0, cliprect);
214 	bitmap.fill(0, cliprect);
215 
216 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
217 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
218 
219 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 1);
220 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 1);
221 
222 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
223 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
224 
225 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 2);
226 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 2);
227 
228 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
229 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
230 
231 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
232 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
233 
234 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 4);
235 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 4);
236 
237 	m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
238 	m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
239 
240 	draw_sprites(screen, bitmap, cliprect);
241 	return 0;
242 }
243