1 /***************************************************************************
2 
3 	Atari Gauntlet hardware
4 
5 ****************************************************************************/
6 
7 #include "driver.h"
8 #include "machine/atarigen.h"
9 #include "gauntlet.h"
10 
11 
12 
13 /*************************************
14  *
15  *	Globals we own
16  *
17  *************************************/
18 
19 UINT8 vindctr2_screen_refresh;
20 
21 
22 
23 /*************************************
24  *
25  *	Statics
26  *
27  *************************************/
28 
29 static UINT8 playfield_tile_bank;
30 static UINT8 playfield_color_bank;
31 
32 
33 
34 /*************************************
35  *
36  *	Tilemap callbacks
37  *
38  *************************************/
39 
get_alpha_tile_info(int tile_index)40 static void get_alpha_tile_info(int tile_index)
41 {
42 	UINT16 data = atarigen_alpha[tile_index];
43 	int code = data & 0x3ff;
44 	int color = ((data >> 10) & 0x0f) | ((data >> 9) & 0x20);
45 	int opaque = data & 0x8000;
46 	SET_TILE_INFO(1, code, color, opaque ? TILE_IGNORE_TRANSPARENCY : 0);
47 }
48 
49 
get_playfield_tile_info(int tile_index)50 static void get_playfield_tile_info(int tile_index)
51 {
52 	UINT16 data = atarigen_playfield[tile_index];
53 	int code = ((playfield_tile_bank * 0x1000) + (data & 0xfff)) ^ 0x800;
54 	int color = 0x10 + (playfield_color_bank * 8) + ((data >> 12) & 7);
55 	SET_TILE_INFO(0, code, color, (data >> 15) & 1);
56 }
57 
58 
59 
60 /*************************************
61  *
62  *	Video system start
63  *
64  *************************************/
65 
VIDEO_START(gauntlet)66 VIDEO_START( gauntlet )
67 {
68 	static const struct atarimo_desc modesc =
69 	{
70 		0,					/* index to which gfx system */
71 		1,					/* number of motion object banks */
72 		1,					/* are the entries linked? */
73 		1,					/* are the entries split? */
74 		0,					/* render in reverse order? */
75 		0,					/* render in swapped X/Y order? */
76 		0,					/* does the neighbor bit affect the next object? */
77 		8,					/* pixels per SLIP entry (0 for no-slip) */
78 		1,					/* pixel offset for SLIPs */
79 		0,					/* maximum number of links to visit/scanline (0=all) */
80 
81 		0x100,				/* base palette entry */
82 		0x100,				/* maximum number of colors */
83 		0,					/* transparent pen index */
84 
85 		{{ 0,0,0,0x03ff }},	/* mask for the link */
86 		{{ 0 }},			/* mask for the graphics bank */
87 		{{ 0x7fff,0,0,0 }},	/* mask for the code index */
88 		{{ 0 }},			/* mask for the upper code index */
89 		{{ 0,0x000f,0,0 }},	/* mask for the color */
90 		{{ 0,0xff80,0,0 }},	/* mask for the X position */
91 		{{ 0,0,0xff80,0 }},	/* mask for the Y position */
92 		{{ 0,0,0x0038,0 }},	/* mask for the width, in tiles*/
93 		{{ 0,0,0x0007,0 }},	/* mask for the height, in tiles */
94 		{{ 0,0,0x0040,0 }},	/* mask for the horizontal flip */
95 		{{ 0 }},			/* mask for the vertical flip */
96 		{{ 0 }},			/* mask for the priority */
97 		{{ 0 }},			/* mask for the neighbor */
98 		{{ 0 }},			/* mask for absolute coordinates */
99 
100 		{{ 0 }},			/* mask for the special value */
101 		0,					/* resulting value to indicate "special" */
102 		0					/* callback routine for special entries */
103 	};
104 
105 	UINT16 *codelookup;
106 	int i, size;
107 
108 	/* initialize the playfield */
109 	atarigen_playfield_tilemap = tilemap_create(get_playfield_tile_info, tilemap_scan_cols, TILEMAP_OPAQUE, 8,8, 64,64);
110 	if (!atarigen_playfield_tilemap)
111 		return 1;
112 
113 	/* initialize the motion objects */
114 	if (!atarimo_init(0, &modesc))
115 		return 1;
116 
117 	/* initialize the alphanumerics */
118 	atarigen_alpha_tilemap = tilemap_create(get_alpha_tile_info, tilemap_scan_rows, TILEMAP_TRANSPARENT, 8,8, 64,32);
119 	if (!atarigen_alpha_tilemap)
120 		return 1;
121 	tilemap_set_transparent_pen(atarigen_alpha_tilemap, 0);
122 
123 	/* modify the motion object code lookup table to account for the code XOR */
124 	codelookup = atarimo_get_code_lookup(0, &size);
125 	for (i = 0; i < size; i++)
126 		codelookup[i] ^= 0x800;
127 
128 	/* set up the base color for the playfield */
129 	playfield_color_bank = vindctr2_screen_refresh ? 0 : 1;
130 	return 0;
131 }
132 
133 
134 
135 /*************************************
136  *
137  *	Horizontal scroll register
138  *
139  *************************************/
140 
WRITE16_HANDLER(gauntlet_xscroll_w)141 WRITE16_HANDLER( gauntlet_xscroll_w )
142 {
143 	UINT16 oldxscroll = *atarigen_xscroll;
144 	COMBINE_DATA(atarigen_xscroll);
145 
146 	/* if something changed, force a partial update */
147 	if (*atarigen_xscroll != oldxscroll)
148 	{
149 		force_partial_update(cpu_getscanline());
150 
151 		/* adjust the scrolls */
152 		tilemap_set_scrollx(atarigen_playfield_tilemap, 0, *atarigen_xscroll);
153 		atarimo_set_xscroll(0, *atarigen_xscroll & 0x1ff);
154 	}
155 }
156 
157 
158 
159 /*************************************
160  *
161  *	Vertical scroll/PF bank register
162  *
163  *************************************/
164 
WRITE16_HANDLER(gauntlet_yscroll_w)165 WRITE16_HANDLER( gauntlet_yscroll_w )
166 {
167 	UINT16 oldyscroll = *atarigen_yscroll;
168 	COMBINE_DATA(atarigen_yscroll);
169 
170 	/* if something changed, force a partial update */
171 	if (*atarigen_yscroll != oldyscroll)
172 	{
173 		force_partial_update(cpu_getscanline());
174 
175 		/* if the bank changed, mark all tiles dirty */
176 		if (playfield_tile_bank != (*atarigen_yscroll & 3))
177 		{
178 			playfield_tile_bank = *atarigen_yscroll & 3;
179 			tilemap_mark_all_tiles_dirty(atarigen_playfield_tilemap);
180 		}
181 
182 		/* adjust the scrolls */
183 		tilemap_set_scrolly(atarigen_playfield_tilemap, 0, *atarigen_yscroll >> 7);
184 		atarimo_set_yscroll(0, (*atarigen_yscroll >> 7) & 0x1ff);
185 	}
186 }
187 
188 
189 
190 /*************************************
191  *
192  *	Main refresh
193  *
194  *************************************/
195 
VIDEO_UPDATE(gauntlet)196 VIDEO_UPDATE( gauntlet )
197 {
198 	struct atarimo_rect_list rectlist;
199 	struct mame_bitmap *mobitmap;
200 	int x, y, r;
201 
202 	/* draw the playfield */
203 	tilemap_draw(bitmap, cliprect, atarigen_playfield_tilemap, 0, 0);
204 
205 	/* draw and merge the MO */
206 	mobitmap = atarimo_render(0, cliprect, &rectlist);
207 	for (r = 0; r < rectlist.numrects; r++, rectlist.rect++)
208 		for (y = rectlist.rect->min_y; y <= rectlist.rect->max_y; y++)
209 		{
210 			UINT16 *mo = (UINT16 *)mobitmap->base + mobitmap->rowpixels * y;
211 			UINT16 *pf = (UINT16 *)bitmap->base + bitmap->rowpixels * y;
212 			for (x = rectlist.rect->min_x; x <= rectlist.rect->max_x; x++)
213 				if (mo[x])
214 				{
215 					/* verified via schematics:
216 
217 						MO pen 1 clears PF color bit 0x80
218 					*/
219 					if ((mo[x] & 0x0f) == 1)
220 					{
221 						/* Vindicators Part II has extra logic here for the bases */
222 						if (!vindctr2_screen_refresh || (mo[x] & 0xf0) != 0)
223 							pf[x] ^= 0x80;
224 					}
225 					else
226 						pf[x] = mo[x];
227 
228 					/* erase behind ourselves */
229 					mo[x] = 0;
230 				}
231 		}
232 
233 	/* add the alpha on top */
234 	tilemap_draw(bitmap, cliprect, atarigen_alpha_tilemap, 0, 0);
235 }
236