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 #include "state.h"
12 
13 
14 static struct rectangle spritevisiblearea =
15 {
16 	2*8, 32*8-1,
17 	2*8, 30*8-1
18 };
19 
20 static struct rectangle spritevisibleareaflipx =
21 {
22 	0*8, 30*8-1,
23 	2*8, 30*8-1
24 };
25 
26 unsigned char *wiz_videoram2;
27 unsigned char *wiz_colorram2;
28 unsigned char *wiz_attributesram;
29 unsigned char *wiz_attributesram2;
30 
31 static int flipx, flipy;
32 static int bgpen;
33 
34 unsigned char *wiz_sprite_bank;
35 static unsigned char char_bank[2];
36 static unsigned char palbank[2];
37 static int palette_bank;
38 
39 
VIDEO_START(wiz)40 VIDEO_START( wiz )
41 {
42 	if (video_start_generic())
43 		return 1;
44 
45 	state_save_register_UINT8("wiz", 0, "char_bank",   char_bank,   2);
46 	state_save_register_UINT8("wiz", 0, "palbank",	   palbank,     2);
47 	state_save_register_int  ("wiz", 0, "flipx",       &flipx);
48 	state_save_register_int  ("wiz", 0, "flipy",       &flipy);
49 	state_save_register_int  ("wiz", 0, "bgpen",       &bgpen);
50 
51 	return 0;
52 }
53 
54 /***************************************************************************
55 
56   Convert the color PROMs into a more useable format.
57 
58   Stinger has three 256x4 palette PROMs (one per gun).
59   The palette PROMs are connected to the RGB output this way:
60 
61   bit 3 -- 100 ohm resistor  -- RED/GREEN/BLUE
62         -- 220 ohm resistor  -- RED/GREEN/BLUE
63         -- 470 ohm resistor  -- RED/GREEN/BLUE
64   bit 0 -- 1  kohm resistor  -- RED/GREEN/BLUE
65 
66 ***************************************************************************/
PALETTE_INIT(wiz)67 PALETTE_INIT( wiz )
68 {
69 	int i;
70 
71 
72 	for (i = 0;i < Machine->drv->total_colors;i++)
73 	{
74 		int bit0,bit1,bit2,bit3,r,g,b;
75 
76 
77 		bit0 = (color_prom[0] >> 0) & 0x01;
78 		bit1 = (color_prom[0] >> 1) & 0x01;
79 		bit2 = (color_prom[0] >> 2) & 0x01;
80 		bit3 = (color_prom[0] >> 3) & 0x01;
81 		r = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
82 		bit0 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
83 		bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
84 		bit2 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
85 		bit3 = (color_prom[Machine->drv->total_colors] >> 3) & 0x01;
86 		g = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
87 		bit0 = (color_prom[2*Machine->drv->total_colors] >> 0) & 0x01;
88 		bit1 = (color_prom[2*Machine->drv->total_colors] >> 1) & 0x01;
89 		bit2 = (color_prom[2*Machine->drv->total_colors] >> 2) & 0x01;
90 		bit3 = (color_prom[2*Machine->drv->total_colors] >> 3) & 0x01;
91 		b = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
92 
93 		palette_set_color(i,r,g,b);
94 
95 		color_prom++;
96 	}
97 }
98 
WRITE_HANDLER(wiz_attributes_w)99 WRITE_HANDLER( wiz_attributes_w )
100 {
101 	if ((offset & 1) && wiz_attributesram[offset] != data)
102 	{
103 		int i;
104 
105 
106 		for (i = offset / 2;i < videoram_size;i += 32)
107 		{
108 			dirtybuffer[i] = 1;
109 		}
110 	}
111 
112 	wiz_attributesram[offset] = data;
113 }
114 
WRITE_HANDLER(wiz_palettebank_w)115 WRITE_HANDLER( wiz_palettebank_w )
116 {
117 	if (palbank[offset] != (data & 1))
118 	{
119 		palbank[offset] = data & 1;
120 		palette_bank = palbank[0] + 2 * palbank[1];
121 
122 		memset(dirtybuffer,1,videoram_size);
123 	}
124 }
125 
WRITE_HANDLER(wiz_bgcolor_w)126 WRITE_HANDLER( wiz_bgcolor_w )
127 {
128 	bgpen = data;
129 }
130 
WRITE_HANDLER(wiz_char_bank_select_w)131 WRITE_HANDLER( wiz_char_bank_select_w )
132 {
133 	if (char_bank[offset] != (data & 1))
134 	{
135 		char_bank[offset] = data & 1;
136 		memset(dirtybuffer,1,videoram_size);
137 	}
138 }
139 
WRITE_HANDLER(wiz_flipx_w)140 WRITE_HANDLER( wiz_flipx_w )
141 {
142     if (flipx != data)
143     {
144 		flipx = data;
145 
146 		memset(dirtybuffer, 1, videoram_size);
147     }
148 }
149 
150 
WRITE_HANDLER(wiz_flipy_w)151 WRITE_HANDLER( wiz_flipy_w )
152 {
153     if (flipy != data)
154     {
155 		flipy = data;
156 
157 		memset(dirtybuffer, 1, videoram_size);
158     }
159 }
160 
draw_background(struct mame_bitmap * bitmap,int bank,int colortype)161 static void draw_background(struct mame_bitmap *bitmap, int bank, int colortype)
162 {
163 	int offs;
164 
165 	/* for every character in the Video RAM, check if it has been modified */
166 	/* since last time and update it accordingly. */
167 
168 	for (offs = videoram_size - 1;offs >= 0;offs--)
169 	{
170 		int scroll,sx,sy,col;
171 
172 		sx = offs % 32;
173 		sy = offs / 32;
174 
175 		if (colortype)
176 		{
177 			col = (wiz_attributesram[2 * sx + 1] & 0x07);
178 		}
179 		else
180 		{
181 			col = (wiz_attributesram[2 * (offs % 32) + 1] & 0x04) + (videoram[offs] & 3);
182 		}
183 
184 		scroll = (8*sy + 256 - wiz_attributesram[2 * sx]) % 256;
185 		if (flipy)
186 		{
187 		   scroll = (248 - scroll) % 256;
188 		}
189 		if (flipx) sx = 31 - sx;
190 
191 
192 		drawgfx(bitmap,Machine->gfx[bank],
193 			videoram[offs],
194 			col + 8 * palette_bank,
195 			flipx,flipy,
196 			8*sx,scroll,
197 			&Machine->visible_area,TRANSPARENCY_PEN,0);
198 	}
199 }
200 
draw_foreground(struct mame_bitmap * bitmap,int colortype)201 static void draw_foreground(struct mame_bitmap *bitmap, int colortype)
202 {
203 	int offs;
204 
205 	/* draw the frontmost playfield. They are characters, but draw them as sprites. */
206 	for (offs = videoram_size - 1;offs >= 0;offs--)
207 	{
208 		int scroll,sx,sy,col;
209 
210 
211 		sx = offs % 32;
212 		sy = offs / 32;
213 
214 		if (colortype)
215 		{
216 			col = (wiz_attributesram2[2 * sx + 1] & 0x07);
217 		}
218 		else
219 		{
220 			col = (wiz_colorram2[offs] & 0x07);
221 		}
222 
223 		scroll = (8*sy + 256 - wiz_attributesram2[2 * sx]) % 256;
224 		if (flipy)
225 		{
226 		   scroll = (248 - scroll) % 256;
227 		}
228 		if (flipx) sx = 31 - sx;
229 
230 
231 		drawgfx(bitmap,Machine->gfx[char_bank[1]],
232 			wiz_videoram2[offs],
233 			col + 8 * palette_bank,
234 			flipx,flipy,
235 			8*sx,scroll,
236 			&Machine->visible_area,TRANSPARENCY_PEN,0);
237 	}
238 }
239 
draw_sprites(struct mame_bitmap * bitmap,unsigned char * sprite_ram,int bank,const struct rectangle * visible_area)240 static void draw_sprites(struct mame_bitmap *bitmap, unsigned char* sprite_ram,
241                          int bank, const struct rectangle* visible_area)
242 {
243 	int offs;
244 
245 	for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
246 	{
247 		int sx,sy;
248 
249 
250 		sx = sprite_ram[offs + 3];
251 		sy = sprite_ram[offs];
252 
253 		if (!sx || !sy) continue;
254 
255 		if ( flipx) sx = 240 - sx;
256 		if (!flipy) sy = 240 - sy;
257 
258 		drawgfx(bitmap,Machine->gfx[bank],
259 				sprite_ram[offs + 1],
260 				(sprite_ram[offs + 2] & 0x07) + 8 * palette_bank,
261 				flipx,flipy,
262 				sx,sy,
263 				visible_area,TRANSPARENCY_PEN,0);
264 	}
265 }
266 
267 /***************************************************************************
268 
269   Draw the game screen in the given mame_bitmap.
270   Do NOT call osd_update_display() from this function, it will be called by
271   the main emulation engine.
272 
273 ***************************************************************************/
274 
VIDEO_UPDATE(kungfut)275 VIDEO_UPDATE( kungfut )
276 {
277 	fillbitmap(bitmap,Machine->pens[bgpen],&Machine->visible_area);
278 	draw_background(bitmap, 2 + char_bank[0] , 0);
279 	draw_foreground(bitmap, 0);
280 	draw_sprites(bitmap, spriteram_2, 4, &Machine->visible_area);
281 	draw_sprites(bitmap, spriteram  , 5, &Machine->visible_area);
282 }
283 
VIDEO_UPDATE(wiz)284 VIDEO_UPDATE( wiz )
285 {
286 	int bank;
287 	const struct rectangle* visible_area;
288 
289 	fillbitmap(bitmap,Machine->pens[bgpen],&Machine->visible_area);
290 	draw_background(bitmap, 2 + ((char_bank[0] << 1) | char_bank[1]), 0);
291 	draw_foreground(bitmap, 0);
292 
293 	visible_area = flipx ? &spritevisibleareaflipx : &spritevisiblearea;
294 
295     bank = 7 + *wiz_sprite_bank;
296 
297 	draw_sprites(bitmap, spriteram_2, 6,    visible_area);
298 	draw_sprites(bitmap, spriteram  , bank, visible_area);
299 }
300 
301 
VIDEO_UPDATE(stinger)302 VIDEO_UPDATE( stinger )
303 {
304 	fillbitmap(bitmap,Machine->pens[bgpen],&Machine->visible_area);
305 	draw_background(bitmap, 2 + char_bank[0], 1);
306 	draw_foreground(bitmap, 1);
307 	draw_sprites(bitmap, spriteram_2, 4, &Machine->visible_area);
308 	draw_sprites(bitmap, spriteram  , 5, &Machine->visible_area);
309 }
310