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