1 /***************************************************************************
2 
3  COSMIC.C
4 
5  emulation of video hardware of cosmic machines of 1979-1980(ish)
6 
7 ***************************************************************************/
8 
9 #include "driver.h"
10 #include "vidhrdw/generic.h"
11 
12 
13 static int (*map_color)(int x, int y);
14 
15 static data_t color_registers[3];
16 static int color_base = 0;
17 static int nomnlnd_background_on=0;
18 
19 
20 /* No Mans Land - I don't know if there are more screen layouts than this */
21 /* this one seems to be OK for the start of the game       */
22 
23 static const signed short nomnlnd_tree_positions[2][2] =
24 {
25 	{66,63},{66,159}
26 };
27 
28 static const signed short nomnlnd_water_positions[4][2] =
29 {
30 	{160,32},{160,96},{160,128},{160,192}
31 };
32 
33 
WRITE_HANDLER(panic_color_register_w)34 WRITE_HANDLER( panic_color_register_w )
35 {
36 	/* 7c0c & 7c0e = Rom Address Offset
37  	   7c0d        = high / low nibble */
38 
39 	set_vh_global_attribute(&color_registers[offset], data & 0x80);
40 
41    	color_base = (color_registers[0] << 2) + (color_registers[2] << 3);
42 }
43 
WRITE_HANDLER(cosmicg_color_register_w)44 WRITE_HANDLER( cosmicg_color_register_w )
45 {
46 	set_vh_global_attribute(&color_registers[offset], data);
47 
48    	color_base = (color_registers[0] << 8) + (color_registers[1] << 9);
49 }
50 
51 
panic_map_color(int x,int y)52 static int panic_map_color(int x, int y)
53 {
54 	/* 8 x 16 coloring */
55 	unsigned char byte = memory_region(REGION_USER1)[color_base + (x / 16) * 32 + (y / 8)];
56 
57 	if (color_registers[1])
58 		return byte >> 4;
59 	else
60 		return byte & 0x0f;
61 }
62 
cosmicg_map_color(int x,int y)63 static int cosmicg_map_color(int x, int y)
64 {
65 	unsigned char byte;
66 
67 	/* 16 x 16 coloring */
68 	byte = memory_region(REGION_USER1)[color_base + (y / 16) * 16 + (x / 16)];
69 
70 	/* the upper 4 bits are for cocktail mode support */
71 
72 	return byte & 0x0f;
73 }
74 
magspot2_map_color(int x,int y)75 static int magspot2_map_color(int x, int y)
76 {
77 	unsigned char byte;
78 
79 	/* 16 x 8 coloring */
80 
81 	// Should the top line of the logo be red or white???
82 
83 	byte = memory_region(REGION_USER1)[(x / 8) * 16 + (y / 16)];
84 
85 	if (color_registers[1])
86 		return byte >> 4;
87 	else
88 		return byte & 0x0f;
89 }
90 
91 
92 static const unsigned char panic_remap_sprite_code[64][2] =
93 {
94 {0x00,0},{0x26,0},{0x25,0},{0x24,0},{0x23,0},{0x22,0},{0x21,0},{0x20,0}, /* 00 */
95 {0x00,0},{0x26,0},{0x25,0},{0x24,0},{0x23,0},{0x22,0},{0x21,0},{0x20,0}, /* 08 */
96 {0x00,0},{0x16,0},{0x15,0},{0x14,0},{0x13,0},{0x12,0},{0x11,0},{0x10,0}, /* 10 */
97 {0x00,0},{0x16,0},{0x15,0},{0x14,0},{0x13,0},{0x12,0},{0x11,0},{0x10,0}, /* 18 */
98 {0x00,0},{0x06,0},{0x05,0},{0x04,0},{0x03,0},{0x02,0},{0x01,0},{0x00,0}, /* 20 */
99 {0x00,0},{0x06,0},{0x05,0},{0x04,0},{0x03,0},{0x02,0},{0x01,0},{0x00,0}, /* 28 */
100 {0x07,2},{0x06,2},{0x05,2},{0x04,2},{0x03,2},{0x02,2},{0x01,2},{0x00,2}, /* 30 */
101 {0x07,2},{0x06,2},{0x05,2},{0x04,2},{0x03,2},{0x02,2},{0x01,2},{0x00,2}, /* 38 */
102 };
103 
104 /*
105  * Panic Color table setup
106  *
107  * Bit 0 = RED, Bit 1 = GREEN, Bit 2 = BLUE
108  *
109  * First 8 colors are normal intensities
110  *
111  * But, bit 3 can be used to pull Blue via a 2k resistor to 5v
112  * (1k to ground) so second version of table has blue set to 2/3
113  *
114  */
115 
panic_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)116 void panic_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
117 {
118 	int i;
119 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
120 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
121 
122 	for (i = 0;i < Machine->drv->total_colors;i++)
123 	{
124 		*(palette++) = 0xff * ((i >> 0) & 1);
125 		*(palette++) = 0xff * ((i >> 1) & 1);
126 		if ((i & 0x0c) == 0x08)
127 			*(palette++) = 0xaa;
128 		else
129 			*(palette++) = 0xff * ((i >> 2) & 1);
130 	}
131 
132 
133 	for (i = 0;i < TOTAL_COLORS(0);i++)
134 		COLOR(0,i) = *(color_prom++) & 0x0f;
135 
136 
137     map_color = panic_map_color;
138 }
139 
140 
141 /*
142  * Cosmic Alien Color table setup
143  *
144  * 8 colors, 16 sprite color codes
145  *
146  * Bit 0 = RED, Bit 1 = GREEN, Bit 2 = BLUE
147  *
148  */
149 
cosmica_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)150 void cosmica_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
151 {
152 	int i;
153 
154 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
155 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
156 
157 	for (i = 0;i < Machine->drv->total_colors;i++)
158 	{
159 		*(palette++) = 0xff * ((i >> 0) & 1);
160 		*(palette++) = 0xff * ((i >> 1) & 1);
161 		*(palette++) = 0xff * ((i >> 2) & 1);
162 	}
163 
164 
165 	for (i = 0;i < TOTAL_COLORS(0)/2;i++)
166 	{
167 		COLOR(0,i)                     =  * color_prom          & 0x07;
168 		COLOR(0,i+(TOTAL_COLORS(0)/2)) = (*(color_prom++) >> 4) & 0x07;
169 	}
170 
171 
172     map_color = panic_map_color;
173 }
174 
175 
176 /*
177  * Cosmic guerilla table setup
178  *
179  * Use AA for normal, FF for Full Red
180  * Bit 0 = R, bit 1 = G, bit 2 = B, bit 4 = High Red
181  *
182  * It's possible that the background is dark gray and not black, as the
183  * resistor chain would never drop to zero, Anybody know ?
184  *
185  */
186 
cosmicg_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)187 void cosmicg_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
188 {
189 	int i;
190 
191 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
192 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
193 
194 	for (i = 0;i < Machine->drv->total_colors;i++)
195 	{
196     	if (i > 8) *(palette++) = 0xff;
197         else *(palette++) = 0xaa * ((i >> 0) & 1);
198 
199 		*(palette++) = 0xaa * ((i >> 1) & 1);
200 		*(palette++) = 0xaa * ((i >> 2) & 1);
201 	}
202 
203 
204     map_color = cosmicg_map_color;
205 }
206 
207 /**************************************************/
208 /* Magical Spot 2/Devil Zone specific routines    */
209 /*												  */
210 /* 16 colors, 8 sprite color codes				  */
211 /**************************************************/
212 
magspot2_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)213 void magspot2_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
214 {
215 	int i;
216 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
217 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
218 
219 
220 	for (i = 0;i < Machine->drv->total_colors;i++)
221 	{
222 		if ((i & 0x09) == 0x08)
223 			*(palette++) = 0xaa;
224 	 	else
225 			*(palette++) = 0xff * ((i >> 0) & 1);
226 
227 		*(palette++) = 0xff * ((i >> 1) & 1);
228 		*(palette++) = 0xff * ((i >> 2) & 1);
229 	}
230 
231 
232 	for (i = 0;i < TOTAL_COLORS(0);i++)
233 	{
234 		COLOR(0,i) = *(color_prom++) & 0x0f;
235 	}
236 
237 
238     map_color = magspot2_map_color;
239 }
240 
241 
WRITE_HANDLER(nomnlnd_background_w)242 WRITE_HANDLER( nomnlnd_background_w )
243 {
244 	nomnlnd_background_on = data;
245 }
246 
247 
WRITE_HANDLER(cosmica_videoram_w)248 WRITE_HANDLER( cosmica_videoram_w )
249 {
250     int i,x,y,col;
251 
252     videoram[offset] = data;
253 
254 	y = offset / 32;
255 	x = 8 * (offset % 32);
256 
257     col = Machine->pens[map_color(x, y)];
258 
259     for (i = 0; i < 8; i++)
260     {
261 		if (flip_screen)
262 			plot_pixel(tmpbitmap, 255-x, 255-y, (data & 0x80) ? col : Machine->pens[0]);
263 		else
264 			plot_pixel(tmpbitmap,     x,     y, (data & 0x80) ? col : Machine->pens[0]);
265 
266 	    x++;
267 	    data <<= 1;
268     }
269 }
270 
271 
cosmicg_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)272 void cosmicg_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
273 {
274 	if (full_refresh)
275 	{
276 		int offs;
277 
278 		for (offs = 0; offs < videoram_size; offs++)
279 		{
280 			cosmica_videoram_w(offs, videoram[offs]);
281 		}
282 	}
283 
284 	copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
285 }
286 
287 
panic_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)288 void panic_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
289 {
290 	int offs;
291 
292 
293 	cosmicg_vh_screenrefresh(bitmap, full_refresh);
294 
295 
296     /* draw the sprites */
297 
298 	for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
299 	{
300 		if (spriteram[offs] != 0)
301 		{
302 			int code,bank,flipy;
303 
304 			/* panic_remap_sprite_code sprite number to my layout */
305 
306 			code = panic_remap_sprite_code[(spriteram[offs] & 0x3F)][0];
307 			bank = panic_remap_sprite_code[(spriteram[offs] & 0x3F)][1];
308 			flipy = spriteram[offs] & 0x40;
309 
310 			/*if((code==0) && (bank==0))
311 				logerror("remap failure %2x\n",(spriteram[offs] & 0x3F));*/
312 
313 			/* Switch Bank */
314 
315 			if(spriteram[offs+3] & 0x08) bank=1;
316 
317 			if (flip_screen)
318 			{
319 				flipy = !flipy;
320 			}
321 
322 			drawgfx(bitmap,Machine->gfx[bank],
323 					code,
324 					7 - (spriteram[offs+3] & 0x07),
325 					flip_screen,flipy,
326 					256-spriteram[offs+2],spriteram[offs+1],
327 					&Machine->visible_area,TRANSPARENCY_PEN,0);
328 		}
329 	}
330 }
331 
332 
cosmica_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)333 void cosmica_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
334 {
335 	int offs;
336 
337 
338 	cosmicg_vh_screenrefresh(bitmap, full_refresh);
339 
340 
341     /* draw the sprites */
342 
343 	for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
344 	{
345 		if (spriteram[offs] != 0)
346         {
347 			int code, color;
348 
349 			code  = ~spriteram[offs  ] & 0x3f;
350 			color = ~spriteram[offs+3] & 0x0f;
351 
352             if (spriteram[offs] & 0x80)
353             {
354                 /* 16x16 sprite */
355 
356 			    drawgfx(bitmap,Machine->gfx[0],
357 					    code,
358 					    color,
359 					    0,0,
360 				    	256-spriteram[offs+2],spriteram[offs+1],
361 				        &Machine->visible_area,TRANSPARENCY_PEN,0);
362             }
363             else
364             {
365                 /* 32x32 sprite */
366 
367 			    drawgfx(bitmap,Machine->gfx[1],
368 					    code >> 2,
369 					    color,
370 					    0,0,
371 				    	256-spriteram[offs+2],spriteram[offs+1],
372 				        &Machine->visible_area,TRANSPARENCY_PEN,0);
373             }
374         }
375 	}
376 }
377 
378 
magspot2_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)379 void magspot2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
380 {
381 	int offs;
382 
383 
384 	cosmicg_vh_screenrefresh(bitmap, full_refresh);
385 
386 
387     /* draw the sprites */
388 
389 	for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
390 	{
391 		if (spriteram[offs] != 0)
392         {
393 			int code, color;
394 
395 			code  = ~spriteram[offs  ] & 0x3f;
396 			color = ~spriteram[offs+3] & 0x07;
397 
398             if (spriteram[offs] & 0x80)
399             {
400                 /* 16x16 sprite */
401 
402 			    drawgfx(bitmap,Machine->gfx[0],
403 					    code,
404 					    color,
405 					    0,0,
406 				    	256-spriteram[offs+2],spriteram[offs+1],
407 				        &Machine->visible_area,TRANSPARENCY_PEN,0);
408             }
409             else
410             {
411                 /* 32x32 sprite */
412 
413 			    drawgfx(bitmap,Machine->gfx[1],
414 					    code >> 2,
415 					    color,
416 					    0,0,
417 				    	256-spriteram[offs+2],spriteram[offs+1],
418 				        &Machine->visible_area,TRANSPARENCY_PEN,0);
419             }
420         }
421 	}
422 }
423 
424 
nomnlnd_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)425 void nomnlnd_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
426 {
427 	int offs;
428 
429 
430 	magspot2_vh_screenrefresh(bitmap, full_refresh);
431 
432 
433     if (nomnlnd_background_on)
434     {
435 		// draw trees
436 
437         static UINT8 water_animate=0;
438 
439         water_animate++;
440 
441     	for(offs=0;offs<2;offs++)
442         {
443 			int code,x,y;
444 
445 			x = nomnlnd_tree_positions[offs][0];
446 			y = nomnlnd_tree_positions[offs][1];
447 
448 			if (flip_screen)
449 			{
450 				x = 223 - x;
451 				y = 223 - y;
452 				code = 2 + offs;
453 			}
454 			else
455 			{
456 				code = offs;
457 			}
458 
459     		drawgfx(bitmap,Machine->gfx[2],
460 					code,
461 					8,
462 					0,0,
463 					x,y,
464 					&Machine->visible_area,TRANSPARENCY_PEN,0);
465         }
466 
467 		// draw water
468 
469     	for(offs=0;offs<4;offs++)
470         {
471 			int x,y;
472 
473 			x = nomnlnd_water_positions[offs][0];
474 			y = nomnlnd_water_positions[offs][1];
475 
476 			if (flip_screen)
477 			{
478 				x = 239 - x;
479 				y = 223 - y;
480 			}
481 
482     		drawgfx(bitmap,Machine->gfx[3],
483 					water_animate >> 3,
484 					9,
485 					0,0,
486 					x,y,
487 					&Machine->visible_area,TRANSPARENCY_NONE,0);
488         }
489     }
490 }
491