1 /***************************************************************************
2 
3 							  -= Unico Games =-
4 
5 					driver by	Luca Elia (l.elia@tin.it)
6 
7 
8 Note:	if MAME_DEBUG is defined, pressing Z with:
9 
10 		Q / W / E		Shows Layer 0 / 1 / 2
11 		A				Shows Sprites
12 
13 		Keys can be used together!
14 
15 
16 	[ 3 Scrolling Layers ]
17 
18 		Tile Size:				16 x 16 x 8
19 		Layer Size (tiles):		64 x 64
20 
21 	[ 512 Sprites ]
22 
23 		Sprites are made of 16 x 16 x 8 tiles. Size can vary from 1 to
24 		16 tiles horizontally, while their height is always 1 tile.
25 		There seems to be 4 levels of priority (wrt layers) for each
26 		sprite, following this simple scheme:
27 
28 		[if we denote the three layers with 0-3 (0 being the backmost)
29 		 and the sprite with S]
30 
31 		Sprite Priority			Order (back -> front)
32 				0					S 0 1 2
33 				1					0 S 1 2
34 				2					0 1 S 2
35 				3					0 1 2 S
36 
37 ***************************************************************************/
38 
39 #include "driver.h"
40 #include "vidhrdw/generic.h"
41 #include "unico.h"
42 
43 /* Variables defined in drivers: */
44 
45 extern int unico_has_lightgun;
46 
47 /* Variables needed by drivers: */
48 
49 data16_t *unico_vram_0,   *unico_scrollx_0, *unico_scrolly_0;
50 data16_t *unico_vram_1,   *unico_scrollx_1, *unico_scrolly_1;
51 data16_t *unico_vram_2,   *unico_scrollx_2, *unico_scrolly_2;
52 data32_t *unico_vram32_0, *unico_vram32_1, *unico_vram32_2, *unico_scroll32;
53 
54 
55 /***************************************************************************
56 
57 									Palette
58 
59 	Byte: 	0	1	2	3
60 	Gun:	R	G	B	0
61 
62 	6 Bits x Gun
63 
64 ***************************************************************************/
65 
WRITE16_HANDLER(unico_palette_w)66 WRITE16_HANDLER( unico_palette_w )
67 {
68 	data16_t data1, data2;
69 	COMBINE_DATA(&paletteram16[offset]);
70 	data1 = paletteram16[offset & ~1];
71 	data2 = paletteram16[offset |  1];
72 	palette_set_color( offset/2,
73 		 (data1 >> 8) & 0xFC,
74 		 (data1 >> 0) & 0xFC,
75 		 (data2 >> 8) & 0xFC	);
76 }
77 
WRITE32_HANDLER(unico_palette32_w)78 WRITE32_HANDLER( unico_palette32_w )
79 {
80 	data32_t rgb0 = COMBINE_DATA(&paletteram32[offset]);
81 	palette_set_color( offset,
82 		 (rgb0 >> 24) & 0xFC,
83 		 (rgb0 >> 16) & 0xFC,
84 		 (rgb0 >>  8) & 0xFC	);
85 }
86 
87 
88 /***************************************************************************
89 
90 								Tilemaps
91 
92 	Offset:		Bits:					Value:
93 
94 		0.w								Code
95 		2.w		fedc ba98 7--- ----
96 				---- ---- -6-- ----		Flip Y
97 				---- ---- --5- ----		Flip X
98 				---- ---- ---4 3210		Color
99 
100 ***************************************************************************/
101 
102 #define LAYER( _N_ ) \
103 static struct tilemap *tilemap_##_N_; \
104 \
105 static void get_tile_info_##_N_(int tile_index) \
106 { \
107 	data16_t code = unico_vram_##_N_[ 2 * tile_index + 0 ]; \
108 	data16_t attr = unico_vram_##_N_[ 2 * tile_index + 1 ]; \
109 	SET_TILE_INFO(1, code, attr & 0x1f, TILE_FLIPYX( attr >> 5 )) \
110 } \
111 \
112 static void get_tile_info32_##_N_(int tile_index) \
113 { \
114 	data32_t code = unico_vram32_##_N_[tile_index]; \
115 	SET_TILE_INFO(1, code >> 16, code & 0x1f, TILE_FLIPYX( code >> 5 )) \
116 } \
117 \
118 WRITE16_HANDLER( unico_vram_##_N_##_w ) \
119 { \
120 	data16_t old_data	=	unico_vram_##_N_[offset]; \
121 	data16_t new_data	=	COMBINE_DATA(&unico_vram_##_N_[offset]); \
122 	if (old_data != new_data)	tilemap_mark_tile_dirty(tilemap_##_N_,offset/2); \
123 } \
124 \
125 WRITE32_HANDLER( unico_vram32_##_N_##_w ) \
126 { \
127 	data32_t old_data	=	unico_vram32_##_N_[offset]; \
128 	data32_t new_data	=	COMBINE_DATA(&unico_vram32_##_N_[offset]); \
129 	if (old_data != new_data)	tilemap_mark_tile_dirty(tilemap_##_N_,offset); \
130 }
131 
132 LAYER( 0 )
133 LAYER( 1 )
134 LAYER( 2 )
135 
136 
137 
138 /***************************************************************************
139 
140 
141 							Video Hardware Init
142 
143 
144 ***************************************************************************/
145 
146 static int sprites_scrolldx, sprites_scrolldy;
147 
VIDEO_START(unico)148 VIDEO_START( unico )
149 {
150 	tilemap_0 = tilemap_create(	get_tile_info_0,tilemap_scan_rows,
151 								TILEMAP_TRANSPARENT,	16,16,	0x40, 0x40);
152 
153 	tilemap_1 = tilemap_create(	get_tile_info_1,tilemap_scan_rows,
154 								TILEMAP_TRANSPARENT,	16,16,	0x40, 0x40);
155 
156 	tilemap_2 = tilemap_create(	get_tile_info_2,tilemap_scan_rows,
157 								TILEMAP_TRANSPARENT,	16,16,	0x40, 0x40);
158 
159 	if (!tilemap_0 || !tilemap_1 || !tilemap_2)	return 1;
160 
161 	sprites_scrolldx = -0x3f;
162 	sprites_scrolldy = -0x0e;
163 
164 	tilemap_set_scrolldx(tilemap_0,-0x32,0);
165 	tilemap_set_scrolldx(tilemap_1,-0x30,0);
166 	tilemap_set_scrolldx(tilemap_2,-0x2e,0);
167 
168 	tilemap_set_scrolldy(tilemap_0,-0x0f,0);
169 	tilemap_set_scrolldy(tilemap_1,-0x0f,0);
170 	tilemap_set_scrolldy(tilemap_2,-0x0f,0);
171 
172 	tilemap_set_transparent_pen(tilemap_0,0x00);
173 	tilemap_set_transparent_pen(tilemap_1,0x00);
174 	tilemap_set_transparent_pen(tilemap_2,0x00);
175 	return 0;
176 }
177 
VIDEO_START(zeropnt2)178 VIDEO_START( zeropnt2 )
179 {
180 	tilemap_0 = tilemap_create(	get_tile_info32_0,tilemap_scan_rows,
181 								TILEMAP_TRANSPARENT,	16,16,	0x40, 0x40);
182 
183 	tilemap_1 = tilemap_create(	get_tile_info32_1,tilemap_scan_rows,
184 								TILEMAP_TRANSPARENT,	16,16,	0x40, 0x40);
185 
186 	tilemap_2 = tilemap_create(	get_tile_info32_2,tilemap_scan_rows,
187 								TILEMAP_TRANSPARENT,	16,16,	0x40, 0x40);
188 
189 	if (!tilemap_0 || !tilemap_1 || !tilemap_2)	return 1;
190 
191 	sprites_scrolldx = -0x3f;
192 	sprites_scrolldy = -0x0e;
193 
194 	tilemap_set_scrolldx(tilemap_0,-0x32,0);
195 	tilemap_set_scrolldx(tilemap_1,-0x30,0);
196 	tilemap_set_scrolldx(tilemap_2,-0x2e,0);
197 
198 	tilemap_set_scrolldy(tilemap_0,-0x0f,0);
199 	tilemap_set_scrolldy(tilemap_1,-0x0f,0);
200 	tilemap_set_scrolldy(tilemap_2,-0x0f,0);
201 
202 	tilemap_set_transparent_pen(tilemap_0,0x00);
203 	tilemap_set_transparent_pen(tilemap_1,0x00);
204 	tilemap_set_transparent_pen(tilemap_2,0x00);
205 	return 0;
206 }
207 
208 
209 
210 /***************************************************************************
211 
212 								Sprites Drawing
213 
214 
215 		0.w								X
216 
217 		2.w								Y
218 
219 		4.w								Code
220 
221 		6.w		fe-- ---- ---- ----
222 				--dc ---- ---- ----		Priority
223 				---- ba98 ---- ----		Number of tiles along X, minus 1
224 				---- ---- 7--- ----
225 				---- ---- -6-- ----		Flip Y?
226 				---- ---- --5- ----		Flip X
227 				---- ---- ---4 3210		Color
228 
229 
230 ***************************************************************************/
231 
unico_draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)232 static void unico_draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
233 {
234 	int offs;
235 
236 	/* Draw them backwards, for pdrawgfx */
237 	for ( offs = (spriteram_size-8)/2; offs >= 0 ; offs -= 8/2 )
238 	{
239 		int x, startx, endx, incx;
240 
241 		int	sx			=	spriteram16[ offs + 0 ];
242 		int	sy			=	spriteram16[ offs + 1 ];
243 		int	code		=	spriteram16[ offs + 2 ];
244 		int	attr		=	spriteram16[ offs + 3 ];
245 
246 		int	flipx		=	attr & 0x020;
247 		int	flipy		=	attr & 0x040;	// not sure
248 
249 		int dimx		=	((attr >> 8) & 0xf) + 1;
250 
251 		int priority	=	((attr >> 12) & 0x3);
252 		int pri_mask;
253 
254 		switch( priority )
255 		{
256 			case 0:		pri_mask = 0xfe;	break;	// below all
257 			case 1:		pri_mask = 0xf0;	break;	// above layer 0
258 			case 2:		pri_mask = 0xfc;	break;	// above layer 1
259 			default:
260 			case 3:		pri_mask = 0x00;			// above all
261 		}
262 
263 		sx	+=	sprites_scrolldx;
264 		sy	+=	sprites_scrolldy;
265 
266 		sx	=	(sx & 0x1ff) - (sx & 0x200);
267 		sy	=	(sy & 0x1ff) - (sy & 0x200);
268 
269 		if (flipx)	{	startx = sx+(dimx-1)*16;	endx = sx-16;		incx = -16;	}
270 		else		{	startx = sx;				endx = sx+dimx*16;	incx = +16;	}
271 
272 		for (x = startx ; x != endx ; x += incx)
273 		{
274 			pdrawgfx(	bitmap, Machine->gfx[0],
275 						code++,
276 						attr & 0x1f,
277 						flipx, flipy,
278 						x, sy,
279 						cliprect, TRANSPARENCY_PEN,0x00,
280 						pri_mask	);
281 		}
282 	}
283 }
284 
unico_draw_sprites32(struct mame_bitmap * bitmap,const struct rectangle * cliprect)285 static void unico_draw_sprites32(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
286 {
287 	int offs;
288 
289 	/* Draw them backwards, for pdrawgfx */
290 	for ( offs = (spriteram_size-8)/4; offs >= 0 ; offs -= 8/4 )
291 	{
292 		int x, startx, endx, incx;
293 
294 		int	sx			=	spriteram32[ offs + 0 ] >> 16;
295 		int	sy			=	spriteram32[ offs + 0 ] & 0xffff;
296 		int	code		=	spriteram32[ offs + 1 ] >> 16;
297 		int	attr		=	spriteram32[ offs + 1 ] & 0xffff;
298 
299 		int	flipx		=	attr & 0x020;
300 		int	flipy		=	attr & 0x040;	// not sure
301 
302 		int dimx		=	((attr >> 8) & 0xf) + 1;
303 
304 		int priority	=	((attr >> 12) & 0x3);
305 		int pri_mask;
306 
307 		switch( priority )
308 		{
309 			case 0:		pri_mask = 0xfe;	break;	// below all
310 			case 1:		pri_mask = 0xf0;	break;	// above layer 0
311 			case 2:		pri_mask = 0xfc;	break;	// above layer 1
312 			default:
313 			case 3:		pri_mask = 0x00;			// above all
314 		}
315 
316 		sx	+=	sprites_scrolldx;
317 		sy	+=	sprites_scrolldy;
318 
319 		sx	=	(sx & 0x1ff) - (sx & 0x200);
320 		sy	=	(sy & 0x1ff) - (sy & 0x200);
321 
322 		if (flipx)	{	startx = sx+(dimx-1)*16;	endx = sx-16;		incx = -16;	}
323 		else		{	startx = sx;				endx = sx+dimx*16;	incx = +16;	}
324 
325 		for (x = startx ; x != endx ; x += incx)
326 		{
327 			pdrawgfx(	bitmap, Machine->gfx[0],
328 						code++,
329 						attr & 0x1f,
330 						flipx, flipy,
331 						x, sy,
332 						cliprect, TRANSPARENCY_PEN,0x00,
333 						pri_mask	);
334 		}
335 	}
336 }
337 
338 
339 
340 /***************************************************************************
341 
342 
343 								Screen Drawing
344 
345 
346 ***************************************************************************/
347 
VIDEO_UPDATE(unico)348 VIDEO_UPDATE( unico )
349 {
350 	int layers_ctrl = -1;
351 
352 	tilemap_set_scrollx(tilemap_0, 0, *unico_scrollx_0);
353 	tilemap_set_scrolly(tilemap_0, 0, *unico_scrolly_0);
354 
355 	tilemap_set_scrollx(tilemap_1, 0, *unico_scrollx_1);
356 	tilemap_set_scrolly(tilemap_1, 0, *unico_scrolly_1);
357 
358 	tilemap_set_scrolly(tilemap_2, 0, *unico_scrolly_2);
359 	tilemap_set_scrollx(tilemap_2, 0, *unico_scrollx_2);
360 
361 #ifdef MAME_DEBUG
362 if ( keyboard_pressed(KEYCODE_Z) || keyboard_pressed(KEYCODE_X) )
363 {
364 	int msk = 0;
365 	if (keyboard_pressed(KEYCODE_Q))	msk |= 1;
366 	if (keyboard_pressed(KEYCODE_W))	msk |= 2;
367 	if (keyboard_pressed(KEYCODE_E))	msk |= 4;
368 	if (keyboard_pressed(KEYCODE_A))	msk |= 8;
369 	if (msk != 0) layers_ctrl &= msk;
370 }
371 #endif
372 
373 	/* The background color is the first of the last palette */
374 	fillbitmap(bitmap,Machine->pens[0x1f00],cliprect);
375 	fillbitmap(priority_bitmap,0,cliprect);
376 
377 	if (layers_ctrl & 1)	tilemap_draw(bitmap,cliprect,tilemap_0,0,1);
378 	if (layers_ctrl & 2)	tilemap_draw(bitmap,cliprect,tilemap_1,0,2);
379 	if (layers_ctrl & 4)	tilemap_draw(bitmap,cliprect,tilemap_2,0,4);
380 
381 	/* Sprites are drawn last, using pdrawgfx */
382 	if (layers_ctrl & 8)	unico_draw_sprites(bitmap,cliprect);
383 
384 	/* Draw the gunsight for ligth gun games */
385 	if (unico_has_lightgun) {
386 		draw_crosshair(bitmap,
387 			readinputport(6)*384/256,
388 			readinputport(5)*224/256,
389 			cliprect);
390 
391 		draw_crosshair(bitmap,
392 			readinputport(4)*384/256,
393 			readinputport(3)*224/256,
394 			cliprect);
395 	}
396 }
397 
VIDEO_UPDATE(zeropnt2)398 VIDEO_UPDATE( zeropnt2 )
399 {
400 	int layers_ctrl = -1;
401 
402 	tilemap_set_scrollx(tilemap_0, 0, unico_scroll32[0] >> 16);
403 	tilemap_set_scrolly(tilemap_0, 0, unico_scroll32[0] & 0xffff);
404 
405 	tilemap_set_scrollx(tilemap_1, 0, unico_scroll32[2] & 0xffff);
406 	tilemap_set_scrolly(tilemap_1, 0, unico_scroll32[5] >> 16);
407 
408 	tilemap_set_scrollx(tilemap_2, 0, unico_scroll32[2] >> 16);
409 	tilemap_set_scrolly(tilemap_2, 0, unico_scroll32[1] >> 16);
410 
411 #ifdef MAME_DEBUG
412 if ( keyboard_pressed(KEYCODE_Z) || keyboard_pressed(KEYCODE_X) )
413 {
414 	int msk = 0;
415 	if (keyboard_pressed(KEYCODE_Q))	msk |= 1;
416 	if (keyboard_pressed(KEYCODE_W))	msk |= 2;
417 	if (keyboard_pressed(KEYCODE_E))	msk |= 4;
418 	if (keyboard_pressed(KEYCODE_A))	msk |= 8;
419 	if (msk != 0) layers_ctrl &= msk;
420 }
421 #endif
422 
423 	/* The background color is the first of the last palette */
424 	fillbitmap(bitmap,Machine->pens[0x1f00],cliprect);
425 	fillbitmap(priority_bitmap,0,cliprect);
426 
427 	if (layers_ctrl & 1)	tilemap_draw(bitmap,cliprect,tilemap_0,0,1);
428 	if (layers_ctrl & 2)	tilemap_draw(bitmap,cliprect,tilemap_1,0,2);
429 	if (layers_ctrl & 4)	tilemap_draw(bitmap,cliprect,tilemap_2,0,4);
430 
431 	/* Sprites are drawn last, using pdrawgfx */
432 	if (layers_ctrl & 8)	unico_draw_sprites32(bitmap,cliprect);
433 
434 	/* Draw the gunsight for ligth gun games */
435 	if (unico_has_lightgun) {
436 		draw_crosshair(bitmap,
437 			readinputport(6)*384/256,
438 			readinputport(5)*224/256,
439 			cliprect);
440 
441 		draw_crosshair(bitmap,
442 			readinputport(4)*384/256,
443 			readinputport(3)*224/256,
444 			cliprect);
445 	}
446 }
447 
448