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 data8_t *cop01_bgvideoram,*cop01_fgvideoram;
15 
16 static unsigned char mightguy_vreg[4];
17 static struct tilemap *bg_tilemap,*fg_tilemap;
18 
19 
20 
PALETTE_INIT(cop01)21 PALETTE_INIT( cop01 )
22 {
23 	int i;
24 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
25 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
26 
27 	for (i = 0;i < Machine->drv->total_colors;i++)
28 	{
29 		int bit0,bit1,bit2,bit3,r,g,b;
30 
31 		bit0 = (color_prom[0] >> 0) & 0x01;
32 		bit1 = (color_prom[0] >> 1) & 0x01;
33 		bit2 = (color_prom[0] >> 2) & 0x01;
34 		bit3 = (color_prom[0] >> 3) & 0x01;
35 		r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
36 		bit0 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
37 		bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
38 		bit2 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
39 		bit3 = (color_prom[Machine->drv->total_colors] >> 3) & 0x01;
40 		g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
41 		bit0 = (color_prom[2*Machine->drv->total_colors] >> 0) & 0x01;
42 		bit1 = (color_prom[2*Machine->drv->total_colors] >> 1) & 0x01;
43 		bit2 = (color_prom[2*Machine->drv->total_colors] >> 2) & 0x01;
44 		bit3 = (color_prom[2*Machine->drv->total_colors] >> 3) & 0x01;
45 		b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
46 
47 		palette_set_color(i,r,g,b);
48 		color_prom++;
49 	}
50 
51 	color_prom += 2*Machine->drv->total_colors;
52 	/* color_prom now points to the beginning of the lookup tables */
53 
54 	/* characters use colors 0-15 (or 0-127, but the eight rows are identical) */
55 	for (i = 0;i < TOTAL_COLORS(0);i++)
56 		COLOR(0,i) = i;
57 
58 	/* background tiles use colors 192-255 */
59 	/* I don't know how much of the lookup table PROM is hooked up, */
60 	/* I'm only using the first 32 bytes because the rest is empty. */
61 	for (i = 0;i < TOTAL_COLORS(1);i++)
62 		COLOR(1,i) = 0xc0 + (i & 0x30) + (color_prom[((i & 0x40) >> 2) + (i & 0x0f)] & 0x0f);
63 	color_prom += 256;
64 
65 	/* sprites use colors 128-143 (or 128-191, but the four rows are identical) */
66 	for (i = 0;i < TOTAL_COLORS(2);i++)
67 		COLOR(2,i) = 0x80 + (*(color_prom++) & 0x0f);
68 }
69 
70 
71 
72 /***************************************************************************
73 
74   Callbacks for the TileMap code
75 
76 ***************************************************************************/
77 
get_bg_tile_info(int tile_index)78 static void get_bg_tile_info(int tile_index)
79 {
80 	int tile = cop01_bgvideoram[tile_index];
81 	int attr = cop01_bgvideoram[tile_index+0x800];
82 	int pri  = (attr & 0x80) >> 7;
83 
84 	/* kludge: priority is not actually pen based, but color based. Since the
85 	 * game uses a lookup table, the two are not the same thing.
86 	 * Palette entries with bits 2&3 set have priority over sprites.
87 	 * tilemap.c can't handle that yet, so I'm cheating, because I know that
88 	 * color codes using the second row of the lookup table don't use palette
89 	 * entries 12-15.
90 	 * The only place where this has any effect is the beach at the bottom of
91 	 * the screen right at the beginning of mightguy. cop01 doesn't seem to
92 	 * use priority at all.
93 	 */
94 	if (attr & 0x10) pri = 0;
95 
96 	SET_TILE_INFO(1,tile + ((attr & 0x03) << 8),(attr & 0x1c) >> 2,TILE_SPLIT(pri));
97 }
98 
get_fg_tile_info(int tile_index)99 static void get_fg_tile_info(int tile_index)
100 {
101 	int tile = cop01_fgvideoram[tile_index];
102 	SET_TILE_INFO(0,tile,0,0);
103 }
104 
105 
106 
107 /***************************************************************************
108 
109   Start the video hardware emulation.
110 
111 ***************************************************************************/
112 
VIDEO_START(cop01)113 VIDEO_START( cop01 )
114 {
115 	bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_SPLIT,      8,8,64,32);
116 	fg_tilemap = tilemap_create(get_fg_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
117 
118 	if (!bg_tilemap || !fg_tilemap)
119 		return 1;
120 
121 	tilemap_set_transparent_pen(fg_tilemap,15);
122 
123 	/* priority doesn't exactly work this way, see above */
124 	tilemap_set_transmask(bg_tilemap,0,0xffff,0x0000); /* split type 0 is totally transparent in front half */
125 	tilemap_set_transmask(bg_tilemap,1,0x0fff,0xf000); /* split type 1 has pens 0-11 transparent in front half */
126 
127 	return 0;
128 }
129 
130 
131 
132 /***************************************************************************
133 
134   Memory handlers
135 
136 ***************************************************************************/
137 
WRITE_HANDLER(cop01_background_w)138 WRITE_HANDLER( cop01_background_w )
139 {
140 	if (cop01_bgvideoram[offset] != data)
141 	{
142 		cop01_bgvideoram[offset] = data;
143 		tilemap_mark_tile_dirty(bg_tilemap,offset & 0x7ff);
144 	}
145 }
146 
WRITE_HANDLER(cop01_foreground_w)147 WRITE_HANDLER( cop01_foreground_w )
148 {
149 	if (cop01_fgvideoram[offset] != data)
150 	{
151 		cop01_fgvideoram[offset] = data;
152 		tilemap_mark_tile_dirty(fg_tilemap,offset);
153 	}
154 }
155 
WRITE_HANDLER(cop01_vreg_w)156 WRITE_HANDLER( cop01_vreg_w )
157 {
158 	/*	0x40: --xx---- sprite bank, coin counters, flip screen
159 	 *	      -----x-- flip screen
160 	 *	      ------xx coin counters
161 	 *	0x41: xxxxxxxx xscroll
162 	 *	0x42: ---xx--- ? matches the bg tile color most of the time, but not
163 	 *                 during level transitions. Maybe sprite palette bank?
164 	 *                 (the four banks in the PROM are identical)
165 	 *	      ------x- unused (xscroll overflow)
166 	 *	      -------x msb xscroll
167 	 *	0x43: xxxxxxxx yscroll
168 	 */
169 	mightguy_vreg[offset] = data;
170 
171 	if (offset == 0)
172 	{
173 		coin_counter_w(0,data & 1);
174 		coin_counter_w(1,data & 2);
175 		flip_screen_set(data & 4);
176 	}
177 }
178 
179 
180 
181 /***************************************************************************
182 
183   Display refresh
184 
185 ***************************************************************************/
186 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)187 static void draw_sprites( struct mame_bitmap *bitmap, const struct rectangle *cliprect )
188 {
189 	int offs,code,attr,sx,sy,flipx,flipy,color;
190 
191 	for (offs = 0;offs < spriteram_size;offs += 4)
192 	{
193 		code = spriteram[offs+1];
194 		attr = spriteram[offs+2];
195 		/* xxxx----	color
196 		 * ----xx--	flipy,flipx
197 		 * -------x msbx
198 		 */
199 		color = attr>>4;
200 		flipx = attr & 0x04;
201 		flipy = attr & 0x08;
202 
203 		sx = (spriteram[offs+3] - 0x80) + 256 * (attr & 0x01);
204 		sy = 240 - spriteram[offs];
205 
206 		if (flip_screen)
207 		{
208 			sx = 240 - sx;
209 			sy = 240 - sy;
210 			flipx = !flipx;
211 			flipy = !flipy;
212 		}
213 
214 		if (code&0x80)
215 			code += (mightguy_vreg[0]&0x30)<<3;
216 
217 		drawgfx(bitmap,Machine->gfx[2],
218 			code,
219 			color,
220 			flipx,flipy,
221 			sx,sy,
222 			cliprect,TRANSPARENCY_PEN,0 );
223 	}
224 }
225 
226 
VIDEO_UPDATE(cop01)227 VIDEO_UPDATE( cop01 )
228 {
229 	tilemap_set_scrollx(bg_tilemap,0,mightguy_vreg[1] + 256 * (mightguy_vreg[2] & 1));
230 	tilemap_set_scrolly(bg_tilemap,0,mightguy_vreg[3]);
231 
232 	tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_BACK,0);
233 	draw_sprites(bitmap,cliprect);
234 	tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_FRONT,0);
235 	tilemap_draw(bitmap,cliprect,fg_tilemap,0,0 );
236 }
237