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