1 /* Macross Plus - Vidhrdw
2 see DRIVER file for notes */
3
4 #include "driver.h"
5 #include "vidhrdw/generic.h"
6
7
8 data32_t *macrossp_scra_videoram, *macrossp_scra_videoregs;
9 data32_t *macrossp_scrb_videoram, *macrossp_scrb_videoregs;
10 data32_t *macrossp_scrc_videoram, *macrossp_scrc_videoregs;
11 data32_t *macrossp_text_videoram, *macrossp_text_videoregs;
12 data32_t *macrossp_spriteram;
13
14 static data32_t *spriteram_old,*spriteram_old2;
15
16 static struct tilemap *macrossp_scra_tilemap, *macrossp_scrb_tilemap,*macrossp_scrc_tilemap, *macrossp_text_tilemap;
17
18
19 /*** SCR A LAYER ***/
20
WRITE32_HANDLER(macrossp_scra_videoram_w)21 WRITE32_HANDLER( macrossp_scra_videoram_w )
22 {
23 COMBINE_DATA(¯ossp_scra_videoram[offset]);
24
25 tilemap_mark_tile_dirty(macrossp_scra_tilemap,offset);
26 }
27
28
get_macrossp_scra_tile_info(int tile_index)29 static void get_macrossp_scra_tile_info(int tile_index)
30 {
31 UINT32 attr,tileno,color;
32
33 attr = macrossp_scra_videoram[tile_index];
34 tileno = attr & 0x0000ffff;
35
36 switch (macrossp_scra_videoregs[0] & 0x00000c00)
37 {
38 case 0x00000800:
39 color = (attr & 0x000e0000) >> 15;
40 break;
41
42 case 0x00000400:
43 color = (attr & 0x003e0000) >> 17;
44 break;
45
46 default:
47 color = rand() & 7;
48 break;
49 }
50
51 SET_TILE_INFO(1,tileno,color,TILE_FLIPYX((attr & 0xc0000000) >> 30))
52 }
53
54 /*** SCR B LAYER ***/
55
WRITE32_HANDLER(macrossp_scrb_videoram_w)56 WRITE32_HANDLER( macrossp_scrb_videoram_w )
57 {
58 COMBINE_DATA(¯ossp_scrb_videoram[offset]);
59
60 tilemap_mark_tile_dirty(macrossp_scrb_tilemap,offset);
61 }
62
63
get_macrossp_scrb_tile_info(int tile_index)64 static void get_macrossp_scrb_tile_info(int tile_index)
65 {
66 UINT32 attr,tileno,color;
67
68 attr = macrossp_scrb_videoram[tile_index];
69 tileno = attr & 0x0000ffff;
70
71 switch (macrossp_scrb_videoregs[0] & 0x00000c00)
72 {
73 case 0x00000800:
74 color = (attr & 0x000e0000) >> 15;
75 break;
76
77 case 0x00000400:
78 color = (attr & 0x003e0000) >> 17;
79 break;
80
81 default:
82 color = rand() & 7;
83 break;
84 }
85
86 SET_TILE_INFO(2,tileno,color,TILE_FLIPYX((attr & 0xc0000000) >> 30))
87 }
88
89 /*** SCR C LAYER ***/
90
WRITE32_HANDLER(macrossp_scrc_videoram_w)91 WRITE32_HANDLER( macrossp_scrc_videoram_w )
92 {
93 COMBINE_DATA(¯ossp_scrc_videoram[offset]);
94
95 tilemap_mark_tile_dirty(macrossp_scrc_tilemap,offset);
96 }
97
98
get_macrossp_scrc_tile_info(int tile_index)99 static void get_macrossp_scrc_tile_info(int tile_index)
100 {
101 UINT32 attr,tileno,color;
102
103 attr = macrossp_scrc_videoram[tile_index];
104 tileno = attr & 0x0000ffff;
105
106 switch (macrossp_scrc_videoregs[0] & 0x00000c00)
107 {
108 case 0x00000800:
109 color = (attr & 0x000e0000) >> 15;
110 break;
111
112 case 0x00000400:
113 color = (attr & 0x003e0000) >> 17;
114 break;
115
116 default:
117 color = rand() & 7;
118 break;
119 }
120
121 SET_TILE_INFO(3,tileno,color,TILE_FLIPYX((attr & 0xc0000000) >> 30))
122 }
123
124 /*** TEXT LAYER ***/
125
WRITE32_HANDLER(macrossp_text_videoram_w)126 WRITE32_HANDLER( macrossp_text_videoram_w )
127 {
128 COMBINE_DATA(¯ossp_text_videoram[offset]);
129
130 tilemap_mark_tile_dirty(macrossp_text_tilemap,offset);
131 }
132
133
get_macrossp_text_tile_info(int tile_index)134 static void get_macrossp_text_tile_info(int tile_index)
135 {
136 UINT32 tileno, colour;
137
138 tileno = macrossp_text_videoram[tile_index] & 0x0000ffff;
139 colour = (macrossp_text_videoram[tile_index] & 0x00fe0000) >> 17;
140
141 SET_TILE_INFO(4,tileno,colour,0)
142 }
143
144
145
146 /*** VIDEO START / UPDATE ***/
147
VIDEO_START(macrossp)148 VIDEO_START(macrossp)
149 {
150 spriteram_old = auto_malloc(spriteram_size);
151 spriteram_old2 = auto_malloc(spriteram_size);
152
153 if (!spriteram_old || !spriteram_old2)
154 return 1;
155
156 memset(spriteram_old,0,spriteram_size);
157 memset(spriteram_old2,0,spriteram_size);
158
159 macrossp_text_tilemap = tilemap_create(get_macrossp_text_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,64,64);
160 macrossp_scra_tilemap = tilemap_create(get_macrossp_scra_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,64,64);
161 macrossp_scrb_tilemap = tilemap_create(get_macrossp_scrb_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,64,64);
162 macrossp_scrc_tilemap = tilemap_create(get_macrossp_scrc_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,64,64);
163
164 if (!macrossp_text_tilemap || !macrossp_scra_tilemap || !macrossp_scrb_tilemap || !macrossp_scrc_tilemap)
165 return 1;
166
167 tilemap_set_transparent_pen(macrossp_text_tilemap,0);
168 tilemap_set_transparent_pen(macrossp_scra_tilemap,0);
169 tilemap_set_transparent_pen(macrossp_scrb_tilemap,0);
170 tilemap_set_transparent_pen(macrossp_scrc_tilemap,0);
171
172 Machine->gfx[0]->color_granularity=64;
173 Machine->gfx[1]->color_granularity=64;
174 Machine->gfx[2]->color_granularity=64;
175 Machine->gfx[3]->color_granularity=64;
176
177 alpha_set_level(0x80); /* guess */
178
179 return 0;
180 }
181
182
183
macrossp_drawsprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)184 static void macrossp_drawsprites( struct mame_bitmap *bitmap, const struct rectangle *cliprect, int priority )
185 {
186 const struct GfxElement *gfx = Machine->gfx[0];
187 /* data32_t *source = macrossp_spriteram;*/
188 data32_t *source = spriteram_old2; /* buffers by two frames */
189 data32_t *finish = source + spriteram_size/4;
190
191
192 while( source<finish )
193 {
194
195 /*
196
197 --hh hhyy yyyy yyyy CCww wwxx xxxx xxxx
198
199 ---- --zz zzzz zzzz ---- --ZZ ZZZZ ZZZZ
200
201 fFa- pp-- cccc c--- tttt tttt tttt tttt
202
203 */
204
205
206 int wide = (source[0] & 0x00003c00) >> 10;
207 int high = (source[0] & 0x3c000000) >> 26;
208
209 int xpos = (source[0] & 0x000003ff) >> 0;
210 int ypos = (source[0] & 0x03ff0000) >> 16;
211
212 int xzoom = (source[1] & 0x000003ff) >> 0; /* 0x100 is zoom factor of 1.0 */
213 int yzoom = (source[1] & 0x03ff0000) >> 16;
214
215 int col;
216 int tileno = (source[2] & 0x0000ffff) >> 0;
217
218 int flipx = (source[2] & 0x40000000) >> 30;
219 int flipy = (source[2] & 0x80000000) >> 31;
220
221 int trans = (source[2] & 0x20000000)?TRANSPARENCY_ALPHA:TRANSPARENCY_PEN; /* alpha blending enable? */
222
223 int loopno = 0;
224
225 int xcnt,ycnt;
226 int xoffset,yoffset;
227
228 int pri = (source[2] & 0x0c000000) >> 26;
229
230 if (pri == priority)
231 {
232 switch (source[0] & 0x0000c000)
233 {
234 case 0x00008000:
235 col = (source[2] & 0x00380000) >> 17;
236 break;
237
238 case 0x00004000:
239 col = (source[2] & 0x00f80000) >> 19;
240 break;
241
242 default:
243 col = rand();
244 break;
245 }
246
247
248 if (xpos > 0x1ff) xpos -=0x400;
249 if (ypos > 0x1ff) ypos -=0x400;
250
251 if (!flipx) {
252 if (!flipy) { /* noxflip, noyflip */
253 yoffset = 0; /* I'm doing this so rounding errors are cumulative, still looks a touch crappy when multiple sprites used together */
254 for (ycnt = 0; ycnt <= high; ycnt++) {
255 xoffset = 0;
256 for (xcnt = 0; xcnt <= wide; xcnt++) {
257 drawgfxzoom(bitmap,gfx,tileno+loopno,col,flipx,flipy,xpos+xoffset,ypos+yoffset,cliprect,trans,0,xzoom*0x100,yzoom*0x100);
258
259 xoffset += ((xzoom*16 + (1<<7)) >> 8);
260 loopno++;
261 }
262 yoffset += ((yzoom*16 + (1<<7)) >> 8);
263 }
264 }else{ /* noxflip, flipy */
265 yoffset = ((high*yzoom*16) >> 8);
266 for (ycnt = high; ycnt >= 0; ycnt--) {
267 xoffset = 0;
268 for (xcnt = 0; xcnt <= wide; xcnt++) {
269 drawgfxzoom(bitmap,gfx,tileno+loopno,col,flipx,flipy,xpos+xoffset,ypos+yoffset,cliprect,trans,0,xzoom*0x100,yzoom*0x100);
270
271 xoffset += ((xzoom*16 + (1<<7)) >> 8);
272 loopno++;
273 }
274 yoffset -= ((yzoom*16 + (1<<7)) >> 8);
275 }
276 }
277 }else{
278 if (!flipy) { /* xflip, noyflip */
279 yoffset = 0;
280 for (ycnt = 0; ycnt <= high; ycnt++) {
281 xoffset = ((wide*xzoom*16) >> 8);
282 for (xcnt = wide; xcnt >= 0; xcnt--) {
283 drawgfxzoom(bitmap,gfx,tileno+loopno,col,flipx,flipy,xpos+xoffset,ypos+yoffset,cliprect,trans,0,xzoom*0x100,yzoom*0x100);
284
285 xoffset -= ((xzoom*16 + (1<<7)) >> 8);
286 loopno++;
287 }
288 yoffset += ((yzoom*16 + (1<<7)) >> 8);
289 }
290 }else{ /* xflip, yflip */
291 yoffset = ((high*yzoom*16) >> 8);
292 for (ycnt = high; ycnt >= 0; ycnt--) {
293 xoffset = ((wide*xzoom*16) >> 8);
294 for (xcnt = wide; xcnt >=0 ; xcnt--) {
295 drawgfxzoom(bitmap,gfx,tileno+loopno,col,flipx,flipy,xpos+xoffset,ypos+yoffset,cliprect,trans,0,xzoom*0x100,yzoom*0x100);
296
297 xoffset -= ((xzoom*16 + (1<<7)) >> 8);
298 loopno++;
299 }
300 yoffset -= ((yzoom*16 + (1<<7)) >> 8);
301 }
302 }
303 }
304 }
305 source += 3;
306 }
307 }
308
309
draw_layer(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int layer)310 static void draw_layer(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int layer)
311 {
312 struct tilemap *tm;
313 data32_t *vr;
314
315 switch (layer)
316 {
317 case 0:
318 default:
319 tm = macrossp_scra_tilemap;
320 vr = macrossp_scra_videoregs;
321 break;
322
323 case 1:
324 tm = macrossp_scrb_tilemap;
325 vr = macrossp_scrb_videoregs;
326 break;
327
328 case 2:
329 tm = macrossp_scrc_tilemap;
330 vr = macrossp_scrc_videoregs;
331 break;
332 }
333
334 if ((vr[2] & 0xf0000000) == 0xe0000000) /* zoom enable (guess, surely wrong) */
335 {
336 int startx,starty,inc;
337
338 startx = (vr[1] & 0x0000ffff) << 16;
339 starty = (vr[1] & 0xffff0000) >> 0;
340 inc = (vr[2] & 0x00ff0000) >> 6,
341
342 /* WRONG! */
343 /* scroll register contain position relative to the center of the screen, so adjust */
344 startx -= (368/2) * inc;
345 starty -= (240/2) * inc;
346
347 tilemap_draw_roz(bitmap,cliprect,tm,
348 startx,starty,inc,0,0,inc,
349 1, /* wraparound */
350 0,0);
351 }
352 else
353 {
354 tilemap_set_scrollx( tm, 0, ((vr[0] & 0x000003ff) >> 0 ) );
355 tilemap_set_scrolly( tm, 0, ((vr[0] & 0x03ff0000) >> 16) );
356 tilemap_draw(bitmap,cliprect,tm,0,0);
357 }
358 }
359
360 /* useful function to sort the three tile layers by priority order */
sortlayers(int * layer,int * pri)361 static void sortlayers(int *layer,int *pri)
362 {
363 #define SWAP(a,b) \
364 if (pri[a] >= pri[b]) \
365 { \
366 int t; \
367 t = pri[a]; pri[a] = pri[b]; pri[b] = t; \
368 t = layer[a]; layer[a] = layer[b]; layer[b] = t; \
369 }
370
371 SWAP(0,1)
372 SWAP(0,2)
373 SWAP(1,2)
374 }
375
VIDEO_UPDATE(macrossp)376 VIDEO_UPDATE(macrossp)
377 {
378 int layers[3],layerpri[3];
379
380
381 fillbitmap(bitmap,get_black_pen(),cliprect);
382
383 layers[0] = 0;
384 layerpri[0] = (macrossp_scra_videoregs[0] & 0x0000c000) >> 14;
385 layers[1] = 1;
386 layerpri[1] = (macrossp_scrb_videoregs[0] & 0x0000c000) >> 14;
387 layers[2] = 2;
388 layerpri[2] = (macrossp_scrc_videoregs[0] & 0x0000c000) >> 14;
389
390 sortlayers(layers, layerpri);
391
392 draw_layer(bitmap,cliprect,layers[0]);
393 macrossp_drawsprites(bitmap,cliprect,0);
394 draw_layer(bitmap,cliprect,layers[1]);
395 macrossp_drawsprites(bitmap,cliprect,1);
396 draw_layer(bitmap,cliprect,layers[2]);
397 macrossp_drawsprites(bitmap,cliprect,2);
398 macrossp_drawsprites(bitmap,cliprect,3);
399 tilemap_draw(bitmap,cliprect,macrossp_text_tilemap,0,0);
400
401 #if 0
402 usrintf_showmessage ("scra - %08x %08x %08x\nscrb - %08x %08x %08x\nscrc - %08x %08x %08x",
403 macrossp_scra_videoregs[0]&0xffff33ff, /* yyyyxxxx*/
404 macrossp_scra_videoregs[1], /* ??? more scrolling?*/
405 macrossp_scra_videoregs[2], /* 08 - 0b*/
406
407 macrossp_scrb_videoregs[0]&0xffff33ff, /* 00 - 03*/
408 macrossp_scrb_videoregs[1], /* 04 - 07*/
409 macrossp_scrb_videoregs[2], /* 08 - 0b*/
410
411 macrossp_scrc_videoregs[0]&0xffff33ff, /* 00 - 03*/
412 macrossp_scrc_videoregs[1], /* 04 - 07*/
413 macrossp_scrc_videoregs[2]);/* 08 - 0b*/
414 #endif
415 }
416
VIDEO_EOF(macrossp)417 VIDEO_EOF( macrossp )
418 {
419 /* looks like sprites are *two* frames ahead, like nmk16 */
420 memcpy(spriteram_old2,spriteram_old,spriteram_size);
421 memcpy(spriteram_old,macrossp_spriteram,spriteram_size);
422 }
423