1 /***************************************************************************
2 
3     Denjin Makai video hardware (derived from D-Con)
4 
5 ***************************************************************************/
6 
7 #include "driver.h"
8 #include "includes/denjinmk.h"
9 #include "vidhrdw/generic.h"
10 
11 UINT16 *denjinmk_back_data,*denjinmk_fore_data,*denjinmk_mid_data,*denjinmk_scrollram16,*denjinmk_textram;
12 
13 static struct tilemap *background_layer,*foreground_layer,*midground_layer,*text_layer;
14 UINT16 denjinmk_layer_disable;
15 int denjinmk_sprite_xoffs,denjinmk_sprite_yoffs;
16 static int denjinmk_has_extended_banking;
17 static int denjinmk_has_extended_priority;
18 /******************************************************************************/
19 static UINT16 back_gfx_bank = 0,fore_gfx_bank = 0,mid_gfx_bank = 0;
20 UINT8 grainbow_pri_n;
21 
22 
23 /*xxx- --- ---- ---- banking*/
denjinmk_setgfxbank(UINT16 data)24 void denjinmk_setgfxbank(UINT16 data)
25 {
26 	fore_gfx_bank = (data &0x2000) >> 1;/*???*/
27 	back_gfx_bank = (data &0x4000) >> 2;
28 	mid_gfx_bank  = (data &0x8000) >> 3;/*???*/
29 
30 	tilemap_mark_all_tiles_dirty (background_layer);
31 	tilemap_mark_all_tiles_dirty (foreground_layer);
32 	tilemap_mark_all_tiles_dirty (midground_layer);
33 	tilemap_mark_all_tiles_dirty (text_layer);
34 }
35 
36 
WRITE16_HANDLER(denjinmk_background_w)37 WRITE16_HANDLER( denjinmk_background_w )
38 {
39 	int oldword = denjinmk_back_data[offset];
40 	COMBINE_DATA(&denjinmk_back_data[offset]);
41 	if (oldword != denjinmk_back_data[offset])
42 		tilemap_mark_tile_dirty(background_layer,offset);
43 }
44 
WRITE16_HANDLER(denjinmk_midground_w)45 WRITE16_HANDLER( denjinmk_midground_w )
46 {
47 	int oldword = denjinmk_mid_data[offset];
48 	COMBINE_DATA(&denjinmk_mid_data[offset]);
49 	if (oldword != denjinmk_mid_data[offset])
50 		tilemap_mark_tile_dirty(midground_layer,offset);
51 }
52 
WRITE16_HANDLER(denjinmk_foreground_w)53 WRITE16_HANDLER( denjinmk_foreground_w )
54 {
55 	int oldword = denjinmk_fore_data[offset];
56 	COMBINE_DATA(&denjinmk_fore_data[offset]);
57 	if (oldword != denjinmk_fore_data[offset])
58 		tilemap_mark_tile_dirty(foreground_layer,offset);
59 }
60 
WRITE16_HANDLER(denjinmk_text_w)61 WRITE16_HANDLER( denjinmk_text_w )
62 {
63 	int oldword = denjinmk_textram[offset];
64 	COMBINE_DATA(&denjinmk_textram[offset]);
65 	if (oldword != denjinmk_textram[offset])
66 		tilemap_mark_tile_dirty(text_layer,offset);
67 }
68 
69 
get_back_tile_info(int tile_index)70 static void get_back_tile_info(int tile_index)
71 {
72 	int tile=denjinmk_back_data[tile_index];
73 	int color=(tile>>12)&0xf;
74 
75 	tile &= 0xfff;
76 	tile |= back_gfx_bank;		/* Heatbrl uses banking */
77 
78 	SET_TILE_INFO(1,tile,color,0);
79 }
80 
81 
get_mid_tile_info(int tile_index)82 static void get_mid_tile_info(int tile_index)
83 {
84 	int tile=denjinmk_mid_data[tile_index];
85 	int color=(tile>>12)&0xf;
86 
87 	tile &= 0xfff;
88 
89 	SET_TILE_INFO(5,tile,color,0);
90 }
91 
92 
get_mid_tile_info_denji(int tile_index)93 static void get_mid_tile_info_denji(int tile_index)
94 {
95 	int tile=denjinmk_mid_data[tile_index];
96 	int color=(tile>>12)&0xf;
97 
98 	tile &= 0xfff;
99 	tile |= mid_gfx_bank;
100 
101 	SET_TILE_INFO(5,tile,color,0);
102 }
103 
104 
105 
get_fore_tile_info(int tile_index)106 static void get_fore_tile_info(int tile_index)	/* this is giving bad tiles... */
107 {
108 	int tile=denjinmk_fore_data[tile_index];
109 	int color=(tile>>12)&0xf;
110 
111 	/* denjinmk tile numbers / gfx set wrong, see screen after coin insertion*/
112 	tile &= 0xfff;
113 
114 	SET_TILE_INFO(4,tile,color,0);
115 }
116 
117 
get_fore_tile_info_denji(int tile_index)118 static void get_fore_tile_info_denji(int tile_index)
119 {
120 	int tile=denjinmk_fore_data[tile_index];
121 	int color=(tile>>12)&0xf;
122 
123 	tile &= 0xfff;
124 	tile |= fore_gfx_bank;
125 
126 	SET_TILE_INFO(4,tile,color,0);
127 }
128 
get_text_tile_info(int tile_index)129 static void get_text_tile_info(int tile_index)
130 {
131 	int tile = denjinmk_textram[tile_index];
132 	int color=(tile>>12)&0xf;
133 
134 	tile &= 0xfff;
135 
136 	SET_TILE_INFO(0,tile,color,0)
137 }
138 
139 
VIDEO_START(denjinmk)140 VIDEO_START( denjinmk )
141 {
142 
143 	background_layer = tilemap_create(get_back_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
144 	foreground_layer = tilemap_create(get_fore_tile_info_denji,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
145 	midground_layer =  tilemap_create(get_mid_tile_info_denji, tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
146 	text_layer =       tilemap_create(get_text_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,  8,8,64,32);
147 
148 
149 	if (!background_layer || !foreground_layer || !midground_layer || !text_layer)
150 	    return 1;
151 
152 	denjinmk_scrollram16 = auto_malloc(0x60);
153 	denjinmk_sprite_xoffs = 0;
154 	denjinmk_sprite_yoffs = 0;
155 
156 	denjinmk_has_extended_banking = 1;
157 	denjinmk_has_extended_priority = 0;
158 
159 	if (!denjinmk_scrollram16)	return 1;
160 
161 	tilemap_set_transparent_pen(background_layer,15);
162 	tilemap_set_transparent_pen(midground_layer,15);
163 	tilemap_set_transparent_pen(foreground_layer,15);
164 	tilemap_set_transparent_pen(text_layer,7); /*?*/
165 
166 
167 	return 0;
168 }
169 
170 
171 /*************************************************************************
172 
173     denjinmk Spriteram (similar to Dcon)
174     ---------------------
175 
176     It has "big sprites" created by setting width or height >0. Tile
177     numbers are read consecutively.
178 
179     +0   x....... ........  Sprite enable
180     +0   .x...... ........  Flip x
181     +0   ..x..... ........  Flip y ???
182     +0   ...xxx.. ........  Width: do this many tiles horizontally
183     +0   ......xx x.......  Height: do this many tiles vertically
184     +0   ........ .x......  Tile bank,used in Denjin Makai
185     +0   ........ ..xxxxxx  Color bank
186 
187     +1   xx...... ........  Priority? (1=high?)
188     +1   ..xxxxxx xxxxxxxx  Tile number
189 
190     +2   ----xxxx xxxxxxxx  X coordinate (signed)
191 
192     +3   b------- --------  more tile banking used by Denjin Makai
193     +3   ----xxxx xxxxxxxx  Y coordinate (signed)
194 
195 *************************************************************************/
196 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)197 static void draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
198 {
199 	int offs,fx,fy,x,y,color,sprite,cur_pri;
200 	int dx,dy,ax,ay;
201 	int pri_mask;
202 
203 	for (offs = 0;offs < 0x400;offs += 4)
204 	{
205 		UINT16 data = spriteram16[offs];
206 		if (!(data &0x8000)) continue;
207 
208 		pri_mask = 0;
209 
210 		if (denjinmk_has_extended_priority)
211 		{
212 
213 			cur_pri = (spriteram16[offs+1] & 0xc000) >> 14;
214 
215 			if(data & 0x0040)
216 			{
217 				cur_pri |= 0x4; /* definitely seems to be needed by grainbow*/
218 			}
219 
220 			/**/
221 			/* -4 behind bg? (mask sprites)*/
222 			/* -32 behind mid*/
223 			/* -256 behind tx*/
224 			/* 0    above all*/
225 
226 			/* is the low bit REALLY priority?*/
227 
228 			switch (cur_pri)
229 			{
230 				case 0:	pri_mask = -256; break; /* gumdam swamp monster l2*/
231 				case 1:	pri_mask = -256; break; /* cupsoc*/
232 				case 2:	pri_mask = -4; break; /* masking effect for gundam l2 monster*/
233 				case 3: pri_mask = -4; break; /* cupsoc (not sure what..)*/
234 				case 4: pri_mask = -32; break; /* gundam level 2/3 player*/
235 				/*case 5: pri_mask = 0; break;*/
236 				case 6: pri_mask = 0; break; /* insert coin in gundam*/
237 				/*case 7: pri_mask = 0; break;*/
238 
239 				default: log_cb(RETRO_LOG_DEBUG, LOGPRE "unhandled pri %d\n",cur_pri); pri_mask=0;
240 			}
241 
242 		}
243 		else
244 		{
245 			cur_pri = (spriteram16[offs+1] & 0xc000) >> 14;
246 
247 			switch (cur_pri)
248 			{
249 				case 0:	pri_mask = 0xfffc; break; /*?*/
250 				case 1:	pri_mask = 0xfffc; break; /*?*/
251 				case 2:	pri_mask = 0xfffc; break; /* player sprites in denjinmkire*/
252 				case 3: pri_mask = 0xfffe; break; /* stuff that goes behind the playfield (barriers on train level in denjinmkire)*/
253 			}
254 
255 		}
256 
257 		sprite = spriteram16[offs+1];
258 
259 		sprite &= 0x3fff;
260 
261 		if (denjinmk_has_extended_banking)
262 		{
263 			if(data & 0x0040)
264 			{
265 				sprite |= 0x4000;/*tile banking,used in Denjin Makai*/
266 			}
267 			if(spriteram16[offs+3] & 0x8000)
268 			{
269 				sprite |= 0x8000;/*tile banking?,used in Denjin Makai*/
270 			}
271 		}
272 
273 
274 		y = spriteram16[offs+3];
275 		x = spriteram16[offs+2];
276 
277 		/* heated barrel hardware seems to need 0x1ff with 0x100 sign bit for sprite warp,
278            this doesn't work on denjin makai as the visible area is larger */
279 		if (cliprect->max_x<(320-1))
280 		{
281 			x&=0x1ff;
282 			y&=0x1ff;
283 
284 			if (x&0x100) x-=0x200;
285 			if (y&0x100) y-=0x200;
286 		}
287 		else
288 		{
289 			x&=0xfff;
290 			y&=0xfff;
291 
292 			if (x&0x800) x-=0x1000;
293 			if (y&0x800) y-=0x1000;
294 
295 		}
296 
297 
298 		color = (data &0x3f) + 0x40;
299 		fx =  (data &0x4000) >> 14;
300 		fy =  (data &0x2000) >> 13;
301 		dy = ((data &0x0380) >> 7)  + 1;
302 		dx = ((data &0x1c00) >> 10) + 1;
303 
304 		if (!fx)
305 		{
306 			if(!fy)
307 			{
308 				for (ax=0; ax<dx; ax++)
309 					for (ay=0; ay<dy; ay++)
310 					{
311 					  pdrawgfx(bitmap,Machine->gfx[3],
312 					  sprite++,
313                       color,fx,fy,(x+ax*16)+denjinmk_sprite_xoffs,y+ay*16+denjinmk_sprite_yoffs,
314 					  cliprect,TRANSPARENCY_PEN,15,
315 					  pri_mask);
316 					}
317 			}
318 			else
319 			{
320 				for (ax=0; ax<dx; ax++)
321 					for (ay=0; ay<dy; ay++)
322 					{
323 					  pdrawgfx(bitmap,Machine->gfx[3],
324 					  sprite++,
325 					  color,fx,fy,(x+ax*16)+denjinmk_sprite_xoffs,y+(dy-ay-1)*16+denjinmk_sprite_yoffs,
326 					  cliprect,TRANSPARENCY_PEN,15,
327 					  pri_mask);
328 					}
329 			}
330 		}
331 		else
332 		{
333 			if(!fy)
334 			{
335 				for (ax=0; ax<dx; ax++)
336 					for (ay=0; ay<dy; ay++)
337 					{
338 						pdrawgfx(bitmap,Machine->gfx[3],
339 					    sprite++,
340 					    color,fx,fy,(x+(dx-ax-1)*16)+denjinmk_sprite_xoffs,y+ay*16+denjinmk_sprite_yoffs,
341 					    cliprect,TRANSPARENCY_PEN,15,
342 						pri_mask);
343 					}
344 			}
345 			else
346 			{
347 				for (ax=0; ax<dx; ax++)
348 					for (ay=0; ay<dy; ay++)
349 					{
350 						pdrawgfx(bitmap,Machine->gfx[3],
351 					    sprite++,
352 					    color,fx,fy,(x+(dx-ax-1)*16)+denjinmk_sprite_xoffs,y+(dy-ay-1)*16+denjinmk_sprite_yoffs,
353 					    cliprect,TRANSPARENCY_PEN,15,
354 						pri_mask);
355 
356 					}
357 			}
358 		}
359 	}
360 }
361 
362 
363 #define LAYER_DB 0
364 
365 
VIDEO_UPDATE(denjinmk)366 VIDEO_UPDATE( denjinmk )
367 {
368 /*  tilemap_set_scrollx( text_layer, 0, 0 );*/
369 /*  tilemap_set_scrolly( text_layer, 0, 112 );*/
370 	/* Setup the tilemaps */
371 
372 	tilemap_set_scrollx( background_layer, 0, denjinmk_scrollram16[0] );
373 	tilemap_set_scrolly( background_layer, 0, denjinmk_scrollram16[1] );
374 	tilemap_set_scrollx( midground_layer,  0, denjinmk_scrollram16[2] );
375 	tilemap_set_scrolly( midground_layer,  0, denjinmk_scrollram16[3] );
376 	tilemap_set_scrollx( foreground_layer, 0, denjinmk_scrollram16[4] );
377 	tilemap_set_scrolly( foreground_layer, 0, denjinmk_scrollram16[5] );
378 	tilemap_set_scrollx( text_layer, 0,  0/*denjinmk_scrollram16[6]*/ );
379 	tilemap_set_scrolly( text_layer, 0,  0/*denjinmk_scrollram16[7]*/ );
380 
381 	fillbitmap(priority_bitmap,0,cliprect);
382 	/* matches PCB recording for Denjin Makai, settable thru CRTC?*/
383 	fillbitmap(bitmap,0xff,cliprect);
384 
385 	if (!(denjinmk_layer_disable&0x0001)) tilemap_draw(bitmap,cliprect,background_layer,0,0);
386 	if (!(denjinmk_layer_disable&0x0002)) tilemap_draw(bitmap,cliprect,midground_layer,0,0);
387 	if (!(denjinmk_layer_disable&0x0004)) tilemap_draw(bitmap,cliprect,foreground_layer,0,1);
388 	if (!(denjinmk_layer_disable&0x0008)) tilemap_draw(bitmap,cliprect,text_layer,0,2);
389 
390 	draw_sprites(bitmap,cliprect);
391 /*	return 0;*/
392 }
393