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