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 "fastfred.h"
11
12 extern UINT8 galaxian_stars_on;
13 extern void galaxian_init_stars(int colors_offset);
14 extern void galaxian_draw_stars(struct mame_bitmap *bitmap);
15
16 data8_t *fastfred_videoram;
17 data8_t *fastfred_spriteram;
18 size_t fastfred_spriteram_size;
19 data8_t *fastfred_attributesram;
20 data8_t *imago_fg_videoram;
21
22
23 static struct rectangle spritevisiblearea =
24 {
25 2*8, 32*8-1,
26 2*8, 30*8-1
27 };
28
29 static struct rectangle spritevisibleareaflipx =
30 {
31 0*8, 30*8-1,
32 2*8, 30*8-1
33 };
34
35 static data16_t charbank;
36 static data8_t colorbank;
37 static int flip_screen_x;
38 static int flip_screen_y;
39 int fastfred_hardware_type;
40 static const UINT8 *fastfred_color_prom;
41 static struct tilemap *bg_tilemap, *fg_tilemap, *web_tilemap;
42
43 /***************************************************************************
44
45 Convert the color PROMs into a more useable format.
46
47 bit 0 -- 1 kohm resistor -- RED/GREEN/BLUE
48 -- 470 ohm resistor -- RED/GREEN/BLUE
49 -- 220 ohm resistor -- RED/GREEN/BLUE
50 bit 3 -- 100 ohm resistor -- RED/GREEN/BLUE
51
52 ***************************************************************************/
53
set_color(pen_t pen,int i)54 static void set_color(pen_t pen, int i)
55 {
56 UINT8 r,g,b;
57 int bit0, bit1, bit2, bit3;
58
59 bit0 = (fastfred_color_prom[i] >> 0) & 0x01;
60 bit1 = (fastfred_color_prom[i] >> 1) & 0x01;
61 bit2 = (fastfred_color_prom[i] >> 2) & 0x01;
62 bit3 = (fastfred_color_prom[i] >> 3) & 0x01;
63 r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
64 bit0 = (fastfred_color_prom[i + 0x100] >> 0) & 0x01;
65 bit1 = (fastfred_color_prom[i + 0x100] >> 1) & 0x01;
66 bit2 = (fastfred_color_prom[i + 0x100] >> 2) & 0x01;
67 bit3 = (fastfred_color_prom[i + 0x100] >> 3) & 0x01;
68 g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
69 bit0 = (fastfred_color_prom[i + 0x200] >> 0) & 0x01;
70 bit1 = (fastfred_color_prom[i + 0x200] >> 1) & 0x01;
71 bit2 = (fastfred_color_prom[i + 0x200] >> 2) & 0x01;
72 bit3 = (fastfred_color_prom[i + 0x200] >> 3) & 0x01;
73 b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
74
75 palette_set_color(pen,r,g,b);
76 }
77
PALETTE_INIT(fastfred)78 PALETTE_INIT( fastfred )
79 {
80 pen_t i;
81 #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
82
83
84 fastfred_color_prom = color_prom; /* we'll need this later */
85
86 for (i = 0;i < 256;i++)
87 {
88 set_color(i, i);
89 }
90
91
92 /* characters and sprites use the same palette */
93 for (i = 0; i < 256; i++)
94 {
95 pen_t color;
96
97 if ((i & 0x07) == 0)
98 color = 0;
99 else
100 color = i;
101
102 COLOR(0,i) = COLOR(1,i) = color;
103 }
104 }
105
106
107 /***************************************************************************
108
109 Callbacks for the TileMap code
110
111 ***************************************************************************/
112
get_tile_info(int tile_index)113 static void get_tile_info(int tile_index)
114 {
115 data8_t x = tile_index & 0x1f;
116
117 data16_t code = charbank | fastfred_videoram[tile_index];
118 data8_t color = colorbank | (fastfred_attributesram[2 * x + 1] & 0x07);
119
120 SET_TILE_INFO(0, code, color, 0)
121 }
122
123
124
125 /*************************************
126 *
127 * Video system start
128 *
129 *************************************/
130
VIDEO_START(fastfred)131 VIDEO_START( fastfred )
132 {
133 bg_tilemap = tilemap_create(get_tile_info,tilemap_scan_rows,TILEMAP_OPAQUE,8,8,32,32);
134
135 if (!bg_tilemap)
136 return 1;
137
138 tilemap_set_scroll_cols(bg_tilemap, 32);
139
140 return 0;
141 }
142
143
144 /*************************************
145 *
146 * Memory handlers
147 *
148 *************************************/
149
WRITE_HANDLER(fastfred_videoram_w)150 WRITE_HANDLER( fastfred_videoram_w )
151 {
152 if (fastfred_videoram[offset] != data)
153 {
154 fastfred_videoram[offset] = data;
155
156 tilemap_mark_tile_dirty(bg_tilemap, offset);
157 }
158 }
159
160
WRITE_HANDLER(fastfred_attributes_w)161 WRITE_HANDLER( fastfred_attributes_w )
162 {
163 if (fastfred_attributesram[offset] != data)
164 {
165 if (offset & 0x01)
166 {
167 /* color change */
168 int i;
169
170 for (i = offset / 2; i < 0x0400; i += 32)
171 tilemap_mark_tile_dirty(bg_tilemap, i);
172 }
173 else
174 {
175 /* coloumn scroll */
176 tilemap_set_scrolly(bg_tilemap, offset / 2, data);
177 }
178
179 fastfred_attributesram[offset] = data;
180 }
181 }
182
183
WRITE_HANDLER(fastfred_charbank1_w)184 WRITE_HANDLER( fastfred_charbank1_w )
185 {
186 data16_t new_data = (charbank & 0x0200) | ((data & 0x01) << 8);
187
188 if (new_data != charbank)
189 {
190 tilemap_mark_all_tiles_dirty(bg_tilemap);
191
192 charbank = new_data;
193 }
194 }
195
WRITE_HANDLER(fastfred_charbank2_w)196 WRITE_HANDLER( fastfred_charbank2_w )
197 {
198 data16_t new_data = (charbank & 0x0100) | ((data & 0x01) << 9);
199
200 if (new_data != charbank)
201 {
202 tilemap_mark_all_tiles_dirty(bg_tilemap);
203
204 charbank = new_data;
205 }
206 }
207
208
WRITE_HANDLER(fastfred_colorbank1_w)209 WRITE_HANDLER( fastfred_colorbank1_w )
210 {
211 data8_t new_data = (colorbank & 0x10) | ((data & 0x01) << 3);
212
213 if (new_data != colorbank)
214 {
215 tilemap_mark_all_tiles_dirty(bg_tilemap);
216
217 colorbank = new_data;
218 }
219 }
220
WRITE_HANDLER(fastfred_colorbank2_w)221 WRITE_HANDLER( fastfred_colorbank2_w )
222 {
223 data8_t new_data = (colorbank & 0x08) | ((data & 0x01) << 4);
224
225 if (new_data != colorbank)
226 {
227 tilemap_mark_all_tiles_dirty(bg_tilemap);
228
229 colorbank = new_data;
230 }
231 }
232
233
WRITE_HANDLER(fastfred_background_color_w)234 WRITE_HANDLER( fastfred_background_color_w )
235 {
236 set_color(0, data);
237 }
238
239
WRITE_HANDLER(fastfred_flip_screen_x_w)240 WRITE_HANDLER( fastfred_flip_screen_x_w )
241 {
242 if (flip_screen_x != (data & 0x01))
243 {
244 flip_screen_x = data & 0x01;
245
246 tilemap_set_flip(bg_tilemap, (flip_screen_x ? TILEMAP_FLIPX : 0) | (flip_screen_y ? TILEMAP_FLIPY : 0));
247 }
248 }
249
WRITE_HANDLER(fastfred_flip_screen_y_w)250 WRITE_HANDLER( fastfred_flip_screen_y_w )
251 {
252 if (flip_screen_y != (data & 0x01))
253 {
254 flip_screen_y = data & 0x01;
255
256 tilemap_set_flip(bg_tilemap, (flip_screen_x ? TILEMAP_FLIPX : 0) | (flip_screen_y ? TILEMAP_FLIPY : 0));
257 }
258 }
259
260
261
262 /*************************************
263 *
264 * Video update
265 *
266 *************************************/
267
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)268 static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cliprect)
269 {
270 int offs;
271
272 for (offs = fastfred_spriteram_size - 4; offs >= 0; offs -= 4)
273 {
274 UINT8 code,sx,sy;
275 int flipx,flipy;
276
277 sx = fastfred_spriteram[offs + 3];
278 sy = 240 - fastfred_spriteram[offs];
279
280 if (fastfred_hardware_type == 3)
281 {
282 /* Imago*/
283 code = (fastfred_spriteram[offs + 1]) & 0x3f;
284
285 flipx = 0;
286 flipy = 0;
287 }
288 else if (fastfred_hardware_type == 2)
289 {
290 /* Boggy 84*/
291 code = fastfred_spriteram[offs + 1] & 0x7f;
292 flipx = 0;
293 flipy = fastfred_spriteram[offs + 1] & 0x80;
294 }
295 else if (fastfred_hardware_type == 1)
296 {
297 /* Fly-Boy/Fast Freddie/Red Robin*/
298 code = fastfred_spriteram[offs + 1] & 0x7f;
299 flipx = 0;
300 flipy = ~fastfred_spriteram[offs + 1] & 0x80;
301 }
302 else
303 {
304 /* Jump Coaster*/
305 code = (fastfred_spriteram[offs + 1] & 0x3f) | 0x40;
306 flipx = ~fastfred_spriteram[offs + 1] & 0x40;
307 flipy = fastfred_spriteram[offs + 1] & 0x80;
308 }
309
310
311 if (flip_screen_x)
312 {
313 sx = 240 - sx;
314 flipx = !flipx;
315 }
316 if (flip_screen_y)
317 {
318 sy = 240 - sy;
319 flipy = !flipy;
320 }
321
322 drawgfx(bitmap,Machine->gfx[1],
323 code,
324 colorbank | (fastfred_spriteram[offs + 2] & 0x07),
325 flipx,flipy,
326 sx,sy,
327 flip_screen_x ? &spritevisibleareaflipx : &spritevisiblearea,TRANSPARENCY_PEN,0);
328 }
329 }
330
331
VIDEO_UPDATE(fastfred)332 VIDEO_UPDATE( fastfred )
333 {
334 tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
335
336 draw_sprites(bitmap, cliprect);
337 }
338
339
imago_get_tile_info_bg(int tile_index)340 static void imago_get_tile_info_bg(int tile_index)
341 {
342 data8_t x = tile_index & 0x1f;
343
344 data16_t code = charbank * 0x100 + fastfred_videoram[tile_index];
345 data8_t color = colorbank | (fastfred_attributesram[2 * x + 1] & 0x07);
346
347 SET_TILE_INFO(0, code, color, 0)
348 }
349
imago_get_tile_info_fg(int tile_index)350 static void imago_get_tile_info_fg(int tile_index)
351 {
352 int code = imago_fg_videoram[tile_index];
353 SET_TILE_INFO(2, code, 2, 0)
354 }
355
imago_get_tile_info_web(int tile_index)356 static void imago_get_tile_info_web(int tile_index)
357 {
358 SET_TILE_INFO(3, tile_index & 0x1ff, 0, 0);
359 }
360
WRITE_HANDLER(imago_fg_videoram_w)361 WRITE_HANDLER( imago_fg_videoram_w )
362 {
363 if( imago_fg_videoram[offset] != data)
364 {
365 imago_fg_videoram[offset] = data;
366 tilemap_mark_tile_dirty(fg_tilemap, offset);
367 }
368 }
369
WRITE_HANDLER(imago_charbank_w)370 WRITE_HANDLER( imago_charbank_w )
371 {
372 if( charbank != data )
373 {
374 charbank = data;
375 tilemap_mark_all_tiles_dirty(bg_tilemap);
376 }
377 }
378
VIDEO_START(imago)379 VIDEO_START( imago )
380 {
381 web_tilemap = tilemap_create(imago_get_tile_info_web,tilemap_scan_rows,TILEMAP_OPAQUE,8,8,32,32);
382 bg_tilemap = tilemap_create(imago_get_tile_info_bg, tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
383 fg_tilemap = tilemap_create(imago_get_tile_info_fg, tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
384
385 if( !web_tilemap || !bg_tilemap || !fg_tilemap )
386 return 1;
387
388 tilemap_set_transparent_pen(bg_tilemap, 0);
389 tilemap_set_transparent_pen(fg_tilemap, 0);
390
391 /* the game has a galaxian starfield */
392 galaxian_init_stars(256);
393 galaxian_stars_on = 1;
394
395 /* web colors */
396 palette_set_color(256+64+0, 0x50, 0x00, 0x00);
397 palette_set_color(256+64+1, 0x00, 0x00, 0x00);
398
399 return 0;
400 }
401
VIDEO_UPDATE(imago)402 VIDEO_UPDATE( imago )
403 {
404 tilemap_draw(bitmap,cliprect,web_tilemap,0,0);
405
406 galaxian_draw_stars(bitmap);
407
408 tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
409
410 draw_sprites(bitmap, cliprect);
411
412 tilemap_draw(bitmap,cliprect,fg_tilemap,0,0);
413 }
414