1 /***************************************************************************
2
3 vidhrdw.c
4
5 Functions to emulate the video hardware of the machine.
6
7 ***************************************************************************/
8
9 #include "driver.h"
10 #include "vidhrdw/generic.h"
11 #include "artwork.h"
12
13 static int use_tmpbitmap;
14 static data_t screen_red;
15 static int screen_red_enabled; /* 1 for games that can turn the screen red */
16 static data_t color_map_select;
17 static int background_color;
18
19 static int overlay_type; /* 0=none, 1=geometric, 2=file */
20 static const void *init_overlay;
21
22 static mem_write_handler videoram_w_p;
23 static void (*vh_screenrefresh_p)(struct osd_bitmap *bitmap,int full_refresh);
24 static void (*plot_pixel_p)(int x, int y, int col);
25
26 static WRITE_HANDLER( bw_videoram_w );
27 static WRITE_HANDLER( schaser_videoram_w );
28 static WRITE_HANDLER( lupin3_videoram_w );
29 static WRITE_HANDLER( polaris_videoram_w );
30 static WRITE_HANDLER( invadpt2_videoram_w );
31 static WRITE_HANDLER( astinvad_videoram_w );
32 static WRITE_HANDLER( spaceint_videoram_w );
33 static WRITE_HANDLER( helifire_videoram_w );
34
35 static void vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
36 static void seawolf_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
37 static void blueshrk_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
38 static void desertgu_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
39 static void phantom2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
40
41 static void plot_pixel_8080 (int x, int y, int col);
42 static void plot_pixel_8080_tmpbitmap (int x, int y, int col);
43
44 /* smoothed pure colors, overlays are not so contrasted */
45
46 #define RED 0xff,0x20,0x20,OVERLAY_DEFAULT_OPACITY
47 #define GREEN 0x20,0xff,0x20,OVERLAY_DEFAULT_OPACITY
48 #define YELLOW 0xff,0xff,0x20,OVERLAY_DEFAULT_OPACITY
49 #define CYAN 0x20,0xff,0xff,OVERLAY_DEFAULT_OPACITY
50
51 #define END {{ -1, -1, -1, -1}, 0,0,0,0}
52
53
54 static const struct artwork_element invaders_overlay[]=
55 {
56 {{ 16, 71, 0, 255}, GREEN },
57 {{ 0, 15, 16, 133}, GREEN },
58 {{ 192, 223, 0, 255}, RED },
59 END
60 };
61
62 //static const struct artwork_element invdpt2m_overlay[]=
63 //{
64 // {{ 16, 71, 0, 255}, GREEN },
65 // {{ 0, 15, 16, 133}, GREEN },
66 // {{ 72, 191, 0, 255}, YELLOW },
67 // {{ 192, 223, 0, 255}, RED },
68 // END
69 //};
70
71 static const struct artwork_element invrvnge_overlay[]=
72 {
73 {{ 0, 71, 0, 255}, GREEN },
74 {{ 192, 223, 0, 255}, RED },
75 END
76 };
77
78 static const struct artwork_element invad2ct_overlay[]=
79 {
80 {{ 0, 47, 0, 255}, YELLOW },
81 {{ 25, 70, 0, 255}, GREEN },
82 {{ 48, 139, 0, 255}, CYAN },
83 {{ 117, 185, 0, 255}, GREEN },
84 {{ 163, 231, 0, 255}, YELLOW },
85 {{ 209, 255, 0, 255}, RED },
86 END
87 };
88
89
init_8080bw(void)90 void init_8080bw(void)
91 {
92 videoram_w_p = bw_videoram_w;
93 vh_screenrefresh_p = vh_screenrefresh;
94 use_tmpbitmap = 0;
95 screen_red = 0;
96 screen_red_enabled = 0;
97 overlay_type = 0;
98 color_map_select = 0;
99 flip_screen_w(0,0);
100 }
101
init_invaders(void)102 void init_invaders(void)
103 {
104 init_8080bw();
105 init_overlay = invaders_overlay;
106 overlay_type = 1;
107 }
108
init_invaddlx(void)109 void init_invaddlx(void)
110 {
111 init_8080bw();
112 //init_overlay = invdpt2m_overlay;
113 //overlay_type = 1;
114 }
115
init_invrvnge(void)116 void init_invrvnge(void)
117 {
118 init_8080bw();
119 init_overlay = invrvnge_overlay;
120 overlay_type = 1;
121 }
122
init_invad2ct(void)123 void init_invad2ct(void)
124 {
125 init_8080bw();
126 init_overlay = invad2ct_overlay;
127 overlay_type = 1;
128 }
129
init_schaser(void)130 void init_schaser(void)
131 {
132 init_8080bw();
133 videoram_w_p = schaser_videoram_w;
134 background_color = 2; /* blue */
135 }
136
init_rollingc(void)137 void init_rollingc(void)
138 {
139 init_8080bw();
140 videoram_w_p = schaser_videoram_w;
141 background_color = 0; /* black */
142 }
143
init_helifire(void)144 void init_helifire(void)
145 {
146 init_8080bw();
147 videoram_w_p = helifire_videoram_w;
148 }
149
init_polaris(void)150 void init_polaris(void)
151 {
152 init_8080bw();
153 videoram_w_p = polaris_videoram_w;
154 }
155
init_lupin3(void)156 void init_lupin3(void)
157 {
158 init_8080bw();
159 videoram_w_p = lupin3_videoram_w;
160 background_color = 0; /* black */
161 }
162
init_invadpt2(void)163 void init_invadpt2(void)
164 {
165 init_8080bw();
166 videoram_w_p = invadpt2_videoram_w;
167 screen_red_enabled = 1;
168 }
169
init_seawolf(void)170 void init_seawolf(void)
171 {
172 init_8080bw();
173 vh_screenrefresh_p = seawolf_vh_screenrefresh;
174 use_tmpbitmap = 1;
175 }
176
init_blueshrk(void)177 void init_blueshrk(void)
178 {
179 init_8080bw();
180 vh_screenrefresh_p = blueshrk_vh_screenrefresh;
181 use_tmpbitmap = 1;
182 }
183
init_desertgu(void)184 void init_desertgu(void)
185 {
186 init_8080bw();
187 vh_screenrefresh_p = desertgu_vh_screenrefresh;
188 use_tmpbitmap = 1;
189 }
190
init_astinvad(void)191 void init_astinvad(void)
192 {
193 init_8080bw();
194 videoram_w_p = astinvad_videoram_w;
195 screen_red_enabled = 1;
196 }
197
init_spaceint(void)198 void init_spaceint(void)
199 {
200 init_8080bw();
201 videoram_w_p = spaceint_videoram_w;
202 }
203
init_spcenctr(void)204 void init_spcenctr(void)
205 {
206 extern struct GameDriver driver_spcenctr;
207
208 init_8080bw();
209 init_overlay = driver_spcenctr.name;
210 overlay_type = 2;
211 }
212
init_phantom2(void)213 void init_phantom2(void)
214 {
215 init_8080bw();
216 vh_screenrefresh_p = phantom2_vh_screenrefresh;
217 use_tmpbitmap = 1;
218 }
219
220
invaders_vh_start(void)221 int invaders_vh_start(void)
222 {
223 /* create overlay if one of was specified in init_X */
224 if (overlay_type)
225 {
226 int start_pen;
227 int max_pens;
228
229
230 start_pen = 2;
231 max_pens = Machine->drv->total_colors-start_pen;
232
233 if (overlay_type == 1)
234 overlay_create((const struct artwork_element *)init_overlay, start_pen, max_pens);
235 else
236 overlay_load((const char *)init_overlay, start_pen, max_pens);
237 }
238
239 if (use_tmpbitmap && (generic_bitmapped_vh_start() != 0))
240 return 1;
241
242 if (use_tmpbitmap)
243 {
244 plot_pixel_p = plot_pixel_8080_tmpbitmap;
245 }
246 else
247 {
248 plot_pixel_p = plot_pixel_8080;
249 }
250
251 /* make sure that the screen matches the videoram, this fixes invad2ct */
252 //schedule_full_refresh();
253
254 return 0;
255 }
256
257
invaders_vh_stop(void)258 void invaders_vh_stop(void)
259 {
260 if (use_tmpbitmap) generic_bitmapped_vh_stop();
261 }
262
263
invaders_flip_screen_w(int data)264 void invaders_flip_screen_w(int data)
265 {
266 set_vh_global_attribute(&color_map_select, data);
267
268 if (input_port_3_r(0) & 0x01)
269 {
270 flip_screen_w(0, data);
271 }
272 }
273
274
invaders_screen_red_w(int data)275 void invaders_screen_red_w(int data)
276 {
277 if (screen_red_enabled)
278 {
279 set_vh_global_attribute(&screen_red, data);
280 }
281 }
282
283
plot_pixel_8080(int x,int y,int col)284 static void plot_pixel_8080 (int x, int y, int col)
285 {
286 if (flip_screen)
287 {
288 x = 255-x;
289 y = 223-y;
290 }
291
292 plot_pixel(Machine->scrbitmap,x,y,Machine->pens[col]);
293 }
294
plot_pixel_8080_tmpbitmap(int x,int y,int col)295 static void plot_pixel_8080_tmpbitmap (int x, int y, int col)
296 {
297 if (flip_screen)
298 {
299 x = 255-x;
300 y = 223-y;
301 }
302
303 plot_pixel(tmpbitmap,x,y,Machine->pens[col]);
304 }
305
plot_byte(int x,int y,int data,int fore_color,int back_color)306 static INLINE void plot_byte(int x, int y, int data, int fore_color, int back_color)
307 {
308 int i;
309
310 for (i = 0; i < 8; i++)
311 {
312 plot_pixel_p (x, y, (data & 0x01) ? fore_color : back_color);
313
314 x++;
315 data >>= 1;
316 }
317 }
318
319
WRITE_HANDLER(invaders_videoram_w)320 WRITE_HANDLER( invaders_videoram_w )
321 {
322 videoram_w_p(offset, data);
323 }
324
325
WRITE_HANDLER(bw_videoram_w)326 static WRITE_HANDLER( bw_videoram_w )
327 {
328 int x,y;
329
330 videoram[offset] = data;
331
332 y = offset / 32;
333 x = 8 * (offset % 32);
334
335 plot_byte(x, y, data, 1, 0);
336 }
337
WRITE_HANDLER(schaser_videoram_w)338 static WRITE_HANDLER( schaser_videoram_w )
339 {
340 int x,y,col;
341
342 videoram[offset] = data;
343
344 y = offset / 32;
345 x = 8 * (offset % 32);
346
347 col = colorram[offset & 0x1f1f] & 0x07;
348
349 plot_byte(x, y, data, col, background_color);
350 }
351
WRITE_HANDLER(lupin3_videoram_w)352 static WRITE_HANDLER( lupin3_videoram_w )
353 {
354 int x,y,col;
355
356 videoram[offset] = data;
357
358 y = offset / 32;
359 x = 8 * (offset % 32);
360
361 col = ~colorram[offset & 0x1f1f] & 0x07;
362
363 plot_byte(x, y, data, col, background_color);
364 }
365
WRITE_HANDLER(polaris_videoram_w)366 static WRITE_HANDLER( polaris_videoram_w )
367 {
368 int x,y,back_color,foreground_color;
369
370 videoram[offset] = data;
371
372 y = offset / 32;
373 x = 8 * (offset % 32);
374
375 /* for the background color, bit 0 if the map PROM is connected to blue gun.
376 red is 0 */
377
378 back_color = (memory_region(REGION_PROMS)[(((y+32)/8)*32) + (x/8)] & 1) ? 6 : 4;
379 foreground_color = ~colorram[offset & 0x1f1f] & 0x07;
380
381 plot_byte(x, y, data, foreground_color, back_color);
382 }
383
WRITE_HANDLER(helifire_videoram_w)384 static WRITE_HANDLER( helifire_videoram_w )
385 {
386 int x,y,back_color,foreground_color;
387
388 videoram[offset] = data;
389
390 y = offset / 32;
391 x = 8 * (offset % 32);
392
393 back_color = 0;
394 foreground_color = colorram[offset] & 0x07;
395
396 if (x < 0x78)
397 {
398 back_color = 4; /* blue */
399 }
400
401 plot_byte(x, y, data, foreground_color, back_color);
402 }
403
404
WRITE_HANDLER(schaser_colorram_w)405 WRITE_HANDLER( schaser_colorram_w )
406 {
407 int i;
408
409
410 offset &= 0x1f1f;
411
412 colorram[offset] = data;
413
414 /* redraw region with (possibly) changed color */
415 for (i = 0; i < 8; i++, offset += 0x20)
416 {
417 videoram_w_p(offset, videoram[offset]);
418 }
419 }
420
READ_HANDLER(schaser_colorram_r)421 READ_HANDLER( schaser_colorram_r )
422 {
423 return colorram[offset & 0x1f1f];
424 }
425
426
WRITE_HANDLER(helifire_colorram_w)427 WRITE_HANDLER( helifire_colorram_w )
428 {
429 colorram[offset] = data;
430
431 /* redraw region with (possibly) changed color */
432 videoram_w_p(offset, videoram[offset]);
433 }
434
435
436 /***************************************************************************
437
438 Draw the game screen in the given osd_bitmap.
439 Do NOT call osd_update_display() from this function, it will be called by
440 the main emulation engine.
441
442 ***************************************************************************/
invaders_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)443 void invaders_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
444 {
445 vh_screenrefresh_p(bitmap, full_refresh);
446 }
447
448
vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)449 static void vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
450 {
451 if (palette_recalc() || full_refresh)
452 {
453 int offs;
454
455 for (offs = 0;offs < videoram_size;offs++)
456 videoram_w_p(offs, videoram[offs]);
457 }
458
459
460 if (use_tmpbitmap)
461 copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
462 }
463
464
draw_sight(int x_center,int y_center)465 static void draw_sight(int x_center, int y_center)
466 {
467 int x,y;
468
469
470 if (x_center<2) x_center=2;
471 if (x_center>253) x_center=253;
472
473 if (y_center<2) y_center=2;
474 if (y_center>253) y_center=253;
475
476 for(y = y_center-10; y < y_center+11; y++)
477 if((y >= 0) && (y < 256))
478 plot_pixel_8080(x_center,y,1);
479
480 for(x = x_center-20; x < x_center+21; x++)
481 if((x >= 0) && (x < 256))
482 plot_pixel_8080(x,y_center,1);
483 }
484
485
seawolf_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)486 static void seawolf_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
487 {
488 /* update the bitmap (and erase old cross) */
489 vh_screenrefresh(bitmap, full_refresh);
490
491 draw_sight(((input_port_0_r(0) & 0x1f) * 8) + 4, 31);
492 }
493
blueshrk_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)494 static void blueshrk_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
495 {
496 /* update the bitmap (and erase old cross) */
497 vh_screenrefresh(bitmap, full_refresh);
498
499 draw_sight(((input_port_0_r(0) & 0x7f) * 2) - 12, 31);
500 }
501
desertgu_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)502 static void desertgu_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
503 {
504 /* update the bitmap (and erase old cross) */
505 vh_screenrefresh(bitmap, full_refresh);
506
507 draw_sight(((input_port_0_r(0) & 0x7f) * 2) - 30,
508 ((input_port_2_r(0) & 0x7f) * 2) - 30);
509 }
510
phantom2_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)511 static void phantom2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
512 {
513 unsigned char *clouds;
514 int x, y;
515
516
517 /* update the bitmap */
518 vh_screenrefresh(bitmap, full_refresh);
519
520
521 /* draw the clouds */
522 clouds = memory_region(REGION_PROMS);
523
524 for (y = 0; y < 128; y++)
525 {
526 unsigned char *offs = &memory_region(REGION_PROMS)[y * 0x10];
527
528 for (x = 0; x < 128; x++)
529 {
530 if (offs[x >> 3] & (1 << (x & 0x07)))
531 {
532 plot_pixel_8080(x*2, y*2, 1);
533 plot_pixel_8080(x*2+1, y*2, 1);
534 plot_pixel_8080(x*2, y*2+1, 1);
535 plot_pixel_8080(x*2+1, y*2+1, 1);
536 }
537 }
538 }
539 }
540
541
invadpt2_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)542 void invadpt2_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
543 {
544 int i;
545
546
547 for (i = 0;i < Machine->drv->total_colors;i++)
548 {
549 /* this bit arrangment is a little unusual but are confirmed by screen shots */
550
551 *(palette++) = 0xff * ((i >> 0) & 1);
552 *(palette++) = 0xff * ((i >> 2) & 1);
553 *(palette++) = 0xff * ((i >> 1) & 1);
554 }
555 }
556
helifire_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)557 void helifire_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
558 {
559 int i;
560
561
562 for (i = 0;i < Machine->drv->total_colors;i++)
563 {
564 *(palette++) = 0xff * ((i >> 0) & 1);
565 *(palette++) = 0xff * ((i >> 1) & 1);
566 *(palette++) = 0xff * ((i >> 2) & 1);
567 }
568 }
569
570
WRITE_HANDLER(invadpt2_videoram_w)571 static WRITE_HANDLER( invadpt2_videoram_w )
572 {
573 int x,y,col;
574
575 videoram[offset] = data;
576
577 y = offset / 32;
578 x = 8 * (offset % 32);
579
580 /* 32 x 32 colormap */
581 if (!screen_red)
582 col = memory_region(REGION_PROMS)[(color_map_select ? 0x400 : 0 ) + (((y+32)/8)*32) + (x/8)] & 7;
583 else
584 col = 1; /* red */
585
586 plot_byte(x, y, data, col, 0);
587 }
588
WRITE_HANDLER(astinvad_videoram_w)589 static WRITE_HANDLER( astinvad_videoram_w )
590 {
591 int x,y,col;
592
593 videoram[offset] = data;
594
595 y = offset / 32;
596 x = 8 * (offset % 32);
597
598 if (!screen_red)
599 {
600 if (flip_screen)
601 col = memory_region(REGION_PROMS)[((y+32)/8)*32+(x/8)] >> 4;
602 else
603 col = memory_region(REGION_PROMS)[(31-y/8)*32+(31-x/8)] & 0x0f;
604 }
605 else
606 col = 1; /* red */
607
608 plot_byte(x, y, data, col, 0);
609 }
610
WRITE_HANDLER(spaceint_videoram_w)611 static WRITE_HANDLER( spaceint_videoram_w )
612 {
613 int i,x,y,col;
614
615 videoram[offset] = data;
616
617 y = 8 * (offset / 256);
618 x = offset % 256;
619
620 /* this is wrong */
621 col = memory_region(REGION_PROMS)[(y/16)+16*((x+16)/32)];
622
623 for (i = 0; i < 8; i++)
624 {
625 plot_pixel_p(x, y, (data & 0x01) ? col : 0);
626
627 y++;
628 data >>= 1;
629 }
630 }
631