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