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