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 
14 unsigned char *gunsmoke_bg_scrolly;
15 unsigned char *gunsmoke_bg_scrollx;
16 static int chon,objon,bgon;
17 static int sprite3bank;
18 static int flipscreen;
19 
20 static struct osd_bitmap * bgbitmap;
21 static unsigned char bgmap[9][9][2];
22 
23 
24 /***************************************************************************
25 
26   Convert the color PROMs into a more useable format.
27 
28   Gunsmoke has three 256x4 palette PROMs (one per gun) and a lot ;-) of
29   256x4 lookup table PROMs.
30   The palette PROMs are connected to the RGB output this way:
31 
32   bit 3 -- 220 ohm resistor  -- RED/GREEN/BLUE
33         -- 470 ohm resistor  -- RED/GREEN/BLUE
34         -- 1  kohm resistor  -- RED/GREEN/BLUE
35   bit 0 -- 2.2kohm resistor  -- RED/GREEN/BLUE
36 
37 ***************************************************************************/
gunsmoke_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)38 void gunsmoke_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
39 {
40 	int i;
41 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
42 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
43 
44 
45 	for (i = 0;i < Machine->drv->total_colors;i++)
46 	{
47 		int bit0,bit1,bit2,bit3;
48 
49 
50 		bit0 = (color_prom[0] >> 0) & 0x01;
51 		bit1 = (color_prom[0] >> 1) & 0x01;
52 		bit2 = (color_prom[0] >> 2) & 0x01;
53 		bit3 = (color_prom[0] >> 3) & 0x01;
54 		*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
55 		bit0 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
56 		bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
57 		bit2 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
58 		bit3 = (color_prom[Machine->drv->total_colors] >> 3) & 0x01;
59 		*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
60 		bit0 = (color_prom[2*Machine->drv->total_colors] >> 0) & 0x01;
61 		bit1 = (color_prom[2*Machine->drv->total_colors] >> 1) & 0x01;
62 		bit2 = (color_prom[2*Machine->drv->total_colors] >> 2) & 0x01;
63 		bit3 = (color_prom[2*Machine->drv->total_colors] >> 3) & 0x01;
64 		*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
65 
66 		color_prom++;
67 	}
68 
69 	color_prom += 2*Machine->drv->total_colors;
70 	/* color_prom now points to the beginning of the lookup table */
71 
72 	/* characters use colors 64-79 */
73 	for (i = 0;i < TOTAL_COLORS(0);i++)
74 		COLOR(0,i) = *(color_prom++) + 64;
75 	color_prom += 128;	/* skip the bottom half of the PROM - not used */
76 
77 	/* background tiles use colors 0-63 */
78 	for (i = 0;i < TOTAL_COLORS(1);i++)
79 	{
80 		COLOR(1,i) = color_prom[0] + 16 * (color_prom[256] & 0x03);
81 		color_prom++;
82 	}
83 	color_prom += TOTAL_COLORS(1);
84 
85 	/* sprites use colors 128-255 */
86 	for (i = 0;i < TOTAL_COLORS(2);i++)
87 	{
88 		COLOR(2,i) = color_prom[0] + 16 * (color_prom[256] & 0x07) + 128;
89 		color_prom++;
90 	}
91 	color_prom += TOTAL_COLORS(2);
92 }
93 
94 
95 
gunsmoke_vh_start(void)96 int gunsmoke_vh_start(void)
97 {
98 	if ((bgbitmap = bitmap_alloc(9*32,9*32)) == 0)
99 		return 1;
100 
101 	if (generic_vh_start() == 1)
102 	{
103 		bitmap_free(bgbitmap);
104 		return 1;
105 	}
106 
107 	memset (bgmap, 0xff, sizeof (bgmap));
108 
109 	return 0;
110 }
111 
112 
gunsmoke_vh_stop(void)113 void gunsmoke_vh_stop(void)
114 {
115 	bitmap_free(bgbitmap);
116 }
117 
118 
119 
WRITE_HANDLER(gunsmoke_c804_w)120 WRITE_HANDLER( gunsmoke_c804_w )
121 {
122 	int bankaddress;
123 	unsigned char *RAM = memory_region(REGION_CPU1);
124 
125 
126 	/* bits 0 and 1 are for coin counters? - we ignore them */
127 
128 	/* bits 2 and 3 select the ROM bank */
129 	bankaddress = 0x10000 + (data & 0x0c) * 0x1000;
130 	cpu_setbank(1,&RAM[bankaddress]);
131 
132 	/* bit 5 resets the sound CPU? - we ignore it */
133 
134 	/* bit 6 flips screen */
135 	if (flipscreen != (data & 0x40))
136 	{
137 		flipscreen = data & 0x40;
138 //		memset(dirtybuffer,1,c1942_backgroundram_size);
139 	}
140 
141 	/* bit 7 enables characters? */
142 	chon = data & 0x80;
143 }
144 
145 
146 
WRITE_HANDLER(gunsmoke_d806_w)147 WRITE_HANDLER( gunsmoke_d806_w )
148 {
149 	/* bits 0-2 select the sprite 3 bank */
150 	sprite3bank = data & 0x07;
151 
152 	/* bit 4 enables bg 1? */
153 	bgon = data & 0x10;
154 
155 	/* bit 5 enables sprites? */
156 	objon = data & 0x20;
157 }
158 
159 
160 
161 /***************************************************************************
162 
163   Draw the game screen in the given osd_bitmap.
164   Do NOT call osd_update_display() from this function, it will be called by
165   the main emulation engine.
166 
167 ***************************************************************************/
gunsmoke_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)168 void gunsmoke_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
169 {
170 	int offs,sx,sy;
171 	int bg_scrolly, bg_scrollx;
172 	unsigned char *p=memory_region(REGION_GFX4);
173 	int top,left,xscroll,yscroll;
174 
175 
176 /* TODO: support flipscreen */
177 	if (bgon)
178 	{
179 		bg_scrolly = gunsmoke_bg_scrolly[0] + 256 * gunsmoke_bg_scrolly[1];
180 		bg_scrollx = gunsmoke_bg_scrollx[0];
181 		offs = 16 * ((bg_scrolly>>5)+8)+2*(bg_scrollx>>5) ;
182 		if (bg_scrollx & 0x80) offs -= 0x10;
183 
184 		top = 8 - (bg_scrolly>>5) % 9;
185 		left = (bg_scrollx>>5) % 9;
186 
187 		bg_scrolly&=0x1f;
188 		bg_scrollx&=0x1f;
189 
190 		for (sy = 0;sy <9;sy++)
191 		{
192 			int ty = (sy + top) % 9;
193 			offs &= 0x7fff; /* Enforce limits (for top of scroll) */
194 
195 			for (sx = 0;sx < 9;sx++)
196 			{
197 				int tile, attr, offset;
198 				int tx = (sx + left) % 9;
199 				unsigned char *map = &bgmap[ty][tx][0];
200 				offset=offs+(sx*2);
201 
202 				tile=p[offset];
203 				attr=p[offset+1];
204 
205 				if (tile != map[0] || attr != map[1])
206 				{
207 					map[0] = tile;
208 					map[1] = attr;
209 					tile+=256*(attr&0x01);
210 					drawgfx(bgbitmap,Machine->gfx[1],
211 							tile,
212 							(attr & 0x3c) >> 2,
213 							attr & 0x40,attr & 0x80,
214 							(8-ty)*32, tx*32,
215 							0,
216 							TRANSPARENCY_NONE,0);
217 				}
218 				map += 2;
219 			}
220 			offs-=0x10;
221 		}
222 
223 		xscroll = (top*32-bg_scrolly);
224 		yscroll = -(left*32+bg_scrollx);
225 		copyscrollbitmap(bitmap,bgbitmap,
226 			1,&xscroll,
227 			1,&yscroll,
228 			&Machine->visible_area,
229 			TRANSPARENCY_NONE,0);
230 	}
231 	else fillbitmap(bitmap,Machine->pens[0],&Machine->visible_area);
232 
233 
234 
235 	if (objon)
236 	{
237 		/* Draw the sprites. */
238 		for (offs = spriteram_size - 32;offs >= 0;offs -= 32)
239 		{
240 			int bank,flipx,flipy;
241 
242 
243 			bank = (spriteram[offs + 1] & 0xc0) >> 6;
244 			if (bank == 3) bank += sprite3bank;
245 
246 			sx = spriteram[offs + 3] - ((spriteram[offs + 1] & 0x20) << 3);
247  			sy = spriteram[offs + 2];
248 			flipx = 0;
249 			flipy = spriteram[offs + 1] & 0x10;
250 			if (flipscreen)
251 			{
252 				sx = 240 - sx;
253 				sy = 240 - sy;
254 				flipx = !flipx;
255 				flipy = !flipy;
256 			}
257 
258 			drawgfx(bitmap,Machine->gfx[2],
259 					spriteram[offs] + 256 * bank,
260 					spriteram[offs + 1] & 0x0f,
261 					flipx,flipy,
262 					sx,sy,
263 					&Machine->visible_area,TRANSPARENCY_PEN,0);
264 		}
265 	}
266 
267 
268 	if (chon)
269 	{
270 		/* draw the frontmost playfield. They are characters, but draw them as sprites */
271 		for (offs = videoram_size - 1;offs >= 0;offs--)
272 		{
273 			sx = offs % 32;
274 			sy = offs / 32;
275 			if (flipscreen)
276 			{
277 				sx = 31 - sx;
278 				sy = 31 - sy;
279 			}
280 
281 			drawgfx(bitmap,Machine->gfx[0],
282 					videoram[offs] + ((colorram[offs] & 0xc0) << 2),
283 					colorram[offs] & 0x1f,
284 					!flipscreen,!flipscreen,
285 					8*sx,8*sy,
286 					&Machine->visible_area,TRANSPARENCY_COLOR,79);
287 		}
288 	}
289 }
290