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