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