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