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 static UINT8 color15_mask[64];
14 
15 
16 /***************************************************************************
17 
18   Convert the color PROMs into a more useable format.
19 
20   digdug has one 32x8 palette PROM and two 256x4 color lookup table PROMs
21   (one for characters, one for sprites). Only the first 128 bytes of the
22   lookup tables seem to be used.
23   The palette PROM is connected to the RGB output this way:
24 
25   bit 7 -- 220 ohm resistor  -- BLUE
26         -- 470 ohm resistor  -- BLUE
27         -- 220 ohm resistor  -- GREEN
28         -- 470 ohm resistor  -- GREEN
29         -- 1  kohm resistor  -- GREEN
30         -- 220 ohm resistor  -- RED
31         -- 470 ohm resistor  -- RED
32   bit 0 -- 1  kohm resistor  -- RED
33 
34 ***************************************************************************/
35 
PALETTE_INIT(superpac)36 PALETTE_INIT( superpac )
37 {
38 	int i, j;
39 
40 	for (i = 0; i < 32; i++)
41 	{
42 		int bit0, bit1, bit2, r, g, b;
43 
44 		bit0 = (color_prom[31-i] >> 0) & 0x01;
45 		bit1 = (color_prom[31-i] >> 1) & 0x01;
46 		bit2 = (color_prom[31-i] >> 2) & 0x01;
47 		r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
48 		bit0 = (color_prom[31-i] >> 3) & 0x01;
49 		bit1 = (color_prom[31-i] >> 4) & 0x01;
50 		bit2 = (color_prom[31-i] >> 5) & 0x01;
51 		g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
52 		bit0 = 0;
53 		bit1 = (color_prom[31-i] >> 6) & 0x01;
54 		bit2 = (color_prom[31-i] >> 7) & 0x01;
55 		b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
56 		palette_set_color(i,r,g,b);
57 	}
58 
59 	/* characters */
60 	for (i = 0; i < 64*4; i++)
61 		colortable[i] = color_prom[i + 32] & 0x0f;
62 
63 	/* sprites */
64 	for (i = 64*4; i < 128*4; i++)
65 		colortable[i] = 0x1f - (color_prom[i + 32] & 0x0f);
66 
67 	/* for sprites, track which pens for each color map to color 31 */
68 	for (i = 0; i < 64; i++)
69 	{
70 		color15_mask[i] = 0;
71 		for (j = 0; j < 4; j++)
72 			if (colortable[64*4 + i*4 + j] == 0x1f)
73 				color15_mask[i] |= 1 << j;
74 	}
75 }
76 
77 
WRITE_HANDLER(superpac_flipscreen_w)78 WRITE_HANDLER( superpac_flipscreen_w )
79 {
80 	flip_screen_set(data);
81 }
82 
83 
84 
READ_HANDLER(superpac_flipscreen_r)85 READ_HANDLER(superpac_flipscreen_r)
86 {
87 	flip_screen_set(1);
88 
89 	return flip_screen;	/* return value not used */
90 }
91 
92 
93 
draw_sprites(struct mame_bitmap * bitmap,struct rectangle * clip,int drawmode)94 static void draw_sprites(struct mame_bitmap *bitmap, struct rectangle *clip, int drawmode)
95 {
96 	const struct GfxElement *gfx = Machine->gfx[1];
97 	int offs;
98 
99 	for (offs = 0; offs < spriteram_size; offs += 2)
100 	{
101 		/* is it on? */
102 		if ((spriteram_3[offs+1] & 2) == 0)
103 		{
104 			int sprite = spriteram[offs];
105 			int color = spriteram[offs+1] & 0x3f;
106 			int x = (spriteram_2[offs+1] - 40) + 0x100*(spriteram_3[offs+1] & 1);
107 			int y = 28*8 - spriteram_2[offs] + 1;
108 			int flipx = spriteram_3[offs] & 1;
109 			int flipy = spriteram_3[offs] & 2;
110 			int pens;
111 
112 			if (flip_screen)
113 			{
114 				flipx = !flipx;
115 				flipy = !flipy;
116 			}
117 
118 			pens = (drawmode == TRANSPARENCY_PENS) ? ~color15_mask[color] : 16;
119 
120 			switch (spriteram_3[offs] & 0x0c)
121 			{
122 				case 0:		/* normal size */
123 					drawgfx(bitmap, gfx, sprite, color, flipx, flipy, x, y, clip, drawmode, pens);
124 					break;
125 
126 				case 4:		/* 2x horizontal */
127 					sprite &= ~1;
128 					if (!flipx)
129 					{
130 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x + 0,  y, clip, drawmode, pens);
131 						drawgfx(bitmap, gfx, sprite + 1, color, flipx, flipy, x + 16, y, clip, drawmode, pens);
132 					}
133 					else
134 					{
135 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x + 16, y, clip, drawmode, pens);
136 						drawgfx(bitmap, gfx, sprite + 1, color, flipx, flipy, x + 0,  y, clip, drawmode, pens);
137 					}
138 					break;
139 
140 				case 8:		/* 2x vertical */
141 					sprite &= ~2;
142 					if (!flipy)
143 					{
144 						drawgfx(bitmap, gfx, sprite + 2, color, flipx, flipy, x, y - 0,  clip, drawmode, pens);
145 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x, y - 16, clip, drawmode, pens);
146 					}
147 					else
148 					{
149 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x, y - 0,  clip, drawmode, pens);
150 						drawgfx(bitmap, gfx, sprite + 2, color, flipx, flipy, x, y - 16, clip, drawmode, pens);
151 					}
152 					break;
153 
154 				case 12:		/* 2x both ways */
155 					sprite &= ~3;
156 					if (!flipx && !flipy)
157 					{
158 						drawgfx(bitmap, gfx, sprite + 2, color, flipx, flipy, x + 0,  y - 0,  clip, drawmode, pens);
159 						drawgfx(bitmap, gfx, sprite + 3, color, flipx, flipy, x + 16, y - 0,  clip, drawmode, pens);
160 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x + 0,  y - 16, clip, drawmode, pens);
161 						drawgfx(bitmap, gfx, sprite + 1, color, flipx, flipy, x + 16, y - 16, clip, drawmode, pens);
162 					}
163 					else if (flipx && flipy)
164 					{
165 						drawgfx(bitmap, gfx, sprite + 1, color, flipx, flipy, x + 0,  y - 0,  clip, drawmode, pens);
166 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x + 16, y - 0,  clip, drawmode, pens);
167 						drawgfx(bitmap, gfx, sprite + 3, color, flipx, flipy, x + 0,  y - 16, clip, drawmode, pens);
168 						drawgfx(bitmap, gfx, sprite + 2, color, flipx, flipy, x + 16, y - 16, clip, drawmode, pens);
169 					}
170 					else if (flipy)
171 					{
172 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x + 0,  y - 0,  clip, drawmode, pens);
173 						drawgfx(bitmap, gfx, sprite + 1, color, flipx, flipy, x + 16, y - 0,  clip, drawmode, pens);
174 						drawgfx(bitmap, gfx, sprite + 2, color, flipx, flipy, x + 0,  y - 16, clip, drawmode, pens);
175 						drawgfx(bitmap, gfx, sprite + 3, color, flipx, flipy, x + 16, y - 16, clip, drawmode, pens);
176 					}
177 					else /* flipx */
178 					{
179 						drawgfx(bitmap, gfx, sprite + 3, color, flipx, flipy, x + 0,  y - 0,  clip, drawmode, pens);
180 						drawgfx(bitmap, gfx, sprite + 2, color, flipx, flipy, x + 16, y - 0,  clip, drawmode, pens);
181 						drawgfx(bitmap, gfx, sprite + 1, color, flipx, flipy, x + 0,  y - 16, clip, drawmode, pens);
182 						drawgfx(bitmap, gfx, sprite + 0, color, flipx, flipy, x + 16, y - 16, clip, drawmode, pens);
183 					}
184 					break;
185 			}
186 		}
187 	}
188 }
189 
190 
191 /***************************************************************************
192 
193   Draw the game screen in the given mame_bitmap.
194   Do NOT call osd_update_display() from this function, it will be called by
195   the main emulation engine.
196 
197 ***************************************************************************/
198 
VIDEO_UPDATE(superpac)199 VIDEO_UPDATE( superpac )
200 {
201 	int offs;
202 
203 	if (get_vh_global_attribute_changed())
204 		memset(dirtybuffer, 1, videoram_size);
205 
206 	/* for every character in the Video RAM, check if it has been modified */
207 	/* since last time and update it accordingly. */
208 	for (offs = videoram_size - 1; offs >= 0; offs--)
209 		if (dirtybuffer[offs])
210 		{
211 			int sx, sy, mx, my;
212 
213 			dirtybuffer[offs] = 0;
214 
215 			/* Even if Super Pac-Man's screen is 28x36, the memory layout is 32x32. We therefore */
216 			/* have to convert the memory coordinates into screen coordinates. */
217 			/* Note that 32*32 = 1024, while 28*36 = 1008: therefore 16 bytes of Video RAM */
218 			/* don't map to a screen position. We don't check that here, however: range */
219 			/* checking is performed by drawgfx(). */
220 
221 			mx = offs % 32;
222 			my = offs / 32;
223 
224 			if (my <= 1)
225 			{
226 				sx = my + 34;
227 				sy = mx - 2;
228 			}
229 			else if (my >= 30)
230 			{
231 				sx = my - 30;
232 				sy = mx - 2;
233 			}
234 			else
235 			{
236 				sx = mx + 2;
237 				sy = my - 2;
238 			}
239 
240 			if (flip_screen)
241 			{
242 				sx = 35 - sx;
243 				sy = 27 - sy;
244 			}
245 
246 			drawgfx(tmpbitmap, Machine->gfx[0], videoram[offs], colorram[offs],
247 					flip_screen, flip_screen, 8 * sx, 8 * sy,
248 					&Machine->visible_area, TRANSPARENCY_NONE, 0);
249 		}
250 
251 	/* copy the character mapped graphics */
252 	copybitmap(bitmap, tmpbitmap, 0, 0, 0, 0, &Machine->visible_area, TRANSPARENCY_NONE, 0);
253 
254 	/* Draw the sprites. */
255 	draw_sprites(bitmap, &Machine->visible_area, TRANSPARENCY_COLOR);
256 
257 	/* Draw the high priority characters */
258 	for (offs = videoram_size - 1;offs >= 0;offs--)
259 		if (colorram[offs] & 0x40)
260 		{
261 			int sx, sy, mx, my;
262 
263 			mx = offs % 32;
264 			my = offs / 32;
265 
266 			if (my <= 1)
267 			{
268 				sx = my + 34;
269 				sy = mx - 2;
270 			}
271 			else if (my >= 30)
272 			{
273 				sx = my - 30;
274 				sy = mx - 2;
275 			}
276 			else
277 			{
278 				sx = mx + 2;
279 				sy = my - 2;
280 			}
281 
282 			if (flip_screen)
283 			{
284 				sx = 35 - sx;
285 				sy = 27 - sy;
286 			}
287 
288 			drawgfx(bitmap, Machine->gfx[0], videoram[offs], colorram[offs],
289 					flip_screen, flip_screen, 8 * sx, 8 * sy,
290 					&Machine->visible_area, TRANSPARENCY_COLOR, 31);
291 		}
292 
293 	/* Color 31 still has priority over that (ghost eyes in Pac 'n Pal) */
294 	draw_sprites(bitmap, &Machine->visible_area, TRANSPARENCY_PENS);
295 }
296