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