1 /***************************************************************************
2 
3   Video Hardware for Armed Formation and Terra Force and Kodure Ookami
4 
5 ***************************************************************************/
6 
7 #include "driver.h"
8 #include "vidhrdw/generic.h"
9 
10 static int scroll_type;
11 
12 UINT16 armedf_vreg;
13 
14 unsigned char *armedf_bg_videoram;
15 UINT16 armedf_bg_scrollx;
16 UINT16 armedf_bg_scrolly;
17 
18 unsigned char *armedf_fg_videoram;
19 UINT16 armedf_fg_scrollx;
20 UINT16 armedf_fg_scrolly;
21 
22 UINT16 terraf_scroll_msb;
23 
24 static struct tilemap *background, *foreground, *text_layer;
25 
26 /******************************************************************/
27 
armedf_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)28 static UINT32 armedf_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
29 {
30 	/* logical (col,row) -> memory offset */
31 	return 32*col+row + 0x80;
32 }
33 
get_tx_tile_info(int tile_index)34 static void get_tx_tile_info(int tile_index)
35 {
36 	UINT16 *source = (UINT16 *)videoram;
37 	unsigned char attributes = source[tile_index+0x800]&0xff;
38 	int tile_number = (source[tile_index]&0xff) + 256*(attributes&3);
39 	int color = attributes>>4;
40 	SET_TILE_INFO( 0, tile_number, color );
41 }
42 
WRITE_HANDLER(armedf_text_videoram_w)43 WRITE_HANDLER( armedf_text_videoram_w )
44 {
45 	int oldword = READ_WORD(&videoram[offset]);
46 	int newword = COMBINE_WORD(oldword,data);
47 	if( oldword != newword )
48 	{
49 		WRITE_WORD(&videoram[offset],newword);
50 		tilemap_mark_tile_dirty(text_layer,(offset/2) & 0x7ff);
51 	}
52 }
53 
READ_HANDLER(armedf_text_videoram_r)54 READ_HANDLER( armedf_text_videoram_r )
55 {
56 	return READ_WORD (&videoram[offset]);
57 }
58 
READ_HANDLER(terraf_text_videoram_r)59 READ_HANDLER( terraf_text_videoram_r )
60 {
61 	return READ_WORD( &videoram[offset] );
62 }
63 
WRITE_HANDLER(terraf_text_videoram_w)64 WRITE_HANDLER( terraf_text_videoram_w )
65 {
66 	int oldword = READ_WORD(&videoram[offset]);
67 	int newword = COMBINE_WORD(oldword,data);
68 	if( oldword != newword )
69 	{
70 		WRITE_WORD(&videoram[offset],newword);
71 		offset = offset/2;
72 		tilemap_mark_tile_dirty(text_layer,offset & 0xbff);
73 	}
74 }
75 
terraf_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)76 static UINT32 terraf_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
77 {
78 	/* logical (col,row) -> memory offset */
79 	int tile_index = 32*(31-row);
80 	if( col<3 )
81 	{
82 		tile_index += 0x800+col+29;
83 	}
84 	else if( col<35 )
85 	{
86 		tile_index += (col-3);
87 	}
88 	else
89 	{
90 		tile_index += 0x800+col-35;
91 	}
92 	return tile_index;
93 }
94 
terraf_get_tx_tile_info(int tile_index)95 static void terraf_get_tx_tile_info(int tile_index)
96 {
97 	UINT16 *source = (UINT16 *)videoram;
98 	unsigned char attributes = source[tile_index+0x400]&0xff;
99 	int tile_number = source[tile_index]&0xff;
100 
101 	SET_TILE_INFO(0,tile_number + 256 * (attributes & 0x3),attributes >> 4);
102 }
103 
104 /******************************************************************/
105 
get_fg_tile_info(int tile_index)106 static void get_fg_tile_info( int tile_index )
107 {
108 	UINT16 data = ((UINT16 *)armedf_fg_videoram)[tile_index];
109 	SET_TILE_INFO( 1, data&0x7ff, data>>11 );
110 }
111 
WRITE_HANDLER(armedf_fg_videoram_w)112 WRITE_HANDLER( armedf_fg_videoram_w )
113 {
114 	int oldword = READ_WORD(&armedf_fg_videoram[offset]);
115 	int newword = COMBINE_WORD(oldword,data);
116 	if( oldword != newword )
117 	{
118 		WRITE_WORD(&armedf_fg_videoram[offset],newword);
119 		tilemap_mark_tile_dirty( foreground, offset/2 );
120 	}
121 }
122 
READ_HANDLER(armedf_fg_videoram_r)123 READ_HANDLER( armedf_fg_videoram_r )
124 {
125 	return READ_WORD (&armedf_fg_videoram[offset]);
126 }
127 
128 /******************************************************************/
129 
get_bg_tile_info(int tile_index)130 static void get_bg_tile_info( int tile_index )
131 {
132 	UINT16 data = ((UINT16 *)armedf_bg_videoram)[tile_index];
133 	SET_TILE_INFO( 2, data&0x3ff, data>>11 );
134 }
135 
WRITE_HANDLER(armedf_bg_videoram_w)136 WRITE_HANDLER( armedf_bg_videoram_w )
137 {
138 	int oldword = READ_WORD(&armedf_bg_videoram[offset]);
139 	int newword = COMBINE_WORD(oldword,data);
140 	if( oldword != newword )
141 	{
142 		WRITE_WORD(&armedf_bg_videoram[offset],newword);
143 		tilemap_mark_tile_dirty( background, offset/2 );
144 	}
145 }
146 
READ_HANDLER(armedf_bg_videoram_r)147 READ_HANDLER( armedf_bg_videoram_r )
148 {
149 	return READ_WORD( &armedf_bg_videoram[offset] );
150 }
151 
152 /******************************************************************/
153 
terraf_vh_start(void)154 int terraf_vh_start(void)
155 {
156 	scroll_type = 0;
157 
158 	text_layer = tilemap_create(terraf_get_tx_tile_info,terraf_scan,TILEMAP_TRANSPARENT,8,8,38,32);
159 	background = tilemap_create(get_bg_tile_info,tilemap_scan_cols,TILEMAP_OPAQUE,16,16,64,32);
160 	foreground = tilemap_create(get_fg_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,16,16,64,32);
161 
162 	if (!background || !foreground || !text_layer)
163 		return 1;
164 
165 	foreground->transparent_pen = 0xf;
166 	text_layer->transparent_pen = 0xf;
167 
168 	return 0;
169 }
170 
armedf_vh_start(void)171 int armedf_vh_start(void)
172 {
173 	scroll_type = 1;
174 
175 	text_layer = tilemap_create(get_tx_tile_info,armedf_scan,TILEMAP_TRANSPARENT,8,8,38,32);
176 	background = tilemap_create(get_bg_tile_info,tilemap_scan_cols,TILEMAP_OPAQUE,16,16,64,32);
177 	foreground = tilemap_create(get_fg_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,16,16,64,32);
178 
179 	if (!background || !foreground || !text_layer)
180 		return 1;
181 
182 	foreground->transparent_pen = 0xf;
183 	text_layer->transparent_pen = 0xf;
184 
185 	return 0;
186 }
187 
kodure_vh_start(void)188 int kodure_vh_start(void)
189 {
190 	scroll_type = 2;
191 
192 	text_layer = tilemap_create(terraf_get_tx_tile_info,terraf_scan,TILEMAP_TRANSPARENT,8,8,38,32);
193 	background = tilemap_create(get_bg_tile_info,tilemap_scan_cols,TILEMAP_OPAQUE,16,16,64,32);
194 	foreground = tilemap_create(get_fg_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,16,16,64,32);
195 
196 	if (!background || !foreground || !text_layer)
197 		return 1;
198 
199 	foreground->transparent_pen = 0xf;
200 	text_layer->transparent_pen = 0xf;
201 
202 	return 0;
203 }
204 
armedf_vh_stop(void)205 void armedf_vh_stop(void)
206 {
207 }
208 
draw_sprites(struct osd_bitmap * bitmap,int priority)209 static void draw_sprites( struct osd_bitmap *bitmap, int priority )
210 {
211 	const struct rectangle *clip = &Machine->visible_area;
212 	const struct GfxElement *gfx = Machine->gfx[3];
213 
214 	UINT16 *source = (UINT16 *)spriteram;
215 	UINT16 *finish = source+512;
216 
217 	while( source<finish )
218 	{
219 		int sy = 128+240-(source[0]&0x1ff);
220 		int tile_number = source[1]; /* ??YX?TTTTTTTTTTT */
221 
222 		int color = (source[2]>>8)&0x1f;
223 		int sx = source[3] - 0x60;
224 
225 		if( ((source[0]&0x2000)?0:1) == priority )
226 		{
227 			drawgfx(bitmap,gfx,
228 				tile_number,
229 				color,
230  				tile_number&0x2000,tile_number&0x1000, /* flip */
231 				sx,sy,
232 				clip,TRANSPARENCY_PEN,0xf);
233 		}
234 
235 		source+=4;
236 	}
237 }
238 
mark_sprite_colors(void)239 static void mark_sprite_colors( void )
240 {
241 	UINT16 *source = (UINT16 *)spriteram;
242 	UINT16 *finish = source+512;
243 	int i;
244 	char flag[32];
245 
246 	for( i=0; i<32; i++ ) flag[i] = 0;
247 
248 	while( source<finish )
249 	{
250 		int color = (source[2]>>8)&0x1f;
251 		flag[color] = 1;
252 		source+=4;
253 	}
254 
255 	{
256 		unsigned char *pen_ptr = &palette_used_colors[Machine->drv->gfxdecodeinfo[3].color_codes_start];
257 		int pen;
258 		for( i = 0; i<32; i++ )
259 		{
260 			if( flag[i] )
261 			{
262 				for( pen = 0; pen<0xf; pen++ ) pen_ptr[pen] = PALETTE_COLOR_USED;
263 			}
264 			pen_ptr += 16;
265 		}
266 	}
267 }
268 
armedf_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)269 void armedf_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
270 {
271 	int sprite_enable = armedf_vreg & 0x200;
272 
273 	tilemap_set_enable( background, armedf_vreg&0x800 );
274 	tilemap_set_enable( foreground, armedf_vreg&0x400 );
275 	tilemap_set_enable( text_layer, armedf_vreg&0x100 );
276 
277 	tilemap_set_scrollx( background, 0, armedf_bg_scrollx+96 );
278 	tilemap_set_scrolly( background, 0, armedf_bg_scrolly );
279 
280 	switch (scroll_type)
281 	{
282 		case	0:		/* terra force */
283 			tilemap_set_scrollx( foreground, 0, (armedf_fg_scrolly>>8) + ((terraf_scroll_msb>>12)&3)*256 - 160-256*3);
284 			tilemap_set_scrolly( foreground, 0, (armedf_fg_scrollx>>8) + ((terraf_scroll_msb>>8)&3)*256 );
285 			break;
286 		case	1:		/* armed formation */
287 		case	2:		/* kodure ookami */
288 			tilemap_set_scrollx( foreground, 0, armedf_fg_scrollx+96 );
289 			tilemap_set_scrolly( foreground, 0, armedf_fg_scrolly );
290 	}
291 
292 	if (scroll_type == 2)		/* kodure ookami */
293 	{
294 		tilemap_set_scrollx( text_layer, 0, -8 );
295 		tilemap_set_scrolly( text_layer, 0, 0 );
296 	}
297 
298 	tilemap_update(  ALL_TILEMAPS  );
299 
300 	palette_init_used_colors();
301 	mark_sprite_colors();
302 	palette_used_colors[0] = PALETTE_COLOR_USED;	/* background */
303 
304 	if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
305 
306 	tilemap_render(  ALL_TILEMAPS  );
307 
308 	if( armedf_vreg & 0x0800 )
309 		tilemap_draw( bitmap, background, 0 );
310 	else
311 		fillbitmap( bitmap, Machine->pens[0], 0 ); /* disabled background - all black? */
312 
313 	if( sprite_enable ) draw_sprites( bitmap, 0 );
314 	tilemap_draw( bitmap, foreground, 0 );
315 	if( sprite_enable ) draw_sprites( bitmap, 1 );
316 	tilemap_draw( bitmap, text_layer, 0 );
317 }
318 
319 
cclimbr2_draw_sprites(struct osd_bitmap * bitmap,int priority)320 static void cclimbr2_draw_sprites( struct osd_bitmap *bitmap, int priority )
321 {
322 	const struct rectangle *clip = &Machine->visible_area;
323 	const struct GfxElement *gfx = Machine->gfx[3];
324 
325 	UINT16 *source = (UINT16 *)spriteram;
326 	UINT16 *finish = source+1024;
327 
328 	while( source<finish )
329 	{
330 		int sy = 240-(source[0]&0x1ff);				// ???
331 		int tile_number = source[1]; /* ??YX?TTTTTTTTTTT */
332 
333 		int color = (source[2]>>8)&0x1f;
334 		int sx = source[3] - 0x68;
335 
336 		if (((source[0] & 0x3000) >> 12) == priority)
337 		{
338 			drawgfx(bitmap,gfx,
339 				tile_number,
340 				color,
341  				tile_number&0x2000,tile_number&0x1000, /* flip */
342 				sx,sy,
343 				clip,TRANSPARENCY_PEN,0xf);
344 		}
345 
346 		source+=4;
347 	}
348 }
349 
cclimbr2_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)350 void cclimbr2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
351 {
352 	unsigned char *RAM;
353 	int sprite_enable = armedf_vreg & 0x200;
354 
355 	tilemap_set_enable( background, armedf_vreg&0x800 );
356 	tilemap_set_enable( foreground, armedf_vreg&0x400 );
357 	tilemap_set_enable( text_layer, armedf_vreg&0x100 );
358 
359 	tilemap_set_scrollx( text_layer, 0, 0 );
360 	tilemap_set_scrolly( text_layer, 0, 0 );
361 
362 	tilemap_set_scrollx( background, 0, armedf_bg_scrollx+104);
363 	tilemap_set_scrolly( background, 0, armedf_bg_scrolly );
364 
365 	RAM = memory_region(REGION_CPU1);
366 	tilemap_set_scrollx( foreground, 0, READ_WORD(&RAM[0x6123c]) - (160 + 256 * 3)+8);	// ???
367 	tilemap_set_scrolly( foreground, 0, READ_WORD(&RAM[0x6123e]) - 1);			// ???
368 
369 	tilemap_update(  ALL_TILEMAPS  );
370 
371 	palette_init_used_colors();
372 	mark_sprite_colors();
373 	palette_used_colors[0] = PALETTE_COLOR_USED;	/* background */
374 
375 	if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
376 
377 	tilemap_render(  ALL_TILEMAPS  );
378 
379 	if( armedf_vreg & 0x0800 )
380 		tilemap_draw( bitmap, background, 0 );
381 	else
382 		fillbitmap( bitmap, Machine->pens[0], 0 ); /* disabled background - all black? */
383 
384 	if( sprite_enable ) cclimbr2_draw_sprites( bitmap, 2 );
385 	tilemap_draw( bitmap, foreground, 0 );
386 	if( sprite_enable ) cclimbr2_draw_sprites( bitmap, 1 );
387 	tilemap_draw( bitmap, text_layer, 0 );
388 	if( sprite_enable ) cclimbr2_draw_sprites( bitmap, 0 );
389 }
390