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