1 #include "driver.h"
2 #include "vidhrdw/generic.h"
3 #include "cpu/z80/z80.h"
4
5 static int flipscreen, sprite_flip_adjust;
6 static struct tilemap *fg_tilemap, *bg_tilemap, *tx_tilemap;
7 static unsigned char bg_color, fg_color, old_bg_color, old_fg_color;
8
9 /***************************************************************************
10 **
11 ** Palette Handling:
12 **
13 ** Each color entry is encoded by 12 bits in color proms
14 **
15 ** There are sixteen 8-color sprite palettes
16 ** sprite palette is selected by a nibble of spriteram
17 **
18 ** There are eight 16-color text layer character palettes
19 ** character palette is determined by character_number
20 **
21 ** Background and Foreground tilemap layers each have eight 16-color
22 ** palettes. A palette bank select register is associated with the whole
23 ** layer.
24 **
25 ***************************************************************************/
26
WRITE_HANDLER(marvins_palette_bank_w)27 WRITE_HANDLER( marvins_palette_bank_w )
28 {
29 bg_color = data>>4;
30 fg_color = data&0xf;
31 }
32
stuff_palette(int source_index,int dest_index,int num_colors)33 static void stuff_palette( int source_index, int dest_index, int num_colors )
34 {
35 unsigned char *color_prom = memory_region(REGION_PROMS) + source_index;
36 int i;
37 for( i=0; i<num_colors; i++ )
38 {
39 int bit0=0,bit1,bit2,bit3;
40 int red, green, blue;
41
42 bit0 = (color_prom[0x800] >> 2) & 0x01; // ?
43 bit1 = (color_prom[0x000] >> 1) & 0x01;
44 bit2 = (color_prom[0x000] >> 2) & 0x01;
45 bit3 = (color_prom[0x000] >> 3) & 0x01;
46 red = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
47
48 bit0 = (color_prom[0x800] >> 1) & 0x01; // ?
49 bit1 = (color_prom[0x400] >> 2) & 0x01;
50 bit2 = (color_prom[0x400] >> 3) & 0x01;
51 bit3 = (color_prom[0x000] >> 0) & 0x01;
52 green = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
53
54 bit0 = (color_prom[0x800] >> 0) & 0x01; // ?
55 bit1 = (color_prom[0x800] >> 3) & 0x01; // ?
56 bit2 = (color_prom[0x400] >> 0) & 0x01;
57 bit3 = (color_prom[0x400] >> 1) & 0x01;
58 blue = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
59
60 palette_change_color( dest_index++, red, green, blue );
61 color_prom++;
62 }
63 }
64
update_palette(int type)65 static void update_palette( int type )
66 {
67 if( bg_color!=old_bg_color )
68 {
69 stuff_palette( 256+16*(bg_color&0x7), (0x11-type)*16, 16 );
70 old_bg_color = bg_color;
71 }
72
73 if( fg_color!=old_fg_color )
74 {
75 stuff_palette( 128+16*(fg_color&0x7), (0x10+type)*16, 16 );
76 old_fg_color = fg_color;
77 }
78 }
79
80 /***************************************************************************
81 **
82 ** Memory Handlers
83 **
84 ***************************************************************************/
85
WRITE_HANDLER(marvins_spriteram_w)86 WRITE_HANDLER( marvins_spriteram_w )
87 {
88 spriteram[offset] = data;
89 }
READ_HANDLER(marvins_spriteram_r)90 READ_HANDLER( marvins_spriteram_r )
91 {
92 return spriteram[offset];
93 }
94
READ_HANDLER(marvins_foreground_ram_r)95 READ_HANDLER( marvins_foreground_ram_r )
96 {
97 return videoram[offset+0x1000];
98 }
WRITE_HANDLER(marvins_foreground_ram_w)99 WRITE_HANDLER( marvins_foreground_ram_w )
100 {
101 if( offset<0x800 )
102 {
103 if( videoram[offset+0x1000]==data ) return;
104 tilemap_mark_tile_dirty(fg_tilemap,offset);
105 }
106 videoram[offset+0x1000] = data;
107 }
108
READ_HANDLER(marvins_background_ram_r)109 READ_HANDLER( marvins_background_ram_r )
110 {
111 return videoram[offset];
112 }
WRITE_HANDLER(marvins_background_ram_w)113 WRITE_HANDLER( marvins_background_ram_w )
114 {
115 if( offset<0x800 )
116 {
117 if( videoram[offset]==data ) return;
118 tilemap_mark_tile_dirty(bg_tilemap,offset);
119 }
120 videoram[offset] = data;
121 }
122
READ_HANDLER(marvins_text_ram_r)123 READ_HANDLER( marvins_text_ram_r )
124 {
125 return videoram[offset+0x2000];
126 }
WRITE_HANDLER(marvins_text_ram_w)127 WRITE_HANDLER( marvins_text_ram_w )
128 {
129 if( offset<0x400 )
130 {
131 if( videoram[offset+0x2000]==data ) return;
132 tilemap_mark_tile_dirty(tx_tilemap,offset);
133 }
134 videoram[offset+0x2000] = data;
135 }
136
137 /***************************************************************************
138 **
139 ** Callbacks for Tilemap Manager
140 **
141 ***************************************************************************/
142
get_bg_tilemap_info(int tile_index)143 static void get_bg_tilemap_info(int tile_index)
144 {
145 SET_TILE_INFO(2,videoram[tile_index],0);
146 }
147
get_fg_tilemap_info(int tile_index)148 static void get_fg_tilemap_info(int tile_index)
149 {
150 SET_TILE_INFO(1,videoram[tile_index+0x1000],0);
151 }
152
get_tx_tilemap_info(int tile_index)153 static void get_tx_tilemap_info(int tile_index)
154 {
155 int tile_number = videoram[tile_index+0x2000];
156 SET_TILE_INFO(0,tile_number,(tile_number>>5));
157 }
158
159 /***************************************************************************
160 **
161 ** Video Initialization
162 **
163 ***************************************************************************/
164
marvins_vh_start(void)165 int marvins_vh_start( void )
166 {
167 flipscreen = -1; old_bg_color = old_fg_color = -1;
168
169 stuff_palette( 0, 0, 16*8 ); /* load sprite colors */
170 stuff_palette( 16*8*3, 16*8, 16*8 ); /* load text colors */
171
172 fg_tilemap = tilemap_create(get_fg_tilemap_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,64,32);
173 bg_tilemap = tilemap_create(get_bg_tilemap_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,64,32);
174 tx_tilemap = tilemap_create(get_tx_tilemap_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,32,32);
175
176 if (!fg_tilemap || !bg_tilemap || !tx_tilemap)
177 return 1;
178
179 {
180 struct rectangle clip = Machine->visible_area;
181 clip.max_x-=16;
182 clip.min_x+=16;
183 tilemap_set_clip( fg_tilemap, &clip );
184 tilemap_set_clip( bg_tilemap, &clip );
185 tilemap_set_clip( tx_tilemap, &clip );
186
187 fg_tilemap->transparent_pen = 0xf;
188 bg_tilemap->transparent_pen = 0xf;
189 tx_tilemap->transparent_pen = 0xf;
190
191 if( strcmp(Machine->gamedrv->name,"marvins")==0 )
192 {
193 tilemap_set_scrolldx( bg_tilemap, 271, 287 );
194 tilemap_set_scrolldx( fg_tilemap, 15, 13+18 );
195 sprite_flip_adjust = 256+182+1;
196 }
197 else
198 {
199 tilemap_set_scrolldx( bg_tilemap, -16, -10 );
200 tilemap_set_scrolldx( fg_tilemap, 16, 22 );
201 sprite_flip_adjust = 256+182;
202 }
203
204 tilemap_set_scrolldx( tx_tilemap, 16, 16 );
205 tilemap_set_scrolldy( bg_tilemap, 0, -40 );
206 tilemap_set_scrolldy( fg_tilemap, 0, -40 );
207 tilemap_set_scrolldy( tx_tilemap, 0, 0 );
208
209 return 0;
210 }
211 }
212
213 /***************************************************************************
214 **
215 ** Screen Refresh
216 **
217 ***************************************************************************/
218
draw_status(struct osd_bitmap * bitmap)219 static void draw_status( struct osd_bitmap *bitmap )
220 {
221 const unsigned char *base = videoram+0x2400;
222 struct rectangle clip = Machine->visible_area;
223 const struct GfxElement *gfx = Machine->gfx[0];
224 int row;
225 for( row=0; row<4; row++ )
226 {
227 int sy,sx = (row&1)*8;
228 const unsigned char *source = base + (row&1)*32;
229 if( row>1 )
230 {
231 sx+=256+16;
232 }
233 else
234 {
235 source+=30*32;
236 }
237
238 for( sy=0; sy<256; sy+=8 )
239 {
240 int tile_number = *source++;
241 drawgfx( bitmap, gfx,
242 tile_number, tile_number>>5,
243 0,0, /* no flip */
244 sx,sy,
245 &clip,
246 TRANSPARENCY_NONE, 0xf );
247 }
248 }
249 }
250
draw_sprites(struct osd_bitmap * bitmap,int scrollx,int scrolly,int priority,unsigned char sprite_partition)251 static void draw_sprites( struct osd_bitmap *bitmap, int scrollx, int scrolly,
252 int priority, unsigned char sprite_partition )
253 {
254 const struct GfxElement *gfx = Machine->gfx[3];
255 struct rectangle clip = Machine->visible_area;
256 const unsigned char *source, *finish;
257
258 if( sprite_partition>0x64 ) sprite_partition = 0x64;
259
260 if( priority )
261 {
262 source = spriteram + sprite_partition;
263 finish = spriteram + 0x64;
264 }
265 else
266 {
267 source = spriteram;
268 finish = spriteram + sprite_partition;
269 }
270
271 while( source<finish )
272 {
273 int attributes = source[3]; /* Y?F? CCCC */
274 int tile_number = source[1];
275 int sy = (-16+source[0] - scrolly)&0xff;
276 int sx = source[2] - scrollx + ((attributes&0x80)?256:0);
277 int color = attributes&0xf;
278 int flipy = (attributes&0x20);
279 int flipx = 0;
280
281 if( flipscreen )
282 {
283 if( flipy )
284 {
285 flipx = 1; flipy = 0;
286 }
287 else
288 {
289 flipx = flipy = 1;
290 }
291 sx = sprite_flip_adjust-sx;
292 sy = 246-sy;
293 }
294
295 if( sy>240 ) sy -= 256;
296
297 drawgfx( bitmap,gfx,
298 tile_number,
299 color,
300 flipx, flipy,
301 (256-sx)&0x1ff,sy,
302 &clip,TRANSPARENCY_PEN,7);
303
304 source+=4;
305 }
306 }
307
marvins_vh_screenrefresh(struct osd_bitmap * bitmap,int fullrefresh)308 void marvins_vh_screenrefresh( struct osd_bitmap *bitmap, int fullrefresh )
309 {
310 unsigned char *mem = memory_region(REGION_CPU1);
311
312 unsigned char sprite_partition = mem[0xfe00];
313
314 int attributes = mem[0x8600]; /* 0x20: normal, 0xa0: video flipped */
315 int scroll_attributes = mem[0xff00];
316 int sprite_scrolly = mem[0xf800];
317 int sprite_scrollx = mem[0xf900];
318
319 int bg_scrolly = mem[0xfa00];
320 int bg_scrollx = mem[0xfb00];
321 int fg_scrolly = mem[0xfc00];
322 int fg_scrollx = mem[0xfd00];
323
324 if( (scroll_attributes & 4)==0 ) bg_scrollx += 256;
325 if( scroll_attributes & 1 ) sprite_scrollx += 256;
326 if( scroll_attributes & 2 ) fg_scrollx += 256;
327
328 /* palette bank for background/foreground is set by a memory-write handler */
329 update_palette(0);
330
331 if( flipscreen != (attributes&0x80) )
332 {
333 flipscreen = attributes&0x80;
334 tilemap_set_flip( ALL_TILEMAPS, flipscreen?TILEMAP_FLIPY|TILEMAP_FLIPX:0);
335 }
336
337 tilemap_set_scrollx( bg_tilemap, 0, bg_scrollx );
338 tilemap_set_scrolly( bg_tilemap, 0, bg_scrolly );
339 tilemap_set_scrollx( fg_tilemap, 0, fg_scrollx );
340 tilemap_set_scrolly( fg_tilemap, 0, fg_scrolly );
341 tilemap_set_scrollx( tx_tilemap, 0, 0 );
342 tilemap_set_scrolly( tx_tilemap, 0, 0 );
343
344 tilemap_update( ALL_TILEMAPS );
345 if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
346 tilemap_render( ALL_TILEMAPS );
347
348 tilemap_draw( bitmap,fg_tilemap,TILEMAP_IGNORE_TRANSPARENCY );
349 draw_sprites( bitmap, sprite_scrollx+29+1, sprite_scrolly, 0, sprite_partition );
350 tilemap_draw( bitmap,bg_tilemap,0 );
351 draw_sprites( bitmap, sprite_scrollx+29+1, sprite_scrolly, 1, sprite_partition );
352 tilemap_draw( bitmap,tx_tilemap,0 );
353 draw_status( bitmap );
354 }
355
madcrash_vh_screenrefresh(struct osd_bitmap * bitmap,int fullrefresh)356 void madcrash_vh_screenrefresh( struct osd_bitmap *bitmap, int fullrefresh )
357 {
358 extern int madcrash_vreg;
359 unsigned char *mem = memory_region(REGION_CPU1)+madcrash_vreg;
360
361 int attributes = mem[0x8600]; /* 0x20: normal, 0xa0: video flipped */
362 int bg_scrolly = mem[0xf800];
363 int bg_scrollx = mem[0xf900];
364 int scroll_attributes = mem[0xfb00];
365 int sprite_scrolly = mem[0xfc00];
366 int sprite_scrollx = mem[0xfd00];
367 int fg_scrolly = mem[0xfe00];
368 int fg_scrollx = mem[0xff00];
369 if( (scroll_attributes & 4)==0 ) bg_scrollx += 256;
370 if( scroll_attributes & 1 ) sprite_scrollx += 256;
371 if( scroll_attributes & 2 ) fg_scrollx += 256;
372
373 marvins_palette_bank_w( 0, mem[0xc800] );
374 update_palette(1);
375
376 if( flipscreen != (attributes&0x80) )
377 {
378 flipscreen = attributes&0x80;
379 tilemap_set_flip( ALL_TILEMAPS, flipscreen?TILEMAP_FLIPY|TILEMAP_FLIPX:0);
380 }
381
382 tilemap_set_scrollx( bg_tilemap, 0, bg_scrollx );
383 tilemap_set_scrolly( bg_tilemap, 0, bg_scrolly );
384 tilemap_set_scrollx( fg_tilemap, 0, fg_scrollx );
385 tilemap_set_scrolly( fg_tilemap, 0, fg_scrolly );
386 tilemap_set_scrollx( tx_tilemap, 0, 0 );
387 tilemap_set_scrolly( tx_tilemap, 0, 0 );
388
389 tilemap_update( ALL_TILEMAPS );
390 if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
391 tilemap_render( ALL_TILEMAPS );
392
393 tilemap_draw( bitmap,bg_tilemap,TILEMAP_IGNORE_TRANSPARENCY );
394 tilemap_draw( bitmap,fg_tilemap,0 );
395 draw_sprites( bitmap, sprite_scrollx+29, sprite_scrolly+1, 1, 0 );
396
397 tilemap_draw( bitmap,tx_tilemap,0 );
398 draw_status( bitmap );
399 }
400