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 #include "osdepend.h"
13
14 unsigned char *sidearms_bg_scrollx,*sidearms_bg_scrolly;
15 unsigned char *sidearms_bg2_scrollx,*sidearms_bg2_scrolly;
16 static struct osd_bitmap *tmpbitmap2;
17 static int flipscreen;
18 static int bgon,objon;
19
20
21 /***************************************************************************
22
23 Start the video hardware emulation.
24
25 ***************************************************************************/
26
sidearms_vh_start(void)27 int sidearms_vh_start(void)
28 {
29 if (generic_vh_start() != 0)
30 return 1;
31
32 /* create a temporary bitmap slightly larger than the screen for the background */
33 if ((tmpbitmap2 = bitmap_alloc(48*8 + 32,Machine->drv->screen_height + 32)) == 0)
34 {
35 generic_vh_stop();
36 return 1;
37 }
38
39 return 0;
40 }
41
42
43
44 /***************************************************************************
45
46 Stop the video hardware emulation.
47
48 ***************************************************************************/
sidearms_vh_stop(void)49 void sidearms_vh_stop(void)
50 {
51 bitmap_free(tmpbitmap2);
52 generic_vh_stop();
53 }
54
55
56
WRITE_HANDLER(sidearms_c804_w)57 WRITE_HANDLER( sidearms_c804_w )
58 {
59 /* bits 0 and 1 are coin counters */
60 coin_counter_w(0,data & 0x01);
61 coin_counter_w(1,data & 0x02);
62
63 /* bit 4 probably resets the sound CPU */
64
65 /* TODO: I don't know about the other bits (all used) */
66
67 /* bit 7 flips screen */
68 if (flipscreen != (data & 0x80))
69 {
70 flipscreen = data & 0x80;
71 /* TODO: support screen flip */
72 // memset(dirtybuffer,1,c1942_backgroundram_size);
73 }
74 }
75
WRITE_HANDLER(sidearms_gfxctrl_w)76 WRITE_HANDLER( sidearms_gfxctrl_w )
77 {
78 objon = data & 0x01;
79 bgon = data & 0x02;
80 }
81
82
83 /***************************************************************************
84
85 Draw the game screen in the given osd_bitmap.
86 Do NOT call osd_update_display() from this function, it will be called by
87 the main emulation engine.
88
89 ***************************************************************************/
sidearms_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)90 void sidearms_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
91 {
92 int offs, sx, sy;
93 int scrollx,scrolly;
94 static int lastoffs;
95 int dirtypalette = 0;
96
97
98 palette_init_used_colors();
99
100
101 {
102 int color,code,i;
103 int colmask[64];
104 int pal_base;
105 unsigned char *p=memory_region(REGION_GFX4);
106
107
108 pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
109
110 for (color = 0;color < 32;color++) colmask[color] = 0;
111
112 scrollx = sidearms_bg_scrollx[0] + 256 * sidearms_bg_scrollx[1] + 64;
113 scrolly = sidearms_bg_scrolly[0] + 256 * sidearms_bg_scrolly[1];
114 offs = 2 * (scrollx >> 5) + 0x100 * (scrolly >> 5);
115 scrollx = -(scrollx & 0x1f);
116 scrolly = -(scrolly & 0x1f);
117
118 for (sy = 0;sy < 9;sy++)
119 {
120 for (sx = 0; sx < 13; sx++)
121 {
122 int offset;
123
124
125 offset = offs + 2 * sx;
126
127 /* swap bits 1-7 and 8-10 of the address to compensate for the */
128 /* funny layout of the ROM data */
129 offset = (offset & 0xf801) | ((offset & 0x0700) >> 7) | ((offset & 0x00fe) << 3);
130
131 code = p[offset] + 256 * (p[offset+1] & 0x01);
132 color = (p[offset+1] & 0xf8) >> 3;
133 colmask[color] |= Machine->gfx[1]->pen_usage[code];
134 }
135 offs += 0x100;
136 }
137
138 for (color = 0;color < 32;color++)
139 {
140 if (colmask[color] & (1 << 15))
141 palette_used_colors[pal_base + 16 * color + 15] = PALETTE_COLOR_TRANSPARENT;
142 for (i = 0;i < 15;i++)
143 {
144 if (colmask[color] & (1 << i))
145 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
146 }
147 }
148
149
150 pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
151
152 for (color = 0;color < 16;color++) colmask[color] = 0;
153
154 for (offs = spriteram_size - 32;offs >= 0;offs -= 32)
155 {
156 code = spriteram[offs] + 8 * (spriteram[offs + 1] & 0xe0);
157 color = spriteram[offs + 1] & 0x0f;
158 colmask[color] |= Machine->gfx[2]->pen_usage[code];
159 }
160
161 for (color = 0;color < 16;color++)
162 {
163 if (colmask[color] & (1 << 15))
164 palette_used_colors[pal_base + 16 * color + 15] = PALETTE_COLOR_TRANSPARENT;
165 for (i = 0;i < 15;i++)
166 {
167 if (colmask[color] & (1 << i))
168 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
169 }
170 }
171
172
173 pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
174
175 for (color = 0;color < 64;color++) colmask[color] = 0;
176
177 for (offs = videoram_size - 1;offs >= 0;offs--)
178 {
179 code = videoram[offs] + 4 * (colorram[offs] & 0xc0);
180 color = colorram[offs] & 0x3f;
181 colmask[color] |= Machine->gfx[0]->pen_usage[code];
182 }
183
184 for (color = 0;color < 64;color++)
185 {
186 if (colmask[color] & (1 << 3))
187 palette_used_colors[pal_base + 4 * color + 3] = PALETTE_COLOR_TRANSPARENT;
188 for (i = 0;i < 3;i++)
189 {
190 if (colmask[color] & (1 << i))
191 palette_used_colors[pal_base + 4 * color + i] = PALETTE_COLOR_USED;
192 }
193 }
194 }
195
196 if (palette_recalc())
197 dirtypalette = 1;
198
199
200 /* There is a scrolling blinking star background behind the tile */
201 /* background, but I have absolutely NO IDEA how to render it. */
202 /* The scroll registers have a 64 pixels resolution. */
203 #if IHAVETHEBACKGROUND
204 {
205 int x,y;
206 for (x = 0;x < 48;x+=8)
207 {
208 for (y = 0;y < 32;y+=8)
209 {
210 drawgfx(tmpbitmap,Machine->gfx[0],
211 (y%8)*48+(x%8),
212 0,
213 0,0,
214 8*x,8*y,
215 0,TRANSPARENCY_NONE,0);
216 }
217 }
218 }
219
220 /* copy the temporary bitmap to the screen */
221 scrollx = -(*sidearms_bg2_scrollx & 0x3f);
222 scrolly = -(*sidearms_bg2_scrolly & 0x3f);
223
224 copyscrollbitmap(bitmap,tmpbitmap,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
225 #endif
226
227
228 if (bgon)
229 {
230 scrollx = sidearms_bg_scrollx[0] + 256 * sidearms_bg_scrollx[1] + 64;
231 scrolly = sidearms_bg_scrolly[0] + 256 * sidearms_bg_scrolly[1];
232 offs = 2 * (scrollx >> 5) + 0x100 * (scrolly >> 5);
233 scrollx = -(scrollx & 0x1f);
234 scrolly = -(scrolly & 0x1f);
235
236 if (offs != lastoffs || dirtypalette)
237 {
238 unsigned char *p=memory_region(REGION_GFX4);
239
240
241 lastoffs = offs;
242
243 /* Draw the entire background scroll */
244 for (sy = 0;sy < 9;sy++)
245 {
246 for (sx = 0; sx < 13; sx++)
247 {
248 int offset;
249
250
251 offset = offs + 2 * sx;
252
253 /* swap bits 1-7 and 8-10 of the address to compensate for the */
254 /* funny layout of the ROM data */
255 offset = (offset & 0xf801) | ((offset & 0x0700) >> 7) | ((offset & 0x00fe) << 3);
256
257 drawgfx(tmpbitmap2,Machine->gfx[1],
258 p[offset] + 256 * (p[offset+1] & 0x01),
259 (p[offset+1] & 0xf8) >> 3,
260 p[offset+1] & 0x02,p[offset+1] & 0x04,
261 32*sx,32*sy,
262 0,TRANSPARENCY_NONE,0);
263 }
264 offs += 0x100;
265 }
266 }
267
268 scrollx += 64;
269 #if IHAVETHEBACKGROUND
270 copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_COLOR,1);
271 #else
272 copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
273 #endif
274 }
275 else fillbitmap(bitmap,Machine->pens[0],&Machine->visible_area);
276
277 /* Draw the sprites. */
278 if (objon)
279 {
280 for (offs = spriteram_size - 32;offs >= 0;offs -= 32)
281 {
282 sx = spriteram[offs + 3] + ((spriteram[offs + 1] & 0x10) << 4);
283 sy = spriteram[offs + 2];
284 if (flipscreen)
285 {
286 sx = 496 - sx;
287 sy = 240 - sy;
288 }
289
290 drawgfx(bitmap,Machine->gfx[2],
291 spriteram[offs] + 8 * (spriteram[offs + 1] & 0xe0),
292 spriteram[offs + 1] & 0x0f,
293 flipscreen,flipscreen,
294 sx,sy,
295 &Machine->visible_area,TRANSPARENCY_PEN,15);
296 }
297 }
298
299
300 /* draw the frontmost playfield. They are characters, but draw them as sprites */
301 for (offs = videoram_size - 1;offs >= 0;offs--)
302 {
303 sx = offs % 64;
304 sy = offs / 64;
305
306 if (flipscreen)
307 {
308 sx = 63 - sx;
309 sy = 31 - sy;
310 }
311
312 drawgfx(bitmap,Machine->gfx[0],
313 videoram[offs] + 4 * (colorram[offs] & 0xc0),
314 colorram[offs] & 0x3f,
315 flipscreen,flipscreen,
316 8*sx,8*sy,
317 &Machine->visible_area,TRANSPARENCY_PEN,3);
318 }
319 }
320