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
12
13 #define MAX_STARS 250
14 #define STARS_COLOR_BASE 32
15
16 unsigned char *bosco_staronoff;
17 unsigned char *bosco_starblink;
18 static unsigned int stars_scrollx;
19 static unsigned int stars_scrolly;
20 static unsigned char bosco_scrollx,bosco_scrolly;
21 static unsigned char bosco_starcontrol;
22 static int flipscreen;
23 static int displacement;
24
25
26 struct star
27 {
28 int x,y,col,set;
29 };
30 static struct star stars[MAX_STARS];
31 static int total_stars;
32
33 #define VIDEO_RAM_SIZE 0x400
34
35 unsigned char *bosco_videoram2,*bosco_colorram2;
36 unsigned char *bosco_radarx,*bosco_radary,*bosco_radarattr;
37 size_t bosco_radarram_size;
38 /* to speed up video refresh */
39 static unsigned char *dirtybuffer2; /* keep track of modified portions of the screen */
40 /* to speed up video refresh */
41 static struct mame_bitmap *tmpbitmap1;
42
43
44
45 static struct rectangle spritevisiblearea =
46 {
47 0*8+3, 28*8-1,
48 0*8, 28*8-1
49 };
50
51 static struct rectangle spritevisibleareaflip =
52 {
53 8*8, 36*8-1-3,
54 0*8, 28*8-1
55 };
56
57
58 static struct rectangle radarvisiblearea =
59 {
60 28*8, 36*8-1,
61 0*8, 28*8-1
62 };
63
64 static struct rectangle radarvisibleareaflip =
65 {
66 0*8, 8*8-1,
67 0*8, 28*8-1
68 };
69
70
71
PALETTE_INIT(bosco)72 PALETTE_INIT( bosco )
73 {
74 int i;
75 #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
76 #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
77
78
79 for (i = 0;i < 32;i++)
80 {
81 int bit0,bit1,bit2,r,g,b;
82
83
84 bit0 = (color_prom[31-i] >> 0) & 0x01;
85 bit1 = (color_prom[31-i] >> 1) & 0x01;
86 bit2 = (color_prom[31-i] >> 2) & 0x01;
87 r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
88 bit0 = (color_prom[31-i] >> 3) & 0x01;
89 bit1 = (color_prom[31-i] >> 4) & 0x01;
90 bit2 = (color_prom[31-i] >> 5) & 0x01;
91 g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
92 bit0 = 0;
93 bit1 = (color_prom[31-i] >> 6) & 0x01;
94 bit2 = (color_prom[31-i] >> 7) & 0x01;
95 b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
96
97 palette_set_color(i,r,g,b);
98 }
99
100 /* characters / sprites */
101 for (i = 0;i < 64*4;i++)
102 {
103 colortable[i] = 15 - (color_prom[i + 32] & 0x0f); /* chars */
104 colortable[i+64*4] = 15 - (color_prom[i + 32] & 0x0f) + 0x10; /* sprites */
105 if (colortable[i+64*4] == 0x10) colortable[i+64*4] = 0; /* preserve transparency */
106 }
107
108 /* radar dots lookup table */
109 /* they use colors 0-3, I think */
110 for (i = 0;i < 4;i++)
111 COLOR(2,i) = i;
112
113 /* now the stars */
114 for (i = 32;i < 32 + 64;i++)
115 {
116 int bits,r,g,b;
117 int map[4] = { 0x00, 0x88, 0xcc, 0xff };
118
119 bits = ((i-32) >> 0) & 0x03;
120 r = map[bits];
121 bits = ((i-32) >> 2) & 0x03;
122 g = map[bits];
123 bits = ((i-32) >> 4) & 0x03;
124 b = map[bits];
125
126 palette_set_color(i,r,g,b);
127 }
128 }
129
VIDEO_START(bosco)130 VIDEO_START( bosco )
131 {
132 int generator;
133 int x,y;
134 int set = 0;
135
136 if (video_start_generic() != 0)
137 return 1;
138
139 if ((dirtybuffer2 = auto_malloc(videoram_size)) == 0)
140 return 1;
141 memset(dirtybuffer2,1,videoram_size);
142
143 if ((tmpbitmap1 = auto_bitmap_alloc(32*8,32*8)) == 0)
144 return 1;
145
146 /* precalculate the star background */
147 /* this comes from the Galaxian hardware, Bosconian is probably different */
148 total_stars = 0;
149 generator = 0;
150
151 for (x = 255;x >= 0;x--)
152 {
153 for (y = 511;y >= 0;y--)
154 {
155 int bit1,bit2;
156
157
158 generator <<= 1;
159 bit1 = (~generator >> 17) & 1;
160 bit2 = (generator >> 5) & 1;
161
162 if (bit1 ^ bit2) generator |= 1;
163
164 if (x >= Machine->visible_area.min_x &&
165 x <= Machine->visible_area.max_x &&
166 ((~generator >> 16) & 1) &&
167 (generator & 0xff) == 0xff)
168 {
169 int color;
170
171 color = (~(generator >> 8)) & 0x3f;
172 if (color && total_stars < MAX_STARS)
173 {
174 stars[total_stars].x = x;
175 stars[total_stars].y = y;
176 stars[total_stars].col = Machine->pens[color + STARS_COLOR_BASE];
177 stars[total_stars].set = set;
178 if (++set > 3)
179 set = 0;
180
181 total_stars++;
182 }
183 }
184 }
185 }
186 *bosco_staronoff = 1;
187
188 displacement = 1;
189
190 return 0;
191 }
192
193
WRITE_HANDLER(bosco_videoram2_w)194 WRITE_HANDLER( bosco_videoram2_w )
195 {
196 if (bosco_videoram2[offset] != data)
197 {
198 dirtybuffer2[offset] = 1;
199
200 bosco_videoram2[offset] = data;
201 }
202 }
203
204
205
WRITE_HANDLER(bosco_colorram2_w)206 WRITE_HANDLER( bosco_colorram2_w )
207 {
208 if (bosco_colorram2[offset] != data)
209 {
210 dirtybuffer2[offset] = 1;
211
212 bosco_colorram2[offset] = data;
213 }
214 }
215
216
WRITE_HANDLER(bosco_flipscreen_w)217 WRITE_HANDLER( bosco_flipscreen_w )
218 {
219 if (flipscreen != (~data & 1))
220 {
221 flipscreen = ~data & 1;
222 memset(dirtybuffer,1,videoram_size);
223 memset(dirtybuffer2,1,videoram_size);
224 }
225 }
226
WRITE_HANDLER(bosco_scrollx_w)227 WRITE_HANDLER( bosco_scrollx_w )
228 {
229 bosco_scrollx = data;
230 }
231
WRITE_HANDLER(bosco_scrolly_w)232 WRITE_HANDLER( bosco_scrolly_w )
233 {
234 bosco_scrolly = data;
235 }
236
WRITE_HANDLER(bosco_starcontrol_w)237 WRITE_HANDLER( bosco_starcontrol_w )
238 {
239 bosco_starcontrol = data;
240 }
241
242
243 /***************************************************************************
244
245 Draw the game screen in the given mame_bitmap.
246 Do NOT call osd_update_display() from this function, it will be called by
247 the main emulation engine.
248
249 ***************************************************************************/
VIDEO_UPDATE(bosco)250 VIDEO_UPDATE( bosco )
251 {
252 int offs,sx,sy;
253
254
255 /* for every character in the Video RAM, check if it has been modified */
256 /* since last time and update it accordingly. */
257 for (offs = videoram_size - 1;offs >= 0;offs--)
258 {
259 if (dirtybuffer2[offs])
260 {
261 int flipx,flipy;
262
263
264 dirtybuffer2[offs] = 0;
265
266 sx = offs % 32;
267 sy = offs / 32;
268 flipx = ~bosco_colorram2[offs] & 0x40;
269 flipy = bosco_colorram2[offs] & 0x80;
270 if (flipscreen)
271 {
272 sx = 31 - sx;
273 sy = 31 - sy;
274 flipx = !flipx;
275 flipy = !flipy;
276 }
277
278 drawgfx(tmpbitmap1,Machine->gfx[0],
279 bosco_videoram2[offs],
280 bosco_colorram2[offs] & 0x3f,
281 flipx,flipy,
282 8*sx,8*sy,
283 0,TRANSPARENCY_NONE,0);
284 }
285 }
286
287 /* update radar */
288 for (offs = videoram_size - 1;offs >= 0;offs--)
289 {
290 if (dirtybuffer[offs])
291 {
292 int flipx,flipy;
293
294
295 dirtybuffer[offs] = 0;
296
297 sx = (offs % 32) ^ 4;
298 sy = offs / 32 - 2;
299 flipx = ~colorram[offs] & 0x40;
300 flipy = colorram[offs] & 0x80;
301 if (flipscreen)
302 {
303 sx = 7 - sx;
304 sy = 27 - sy;
305 flipx = !flipx;
306 flipy = !flipy;
307 }
308
309 drawgfx(tmpbitmap,Machine->gfx[0],
310 videoram[offs],
311 colorram[offs] & 0x3f,
312 flipx,flipy,
313 8*sx,8*sy,
314 &radarvisibleareaflip,TRANSPARENCY_NONE,0);
315 }
316 }
317
318
319 fillbitmap(bitmap,Machine->pens[0],&Machine->visible_area);
320
321
322 /* draw the sprites */
323 for (offs = 0;offs < spriteram_size;offs += 2)
324 {
325 sx = spriteram[offs + 1] - displacement;
326 if (flipscreen) sx += 32;
327 sy = 225 - spriteram_2[offs] - displacement;
328
329 drawgfx(bitmap,Machine->gfx[1],
330 (spriteram[offs] & 0xfc) >> 2,
331 spriteram_2[offs + 1] & 0x3f,
332 spriteram[offs] & 1,spriteram[offs] & 2,
333 sx,sy,
334 flipscreen ? &spritevisibleareaflip : &spritevisiblearea,TRANSPARENCY_COLOR,0);
335 }
336
337
338 /* copy the temporary bitmap to the screen */
339 {
340 int scrollx,scrolly;
341
342
343 if (flipscreen)
344 {
345 scrollx = (bosco_scrollx +32);//- 3*displacement) + 32;
346 scrolly = (bosco_scrolly + 16) - 32;
347 }
348 else
349 {
350 scrollx = -(bosco_scrollx);
351 scrolly = -(bosco_scrolly + 16);
352 }
353
354 copyscrollbitmap(bitmap,tmpbitmap1,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_COLOR,0);
355 }
356
357
358 /* radar */
359 if (flipscreen)
360 copybitmap(bitmap,tmpbitmap,0,0,0,0,&radarvisibleareaflip,TRANSPARENCY_NONE,0);
361 else
362 copybitmap(bitmap,tmpbitmap,0,0,28*8,0,&radarvisiblearea,TRANSPARENCY_NONE,0);
363
364
365 /* draw the dots on the radar and the bullets */
366 for (offs = 0; offs < bosco_radarram_size;offs++)
367 {
368 int x,y;
369
370
371 x = bosco_radarx[offs] + ((~bosco_radarattr[offs] & 0x01) << 8) - 2;
372 y = 235 - bosco_radary[offs];
373 if (flipscreen)
374 {
375 x -= 1;
376 y += 2;
377 }
378
379 drawgfx(bitmap,Machine->gfx[2],
380 ((bosco_radarattr[offs] & 0x0e) >> 1) ^ 0x07,
381 0,
382 flipscreen,flipscreen,
383 x,y,
384 &Machine->visible_area,TRANSPARENCY_PEN,3);
385 }
386
387
388 /* draw the stars */
389 if ((*bosco_staronoff & 1) == 0)
390 {
391 int bpen;
392
393 bpen = Machine->pens[0];
394 for (offs = 0;offs < total_stars;offs++)
395 {
396 int x,y;
397 int set;
398 int starset[4][2] = {{0,3},{0,1},{2,3},{2,1}};
399
400 x = (stars[offs].x + stars_scrollx) % 224;
401 y = (stars[offs].y + stars_scrolly) % 224;
402
403 set = (bosco_starblink[0] & 1) + ((bosco_starblink[1] & 1) << 1);
404
405 if (((stars[offs].set == starset[set][0]) ||
406 (stars[offs].set == starset[set][1])))
407 {
408 if (read_pixel(bitmap, x, y) == bpen)
409 {
410 plot_pixel(bitmap, x, y, stars[offs].col);
411 }
412 }
413 }
414 }
415 }
416
bosco_vh_interrupt(void)417 void bosco_vh_interrupt(void)
418 {
419 int speedsx[8] = { -1, -2, -3, 0, 3, 2, 1, 0 };
420 int speedsy[8] = { 0, -1, -2, -3, 0, 3, 2, 1 };
421
422 stars_scrollx += speedsx[bosco_starcontrol & 7];
423 stars_scrolly += speedsy[(bosco_starcontrol & 56) >> 3];
424 }
425