Previous 15994 Revisions Next

r9079 Thursday 9th September, 2010 at 14:55:27 UTC by Angelo Salese
[SUPER A'CAN] cleaned up super a'can video implementation, pending further work [David Haywood]
[src/mess/drivers]supracan.c

src/mess/drivers/supracan.c
r9078r9079
4747    - All: Priorities are largely unknown.
4848    - C.U.G.: Gameplay backgrounds are broken.
4949    - Sango Fighter: Possible missing masking on the upper edges of the screen during gameplay.
50   - Sango Fighter: Raster effects off by 1 line
5051    - Speedy Dragon: Backgrounds are broken (wrong tile bank/region).
5152    - Super Taiwanese Baseball League: Does not boot for unknown reasons.
5253    - Super Taiwanese Baseball League: Missing window effect applied on tilemaps?
5354    - The Son of Evil: Does not boot for unknown reasons.
5455    - The Son of Evil: Many graphical issues.
56   
57   - All: are ALL the layers ROZ capable??
5558
5659DEBUG TRICKS:
5760
r9078r9079
130133    emu_timer *line_on_timer;
131134    emu_timer *line_off_timer;
132135   UINT16 *vram;
136   UINT16 *vram_swapped;
137   UINT8 *vram_addr_swapped;
138   
133139    UINT16 *pram;
134140
135    bitmap_t *sprite_final_bitmap;
136    UINT8 sprite_pri[1024*1024];
137141    UINT16 sprite_count;
138142   UINT32 sprite_base_addr;
139143    UINT8 sprite_flags;
140144
141    bitmap_t *tilemap_bitmap[3];
142    bitmap_t *tilemap_final_bitmap[3];
143    UINT8 tilemap_pri[3][1024*1024];
144    UINT8 tilemap_final_pri[3][320*240];
145   UINT32 tilemap_base_addr[3];
145    UINT32 tilemap_base_addr[3];
146146   int tilemap_scrollx[3];
147147    int tilemap_scrolly[3];
148148   UINT16 video_flags;
r9078r9079
151151   UINT16 irq_mask;
152152    UINT16 hbl_mask;
153153
154    bitmap_t *roz_bitmap;
155    bitmap_t *roz_final_bitmap;
156    UINT8 roz_pri[1024*1024];
157    UINT8 roz_final_pri[320*240];
158154   UINT32 roz_base_addr;
159155   UINT16 roz_mode;
160156   UINT32 roz_scrollx;
r9078r9079
175171   UINT16 video_regs[256];
176172
177173    bool hack_68k_to_6502_access;
174   
175   tilemap_t    *tilemap_sizes[4][4];
176   bitmap_t    *sprite_final_bitmap;
177
178
179
178180};
179181
180182static READ16_HANDLER( supracan_68k_soundram_r );
r9078r9079
202204#define verboselog(w,x,y,z,...)
203205#endif
204206
205static VIDEO_START( supracan )
207int supracan_tilemap_get_region(running_machine* machine, int layer)
206208{
207209    supracan_state *state = machine->driver_data<supracan_state>();
208    state->roz_bitmap = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16);
209    state->roz_final_bitmap = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16);
210    state->tilemap_bitmap[0] = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16);
211    state->tilemap_bitmap[1] = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16);
212    state->tilemap_bitmap[2] = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16);
213    state->tilemap_final_bitmap[0] = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16);
214    state->tilemap_final_bitmap[1] = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16);
215    state->tilemap_final_bitmap[2] = auto_bitmap_alloc(machine, 320, 240, BITMAP_FORMAT_INDEXED16);
216    state->sprite_final_bitmap = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16);
217}
218210
219static UINT16 fetch_8bpp_tile_pixel(running_machine *machine, int tile, int palette, bool xflip, bool yflip, int x, int y)
220{
221    supracan_state *state = machine->driver_data<supracan_state>();
222    UINT16 *supracan_vram = state->vram;
211   // HACK!!!
212   if (layer==2)
213   {
214      return 2;
215   }
216   
217   
218   if (layer==3)
219   {
220      // roz layer
223221
224    if(xflip) x = 7 - x;
225    if(yflip) y = 7 - y;
222      int gfx_mode = (state->roz_mode & 3);
223     
224      switch(gfx_mode)
225      {
226         case 0:   return 4;
227         case 1: return 2;
228         case 2: return 1;
229         case 3: return 0;
230      }
231      return 1;
232   }
233   else
234   {
235      // normal layers
236      int gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12;
226237
227    UINT32 address = (tile * 8 * 8 + y * 8 + x) >> 1;
228    UINT8 shift = (x & 1) ? 0 : 8;
238      switch(gfx_mode)
239      {
240         case 7: return 2;
241         case 4: return 1;
242         case 2: return 1;
243         case 0: return 1;
244      }
245           
246      return 1;
247   }
229248
230    return (supracan_vram[address] >> shift) & 0x00ff;
231249}
232250
233static UINT16 fetch_4bpp_tile_pixel(running_machine *machine, int tile, int palette, bool xflip, bool yflip, int x, int y)
251static void supracan_tilemap_get_info_common(running_machine* machine, int layer, tile_data *tileinfo, int count)
234252{
235253    supracan_state *state = machine->driver_data<supracan_state>();
236    UINT16 *supracan_vram = state->vram;
237254
238    if(xflip) x = 7 - x;
239    if(yflip) y = 7 - y;
255   UINT16* supracan_vram = state->vram;
240256
241    UINT32 address = (tile * 8 * 4 + y * 4 + (x >> 1)) >> 1;
242    UINT8 shift = (3 - (x & 3)) * 4;
243
244    return (palette << 4) | ((supracan_vram[address] >> shift) & 0x000f);
245}
246
247static UINT16 fetch_2bpp_tile_pixel(running_machine *machine, int tile, int palette, bool xflip, bool yflip, int x, int y)
248{
249    supracan_state *state = machine->driver_data<supracan_state>();
250    UINT16 *supracan_vram = state->vram;
251
252    if(xflip) x = 7 - x;
253    if(yflip) y = 7 - y;
254
255    UINT32 address = (tile * 8 * 2 + y * 2 + (x >> 2)) >> 1;
256    UINT8 shift = (7 - (x & 7)) * 2;
257
258    return (palette << 4) | ((supracan_vram[address] >> shift) & 0x0003);
259}
260
261static void draw_tile(running_machine *machine, UINT8* primap, bitmap_t *bitmap, const rectangle *cliprect, int tile, int palette, bool xflip, bool yflip, int x, int y, int priority, int depth, int mask, int xprioffset = 0, int yprioffset = 0, UINT32 xwrap = 0, UINT32 ywrap = 0)
262{
263    for(int tiley = 0; tiley < 8; tiley++)
264    {
265        for(int tilex = 0; tilex < 8; tilex++)
266        {
267            UINT16 pixel = 0;
268            switch(depth)
269            {
270                case 0: // 8bpp
271                    pixel = fetch_8bpp_tile_pixel(machine, tile, palette, xflip, yflip, tilex, tiley);
272                    break;
273                case 1: // 4bpp
274                    pixel = fetch_4bpp_tile_pixel(machine, tile, palette, xflip, yflip, tilex, tiley);
275                    if((pixel & 0x0f) == 0)
276                    {
277                        pixel = 0;
278                    }
279                    break;
280                case 2: // 2bpp
281                    pixel = fetch_2bpp_tile_pixel(machine, tile, palette, xflip, yflip, tilex, tiley);
282                    if((pixel & 0x03) == 0)
283                    {
284                        pixel = 0;
285                    }
286                    break;
287                default:
288                    fatalerror("Unsupported bit depth for draw_tile\n");
289                    break;
290            }
291
292            int total_x = x + tilex;
293            int total_y = y + tiley;
294            if(xwrap)
295            {
296            while(total_x < 0) total_x += xwrap;
297            while(total_x >= xwrap) total_x -= xwrap;
298         }
299            if(ywrap)
300            {
301            while(total_y < 0) total_y += ywrap;
302            while(total_y >= ywrap) total_y -= ywrap;
303         }
304            if((cliprect != NULL && total_x >= cliprect->min_x && total_y >= cliprect->min_y && total_x < cliprect->max_x && total_y < cliprect->max_y) || cliprect == NULL)
305            {
306                if(pixel)
307                {
308                    switch(mask)
309                    {
310                        case 0: // Default
311                            *BITMAP_ADDR16(bitmap, total_y, total_x) = pixel;
312                            primap[(total_y + yprioffset)*1024 + total_x + xprioffset] = (UINT8)priority;
313                            break;
314                        case 1: // Mask against previous alpha
315                            if(*BITMAP_ADDR16(bitmap, total_y, total_x) & 0x8000)
316                            {
317                                *BITMAP_ADDR16(bitmap, total_y, total_x) = pixel | 0x8000;
318                                primap[(total_y + yprioffset)*1024 + total_x + xprioffset] = (UINT8)priority;
319                            }
320                            break;
321                        case 2: // Write to alpha
322                            *BITMAP_ADDR16(bitmap, total_y, total_x) |= 0x8000;
323                            break;
324                        case 3: // Clear mask
325                            *BITMAP_ADDR16(bitmap, total_y, total_x) &= 0x7fff;
326                            break;
327                    }
328                }
329            }
330        }
331    }
332}
333
334static void draw_tilemap_scanline(running_machine *machine, UINT16 *scanline, UINT8 *priline, int ypos, int layer)
335{
336    supracan_state *state = machine->driver_data<supracan_state>();
337
338    if((!(state->video_flags & 0x80) && layer == 0) ||
339       (!(state->video_flags & 0x40) && layer == 1) ||
340       (!(state->video_flags & 0x20) && layer == 2))
341    {
342        for(int x = 0; x < 320; x++)
343        {
344            priline[x] = 9;
345            scanline[x] = 0;
346        }
347        return;
348    }
349
350    int width = 32;
351    int height = 32;
352    switch(state->tilemap_flags[layer] & 0x0f00)
353    {
354        case 0x600:
355            width = 64;
356            break;
357
358        case 0xa00:
359            width = 128;
360            break;
361
362        case 0xc00:
363            width = 64;
364            height = 64;
365            break;
366
367        default:
368            //verboselog("maincpu", machine, 0, "Unsupported tilemap size: %04x\n", state->tilemap_flags[layer] & 0x0f00);
369            break;
370    }
371
372    int scrollx = state->tilemap_scrollx[layer];
373    int scrolly = state->tilemap_scrolly[layer];
374    scrollx |= (scrollx & 0x800) ? 0xfffff000 : 0;
375    scrolly |= (scrolly & 0x800) ? 0xfffff000 : 0;
376
377    int wrapped_x = scrollx;
378    int wrapped_y = ypos + scrolly;
379
380    if(state->tilemap_flags[layer] & 0x20)
381    {
382        while(wrapped_y >= height*8) wrapped_y -= height*8;
383        while(wrapped_y < 0) wrapped_y += height*8;
384    }
385    else
386    {
387        if(wrapped_y < 0 || wrapped_y >= height*8)
388        {
389            for(int x = 0; x < 320; x++)
390            {
391                scanline[x] = 0;
392                priline[x] = 9;
393            }
394            return;
395        }
396    }
397
398    int mosaic_count = (state->tilemap_flags[layer] & 0x001c) >> 2;
399    int mosaic_mask = 0xffffffff << mosaic_count;
400
401    UINT16 *src = BITMAP_ADDR16(state->tilemap_bitmap[layer], wrapped_y & mosaic_mask, 0);
402    UINT8 *srcpri = &state->tilemap_pri[layer][1024*(wrapped_y & mosaic_mask)];
403
404    if(state->tilemap_flags[layer] & 0x20)
405    {
406        while(wrapped_x >= width*8) wrapped_x -= width*8;
407        while(wrapped_x < 0) wrapped_x += width*8;
408
409        for(int x = 0; x < 320; x++)
410        {
411            scanline[x] = src[wrapped_x & mosaic_mask] ? src[wrapped_x & mosaic_mask] : scanline[x];
412            priline[x] = src[wrapped_x & mosaic_mask] ? srcpri[wrapped_x & mosaic_mask] : 9;
413            wrapped_x++;
414            while(wrapped_x >= width*8) wrapped_x -= width*8;
415        }
416    }
417    else
418    {
419        for(int x = 0; x < 320; x++)
420        {
421            if(wrapped_x >= 0 && wrapped_x < width*8)
422            {
423                scanline[x] = src[wrapped_x & mosaic_mask] ? src[wrapped_x & mosaic_mask] : scanline[x];
424                priline[x] = src[wrapped_x & mosaic_mask] ? srcpri[wrapped_x & mosaic_mask] : 9;
425            }
426            else
427            {
428                scanline[x] = scanline[x];
429                priline[x] = 9;
430            }
431            wrapped_x++;
432        }
433    }
434}
435
436static void draw_tilemap(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int layer)
437{
438    /*crash debug: printf("F"); fflush(stdout); */
439    supracan_state *state = machine->driver_data<supracan_state>();
440   UINT16 *supracan_vram = state->vram;
441
442   UINT32 count = (state->tilemap_base_addr[layer]);
443
444    int xsize = 32;
445    int ysize = 32;
446   switch(state->tilemap_flags[layer] & 0x0f00)
447   {
448      case 0x600:
449            xsize = 64;
450            ysize = 32;
451            break;
452
453        case 0xa00:
454            xsize = 128;
455            ysize = 32;
456            break;
457
458        case 0xc00:
459            xsize = 64;
460            ysize = 64;
461            break;
462
463        default:
464            verboselog("maincpu", machine, 0, "Unsupported tilemap size for layer %d: %04x\n", layer, state->tilemap_flags[layer] & 0x0f00);
465            break;
466   }
467
468    UINT8 priority = ((state->tilemap_flags[layer] >> 13) & 7) + 1;
469
470    int scrollx = state->tilemap_scrollx[layer];
471    int scrolly = state->tilemap_scrolly[layer];
472    scrollx |= (scrollx & 0x800) ? 0xfffff000 : 0;
473    scrolly |= (scrolly & 0x800) ? 0xfffff000 : 0;
474
257   UINT32 base = (state->tilemap_base_addr[layer]);
475258   int gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12;
259   int region = supracan_tilemap_get_region(machine, layer);
476260
477    int region = 1;
261   count += base;
262 
478263    UINT16 tile_bank = 0;
479264    UINT16 palette_bank = 0;
480265   switch(gfx_mode)
481266   {
482267      case 7:
483            region = 2;
484268            tile_bank = 0x1c00;
485269            palette_bank = 0x00;
486270            break;
487271
488272        case 4:
489            region = 1;
490273            tile_bank = 0x800;
491274            palette_bank = 0x00;
492275            break;
493276
494277        case 2:
495            region = 1;
496278            tile_bank = 0x400;
497279            palette_bank = 0x00;
498280            break;
499281
500282        case 0:
501            region = 1;
502283            tile_bank = 0;
503284            palette_bank = 0x00;
504285            break;
r9078r9079
508289            break;
509290   }
510291
292
511293    if(layer == 2)
512294    {
513        region = 2;
514295        tile_bank = 0x1000;
515296    }
297 
298   int tile = (supracan_vram[count] & 0x03ff) + tile_bank;
299   int flipxy = (supracan_vram[count] & 0x0c00)>>10;
300   int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank;
516301
517    if(state->tilemap_flags[layer] & 0x20)
518    {
519        bitmap_fill(state->tilemap_bitmap[layer], NULL, 0);
520
521        for(int y = 0; y < ysize; y++)
522        {
523            for(int x = 0; x < xsize; x++)
524            {
525                int tile = (supracan_vram[count] & 0x03ff) + tile_bank;
526                bool flipx = (supracan_vram[count] & 0x0800) ? true : false;
527                bool flipy = (supracan_vram[count] & 0x0400) ? true : false;
528                int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank;
529
530                draw_tile(machine, state->tilemap_pri[layer], bitmap, NULL, tile, palette, flipx, flipy, x*8, y*8, priority, region, 0);
531
532                count++;
533            }
534        }
535    }
536    else
537    {
538        bitmap_fill(state->tilemap_bitmap[layer], NULL, 0);
539
540        for(int y = 0; y < ysize; y++)
541        {
542            for(int x = 0; x < xsize; x++)
543            {
544                int tile = (supracan_vram[count] & 0x03ff) + tile_bank;
545                bool flipx = (supracan_vram[count] & 0x0800) ? true : false;
546                bool flipy = (supracan_vram[count] & 0x0400) ? true : false;
547                int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank;
548
549                draw_tile(machine, state->tilemap_pri[layer], bitmap, cliprect, tile, palette, flipx, flipy, x*8/*-scrollx*/, y*8/*-scrolly*/, priority, region, 0);
550
551                count++;
552            }
553        }
554    }
302   SET_TILE_INFO(region, tile, palette, TILE_FLIPXY(flipxy));
555303}
556304
557static void draw_roz_bitmap_scanline(running_machine *machine, bitmap_t *roz_bitmap, UINT16 *scanline, UINT8 *priline, int ypos, INT32 X, INT32 Y, INT32 PA, INT32 PB, INT32 PC, INT32 PD, INT32 *currentx, INT32 *currenty, int changed)
305// I wonder how different this really is.. my guess, not at all.
306static void supracan_tilemap_get_info_roz(running_machine* machine, int layer, tile_data *tileinfo, int count)
558307{
559308    supracan_state *state = machine->driver_data<supracan_state>();
560    //UINT16 *supracan_vram = state->vram;
561    //UINT16 roztbl0 = supracan_vram[(state->roz_unk_base0 >> 1) + ypos];
562   //UINT32 roztbl1 = supracan_vram[(state->roz_unk_base1 >> 1) + ypos*2] << 16;
563    //       roztbl1 |= supracan_vram[(state->roz_unk_base1 >> 1) + ypos*2 + 1];
564   //UINT32 roztbl2 = supracan_vram[(state->roz_unk_base2 >> 1) + ypos*2] << 16;
565    //       roztbl2 |= supracan_vram[(state->roz_unk_base2 >> 1) + ypos*2 + 1];
566    INT32 sx = 0;
567    INT32 sy = 0;
568309
569    //if(state->roz_mode & 0x20 && (roztbl0 == 0 && roztbl1 == 0 && roztbl2 == 0))
570    {
571        //return;
572    }
310   UINT16* supracan_vram = state->vram;
311   
312   UINT32 base = state->roz_base_addr;
573313
574    switch(state->roz_mode & 0x0f00)
314 
315    int region = 1;
316    UINT16 tile_bank = 0;
317    UINT16 palette_bank = 0;
318   
319   region = supracan_tilemap_get_region(machine, layer);
320   
321    switch(state->roz_mode & 3) //FIXME: fix gfx bpp order
575322    {
576        case 0x600: sx = 64*8; sy = 32*8; break;
577        case 0xa00: sx = 128*8; sy = 32*8; break;
578        case 0xc00: sx = 64*8; sy = 64*8; break;
579        default: sx = 32*8; sy = 32*8; break;
580    }
323        case 0:
324         // hack: case for startup logo
325         // this isn't understood properly, it's rendering a single 64x64 tile, which for convenience we've rearranged and decoded as 8x8 for the tilemaps
326           {
327            int tile = 0x880 + ((count & 7)*2);
328         //   tile += (count & 0x070) >> 2;
329           
330            if (count & 0x20) tile ^= 1;
331            tile |= (count & 0xc0)>>2;
332           
333            SET_TILE_INFO(region, tile, 0, 0);
334            return;
335         }
581336
582    if((state->roz_mode & 3) == 0)
583    {
584        sx = 64;
585        sy = 32;
586    }
587337
588    if (X & 0x08000000) X |= 0xf0000000;
589    if (Y & 0x08000000) Y |= 0xf0000000;
590    if (PA & 0x8000) PA |= 0xffff0000;
591    if (PB & 0x8000) PB |= 0xffff0000;
592    if (PC & 0x8000) PC |= 0xffff0000;
593    if (PD & 0x8000) PD |= 0xffff0000;
338        case 1:
339            tile_bank = (state->roz_tile_bank & 0xf000) >> 3;
340            break;
594341
595    // re-assign parameters for convenience's sake
596    INT32 dx = PA;
597    INT32 dmx = PB;//roztbl1;
598    INT32 dy = PC;
599    INT32 dmy = PD;//roztbl2;
600    INT32 startx = X;
601    INT32 starty = Y;
342        case 2:
343            tile_bank = (state->roz_tile_bank & 0xf000) >> 3;
344            break;
602345
603    if(ypos == 0)
604    {
605        changed = 3;
346        case 3:
347            tile_bank = (state->roz_tile_bank & 0xf000) >> 3;
348            break;
606349    }
350   
351   count += base;
352   
353   int tile = (supracan_vram[count] & 0x03ff) + tile_bank;
354   int flipxy = (supracan_vram[count] & 0x0c00)>>10;
355   int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank;
607356
608    if(changed & 1)
609    {
610        *currentx = startx;
611    }
612    else
613    {
614        *currentx += dmx;
615    }
357   SET_TILE_INFO(region, tile, palette, TILE_FLIPXY(flipxy));
358}
616359
617    if(changed & 2)
618    {
619        *currenty = starty;
620    }
621    else
622    {
623        *currenty += dmy;
624    }
625360
626    INT32 rx = *currentx;
627    INT32 ry = *currenty;
628361
629   //printf("%08x\n", ry);
630    INT32 pixx = rx >> 8;
631    INT32 pixy = ry >> 8;
362static TILE_GET_INFO( get_supracan_tilemap0_tile_info )
363{
632364
633    for(int x = 0; x < 320; x++)
634    {
635        if(state->roz_mode & 0x20)
636        {
637            while(pixx < 0) pixx += sx;
638            while(pixy < 0) pixy += sy;
639            while(pixx >= sx) pixx -= sx;
640            while(pixy >= sy) pixy -= sy;
365   supracan_tilemap_get_info_common(machine, 0, tileinfo, tile_index);
366}
641367
642            scanline[x] = *BITMAP_ADDR16(roz_bitmap, pixy, pixx);
643            priline[x] = ((state->roz_mode >> 13) & 7) + 1;
644        }
645        else
646        {
647            if(pixx >= 0 && pixy >= 0 && pixx < sx && pixy < sy)
648            {
649                scanline[x] = *BITMAP_ADDR16(roz_bitmap, pixy, pixx);
650                priline[x] = ((state->roz_mode >> 13) & 7) + 1;
651            }
652        }
368static TILE_GET_INFO( get_supracan_tilemap1_tile_info )
369{
370   supracan_tilemap_get_info_common(machine, 1, tileinfo, tile_index);
371}
653372
654        rx += dx;
655        ry += dy;
373static TILE_GET_INFO( get_supracan_tilemap2_tile_info )
374{
656375
657        pixx = rx >> 8;
658        pixy = ry >> 8;
659    }
660
661    state->roz_changed = 0;
376   supracan_tilemap_get_info_common(machine, 2, tileinfo, tile_index);
662377}
663378
664static void draw_roz_bitmap(running_machine *machine, const rectangle *cliprect)
379static TILE_GET_INFO( get_supracan_roz_tile_info )
665380{
666    supracan_state *state = machine->driver_data<supracan_state>();
667    UINT16 *supracan_vram = state->vram;
668    UINT32 addr = state->roz_tile_bank << 1;
669381
670    const int ysize = 32;
671    bitmap_t *roz_bitmap = state->roz_bitmap;
672    for (int y = 0; y < ysize; y++)
673    {
674        UINT32 plane_word_msw[2];
675        UINT32 plane_word_lsw[2];
676        plane_word_msw[0] = ((UINT32)supracan_vram[addr + (y * 8) + 0] << 16) | supracan_vram[addr + (y * 8) + 1];
677        plane_word_lsw[0] = ((UINT32)supracan_vram[addr + (y * 8) + 2] << 16) | supracan_vram[addr + (y * 8) + 3];
678        plane_word_msw[1] = ((UINT32)supracan_vram[addr + (y * 8) + 4] << 16) | supracan_vram[addr + (y * 8) + 5];
679        plane_word_lsw[1] = ((UINT32)supracan_vram[addr + (y * 8) + 6] << 16) | supracan_vram[addr + (y * 8) + 7];
680        for (int x = 0; x < 32; x++)
681        {
682            UINT8 bit = BIT(plane_word_msw[0], 31-x);// | BIT(plane_word_msw[1], 31-x);
683            if(bit)
684            {
685                *BITMAP_ADDR16(roz_bitmap, y, x) = bit;
686                state->roz_pri[y*1024 + x] = ((state->roz_mode >> 13) & 7) + 1;
687            }
688        }
689        for (int x = 0; x < 32; x++)
690        {
691            UINT8 bit = BIT(plane_word_lsw[0], 31-x);// | BIT(plane_word_lsw[1], 31-x)
692            if(bit)
693            {
694                *BITMAP_ADDR16(roz_bitmap, y, x+32) = bit;
695                state->roz_pri[y*1024 + x + 32] = ((state->roz_mode >> 13) & 7) + 1;
696            }
697        }
698    }
382   supracan_tilemap_get_info_roz(machine, 3, tileinfo, tile_index);
699383}
700384
701static void draw_roz(running_machine *machine, const rectangle *cliprect)
385
386static VIDEO_START( supracan )
702387{
703388    supracan_state *state = machine->driver_data<supracan_state>();
704    UINT16 *supracan_vram = state->vram;
705    UINT32 roz_base_addr = state->roz_base_addr;
706    int region = 0;
707    UINT16 tile_bank = 0;
389    state->sprite_final_bitmap = auto_bitmap_alloc(machine, 1024, 1024, BITMAP_FORMAT_INDEXED16);
390   
391   state->vram = (UINT16*)memory_region(machine,"ram_gfx");
392   state->vram_swapped = (UINT16*)memory_region(machine,"ram_gfx2");
393   state->vram_addr_swapped = (UINT8*)memory_region(machine,"ram_gfx3"); // hack for 1bpp layer at startup
708394
709    switch(state->roz_mode & 3) //FIXME: fix gfx bpp order
710    {
711        case 0:
712            return draw_roz_bitmap(machine, cliprect);
395   state->tilemap_sizes[0][0] = tilemap_create(machine, get_supracan_tilemap0_tile_info, tilemap_scan_rows, 8, 8, 32, 32);
396   state->tilemap_sizes[0][1] = tilemap_create(machine, get_supracan_tilemap0_tile_info, tilemap_scan_rows, 8, 8, 64, 32);
397   state->tilemap_sizes[0][2] = tilemap_create(machine, get_supracan_tilemap0_tile_info, tilemap_scan_rows, 8, 8, 128, 32);
398   state->tilemap_sizes[0][3] = tilemap_create(machine, get_supracan_tilemap0_tile_info, tilemap_scan_rows, 8, 8, 64, 64);
713399
714        case 1:
715            region = 2;
716            tile_bank = (state->roz_tile_bank & 0xf000) >> 3;
717            break;
400   state->tilemap_sizes[1][0] = tilemap_create(machine, get_supracan_tilemap1_tile_info, tilemap_scan_rows, 8, 8, 32, 32);
401   state->tilemap_sizes[1][1] = tilemap_create(machine, get_supracan_tilemap1_tile_info, tilemap_scan_rows, 8, 8, 64, 32);
402   state->tilemap_sizes[1][2] = tilemap_create(machine, get_supracan_tilemap1_tile_info, tilemap_scan_rows, 8, 8, 128, 32);
403   state->tilemap_sizes[1][3] = tilemap_create(machine, get_supracan_tilemap1_tile_info, tilemap_scan_rows, 8, 8, 64, 64);
718404
719        case 2:
720            region = 1;
721            tile_bank = (state->roz_tile_bank & 0xf000) >> 3;
722            break;
405   state->tilemap_sizes[2][0] = tilemap_create(machine, get_supracan_tilemap2_tile_info, tilemap_scan_rows, 8, 8, 32, 32);
406   state->tilemap_sizes[2][1] = tilemap_create(machine, get_supracan_tilemap2_tile_info, tilemap_scan_rows, 8, 8, 64, 32);
407   state->tilemap_sizes[2][2] = tilemap_create(machine, get_supracan_tilemap2_tile_info, tilemap_scan_rows, 8, 8, 128, 32);
408   state->tilemap_sizes[2][3] = tilemap_create(machine, get_supracan_tilemap2_tile_info, tilemap_scan_rows, 8, 8, 64, 64);
723409
724        case 3:
725            region = 0;
726            tile_bank = (state->roz_tile_bank & 0xf000) >> 3;
727            break;
728    }
410   state->tilemap_sizes[3][0] = tilemap_create(machine, get_supracan_roz_tile_info, tilemap_scan_rows, 8, 8, 32, 32);
411   state->tilemap_sizes[3][1] = tilemap_create(machine, get_supracan_roz_tile_info, tilemap_scan_rows, 8, 8, 64, 32);
412   state->tilemap_sizes[3][2] = tilemap_create(machine, get_supracan_roz_tile_info, tilemap_scan_rows, 8, 8, 128, 32);
413   state->tilemap_sizes[3][3] = tilemap_create(machine, get_supracan_roz_tile_info, tilemap_scan_rows, 8, 8, 64, 64);   
414}
729415
730    int xsize = 32;
731    int ysize = 32;
732    switch(state->roz_mode & 0x0f00)
733    {
734        case 0x600:
735            xsize = 64;
736            ysize = 32;
737            break;
416static int get_tilemap_dimensions(running_machine* machine, int &xsize, int &ysize, int layer)
417{
418    supracan_state *state = (supracan_state *)machine->driver_data<supracan_state>();
419   int select;
420   
421   xsize = 32;
422   ysize = 32;
423   
424   if (layer==3) select = (state->roz_mode & 0x0f00);
425   else select = state->tilemap_flags[layer] & 0x0f00;
426   
427   switch(select)
428   {
429      case 0x600:
430         xsize = 64;
431         ysize = 32;
432         return 1;
738433
739        case 0xa00:
740            xsize = 128;
741            ysize = 32;
742            break;
434      case 0xa00:
435         xsize = 128;
436         ysize = 32;
437         return 2;
743438
744        case 0xc00:
745            xsize = 64;
746            ysize = 64;
747            break;
439      case 0xc00:
440         xsize = 64;
441         ysize = 64;
442         return 3;
748443
749        default:
750            xsize = 32;
751            ysize = 32;
752            break;
753    }
444      default:
445         verboselog("maincpu", machine, 0, "Unsupported tilemap size for layer %d: %04x\n", layer, select);
446         return 0;
447   }
448}
754449
755    UINT32 count = 0;
756    UINT8 priority = ((state->roz_mode >> 13) & 7) + 1;
757450
758    bitmap_t *roz_bitmap = state->roz_bitmap;
759    for (int y = 0; y < ysize; y++)
760    {
761        for (int x = 0; x < xsize; x++)
762        {
763            int tile = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x03ff) | tile_bank;
764            bool flipx = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0800) ? true : false;
765            bool flipy = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0400) ? true : false;
766            int palette = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0xf000) >> 12;
767451
768            draw_tile(machine, state->roz_pri, roz_bitmap, NULL, tile, palette, flipx, flipy, x*8, y*8, priority, region, 0);
769452
770            count++;
771        }
772    }
773}
774453
775#define DRAW_DEBUG_SPRITE_PRI \
776   tile = 0; xflip = false; yflip = false; palette = 0; \
777   for(int ypix = 0; ypix < 8; ypix++) \
778      for(int xpix = 0; xpix < 8; xpix++) \
779         if((y + ytile*8 + ypix) < 240 && (y + ytile*8 + ypix) >= 0 && \
780            (x + xtile*8 + xpix) < 320 && (x + xtile*8 + xpix) >= 0) \
781            *BITMAP_ADDR16(bitmap, y + ytile*8 + ypix, x + xtile*8 + xpix) = supracan_vram[i+2] >> 9;
782
783454static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect)
784455{
785456    supracan_state *state = machine->driver_data<supracan_state>();
786457   UINT16 *supracan_vram = state->vram;
787458
788#if !(DRAW_DEBUG_UNK_SPRITE)
789    int region = (state->sprite_flags & 1) ? 0 : 1; //8bpp : 4bpp
790#endif
791
792459//      [0]
793460//      ---h hhh- ---- ---- Y size (not always right)
794461//      ---- ---y yyyy yyyy Y position
r9078r9079
807474   UINT32 skip_count = 0;
808475    UINT32 start_word = (state->sprite_base_addr >> 1) + skip_count * 4;
809476    UINT32 end_word = start_word + (state->sprite_count - skip_count) * 4;
810    for(int i = start_word; i < end_word; i += 4)
477   int region = (state->sprite_flags & 1) ? 0 : 1; //8bpp : 4bpp
478
479   for(int i = start_word; i < end_word; i += 4)
811480   {
812481      int x = supracan_vram[i+2] & 0x01ff;
813482      int y = supracan_vram[i+0] & 0x01ff;
483           
814484      int sprite_offset = supracan_vram[i+3] << 2;
815485      int bank = (supracan_vram[i+1] & 0xf000) >> 12;
816        int mask = (supracan_vram[i+1] & 0x0300) >> 8;
486        //int mask = (supracan_vram[i+1] & 0x0300) >> 8;
817487      bool hflip = (supracan_vram[i+1] & 0x0800) ? true : false;
818488      bool vflip = (supracan_vram[i+1] & 0x0400) ? true : false;
819        int xscale = (supracan_vram[i+2] & 0xf000) >> 12;
820#if !(DRAW_DEBUG_UNK_SPRITE)
821        UINT8 priority = ((supracan_vram[i+0] >> 13) & 7) + 1;
822#endif
489        //int xscale = (supracan_vram[i+2] & 0xf000) >> 12;
490      const gfx_element *gfx = machine->gfx[region];
823491
824      while(x >= 0x200) x -= 0x200;
825      while(y >= 0x200) y -= 0x200;
492      // wraparound
493      if (y>=0x180) y-=0x200;
494      if (x>=0x180) x-=0x200;
826495
827496      if(supracan_vram[i+3] != 0)
828497      {
829498            int xsize = 1 << (supracan_vram[i+1] & 7);
830            //int ysize = ((supracan_vram[i+0] & 0x0700) >> 9) + 1;
831            //ysize += 8 * ((supracan_vram[i+0] & 0x1800) >> 11);
832499            int ysize = ((supracan_vram[i+0] & 0x1e00) >> 9) + 1;
833500
834         // Blit background into working space for final scale
835            bitmap_t *sprite_bitmap = auto_bitmap_alloc(machine, xsize*8, ysize*8, BITMAP_FORMAT_INDEXED16);
836            for(int sy = 0; sy < ysize*8; sy++)
837            {
838                UINT16 *src = BITMAP_ADDR16(bitmap, y + sy, 0);
839                UINT16 *dst = BITMAP_ADDR16(sprite_bitmap, sy, 0);
840                for(int sx = 0; sx < xsize*8; sx++)
841                {
842                    dst[sx] = src[x + sx];
843                }
844            }
845
846501         if(vflip)
847502         {
848503            for(int ytile = (ysize - 1); ytile >= 0; ytile--)
r9078r9079
856511                            bool xflip = (data & 0x0800) ? false : true;
857512                            bool yflip = (data & 0x0400) ? false : true;
858513                            int palette = (data & 0xf000) >> 12;
859
860#if !(DRAW_DEBUG_UNK_SPRITE)
861                            draw_tile(machine, state->sprite_pri, /*bitmap*/sprite_bitmap, cliprect, tile, palette, xflip, yflip, ((xsize - 1) - xtile)*8, ((ysize - 1) - ytile)*8, priority, region, mask, x, y, 0x200, 0x200);
862#else
863                     DRAW_DEBUG_SPRITE_PRI()
864#endif
514                     int xpos = x + ((xsize - 1) - xtile)*8;
515                     int ypos = y + ((ysize - 1) - ytile)*8;
516                     
517                     drawgfx_transpen(bitmap,cliprect,gfx,tile,palette,xflip,yflip,
518                     xpos,
519                     ypos,
520                     0);                 
521                     
865522                  }
866523               }
867524               else
r9078r9079
873530                            bool xflip = (data & 0x0800) ? true : false;
874531                            bool yflip = (data & 0x0400) ? false : true;
875532                            int palette = (data & 0xf000) >> 12;
533                     
534                     int xpos = x + xtile*8;
535                     int ypos = y + ((ysize - 1) - ytile)*8;
876536
877#if !(DRAW_DEBUG_UNK_SPRITE)
878                            draw_tile(machine, state->sprite_pri, /*bitmap*/sprite_bitmap, cliprect, tile, palette, xflip, yflip, xtile*8, ((ysize - 1) - ytile)*8, priority, region, mask, x, y, 0x200, 0x200);
879#else
880                     DRAW_DEBUG_SPRITE_PRI()
881#endif
537                     drawgfx_transpen(bitmap,cliprect,gfx,tile,palette,xflip,yflip,
538                     xpos,
539                     ypos,
540                     0);
882541                  }
883542               }
884543            }
r9078r9079
897556                            bool yflip = (data & 0x0400) ? true : false;
898557                            int palette = (data & 0xf000) >> 12;
899558
900#if !(DRAW_DEBUG_UNK_SPRITE)
901                            draw_tile(machine, state->sprite_pri, /*bitmap*/sprite_bitmap, cliprect, tile, palette, xflip, yflip, ((xsize - 1) - xtile)*8, ytile*8, priority, region, mask, x, y, 0x200, 0x200);
902#else
903                     DRAW_DEBUG_SPRITE_PRI()
904#endif
559                     int xpos = x + ((xsize - 1) - xtile)*8;
560                     int ypos = y + ytile*8;
561
562                     drawgfx_transpen(bitmap,cliprect,gfx,tile,palette,xflip,yflip,
563                     xpos,
564                     ypos,
565                     0);
905566                  }
906567               }
907568               else
r9078r9079
914575                            bool yflip = (data & 0x0400) ? true : false;
915576                            int palette = (data & 0xf000) >> 12;
916577
917#if !(DRAW_DEBUG_UNK_SPRITE)
918                            draw_tile(machine, state->sprite_pri, /*bitmap*/sprite_bitmap, cliprect, tile, palette, xflip, yflip, xtile*8, ytile*8, priority, region, mask, x, y, 0x200, 0x200);
919#else
920                     DRAW_DEBUG_SPRITE_PRI()
921#endif
578                     int xpos = x + xtile*8;
579                     int ypos = y + ytile*8;
580
581                     drawgfx_transpen(bitmap,cliprect,gfx,tile,palette,xflip,yflip,
582                     xpos,
583                     ypos,
584                     0);
585                     
922586                  }
923587               }
924588            }
925589         }
926590
591#if 0
927592            if(xscale == 0) continue;
928593            UINT32 delta = (1 << 17) / xscale;
929594            for(int sy = 0; sy < ysize*8; sy++)
r9078r9079
937602                    dx += delta;
938603                }
939604            }
605#endif         
606         
940607      }
941608   }
942609}
943610
944#if DRAW_DEBUG_ROZ
945static void draw_debug_roz(running_machine *machine, bitmap_t *bitmap)
611
612
613void mark_active_tilemap_all_dirty(running_machine* machine, int layer)
946614{
947    supracan_state *state = machine->driver_data<supracan_state>();
948    UINT16 *supracan_vram = state->vram;
615    supracan_state *state = (supracan_state *)machine->driver_data<supracan_state>();
616   int xsize = 0;
617   int ysize = 0;
618   
619   int which_tilemap_size;
949620
950    for(int y = 0; y < 240; y++)
951    {
952        float x = ((float)supracan_vram[(state->roz_unk_base0 >> 1) + y] / 1024.0f) * 256.0f;
953        *BITMAP_ADDR16(bitmap, y, (int)x) = 0x3fff;
621   which_tilemap_size = get_tilemap_dimensions(machine, xsize, ysize, layer);
622//   for (int i=0;i<4;i++)
623//      tilemap_mark_all_tiles_dirty(state->tilemap_sizes[layer][i]);
624   tilemap_mark_all_tiles_dirty(state->tilemap_sizes[layer][which_tilemap_size]);
625}
954626
955        INT32 temp = supracan_vram[(state->roz_unk_base1 >> 1) + y*2] << 16;
956        temp |= supracan_vram[(state->roz_unk_base1 >> 1) + y*2 + 1];
957        x = ((float)temp / 131072.0f) * 128.0f;
958        if(x >= -160 && x < 160)
959        {
960            *BITMAP_ADDR16(bitmap, y, (int)x + 160) = 0x7fff;
961        }
962        temp = supracan_vram[(state->roz_unk_base2 >> 1) + y*2] << 16;
963        temp |= supracan_vram[(state->roz_unk_base2 >> 1) + y*2 + 1];
964        x = ((float)temp / 131072.0f) * 128.0f;
965        if(x >= -160 && x < 160)
966        {
967            *BITMAP_ADDR16(bitmap, y, (int)x + 160) = 0x5fff;
968        }
969    }
627
628
629/* draws ROZ with linescroll OR columnscroll to 16-bit indexed bitmap */
630static void supracan_suprnova_draw_roz(bitmap_t* bitmap, const rectangle *cliprect, tilemap_t *tmap, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound/*, int columnscroll, UINT32* scrollram*/, int transmask)
631{
632   //bitmap_t *destbitmap = bitmap;
633   bitmap_t *srcbitmap = tilemap_get_pixmap(tmap);
634   //bitmap_t *srcbitmapflags = tilemap_get_flagsmap(tmap);
635   const int xmask = srcbitmap->width-1;
636   const int ymask = srcbitmap->height-1;
637   const int widthshifted = srcbitmap->width << 16;
638   const int heightshifted = srcbitmap->height << 16;
639   UINT32 cx;
640   UINT32 cy;
641   int x;
642   int sx;
643   int sy;
644   int ex;
645   int ey;
646   UINT16 *dest;
647   UINT8* destflags;
648//  UINT8 *pri;
649   //const UINT16 *src;
650   //const UINT8 *maskptr;
651   //int destadvance = destbitmap->bpp / 8;
652
653   /* pre-advance based on the cliprect */
654   startx += cliprect->min_x * incxx + cliprect->min_y * incyx;
655   starty += cliprect->min_x * incxy + cliprect->min_y * incyy;
656
657   /* extract start/end points */
658   sx = cliprect->min_x;
659   sy = cliprect->min_y;
660   ex = cliprect->max_x;
661   ey = cliprect->max_y;
662
663   {
664      /* loop over rows */
665      while (sy <= ey)
666      {
667
668         /* initialize X counters */
669         x = sx;
670         cx = startx;
671         cy = starty;
672
673         /* get dest and priority pointers */
674         dest = BITMAP_ADDR16( bitmap, sy, sx);
675         //destflags = BITMAP_ADDR8( bitmapflags, sy, sx);
676
677         /* loop over columns */
678         while (x <= ex)
679         {
680            if ((wraparound) || (cx < widthshifted && cy < heightshifted)) // not sure how this will cope with no wraparound, but row/col scroll..
681            {
682               #if 0
683               if (columnscroll)
684               {
685                  int scroll = 0;//scrollram[(cx>>16)&0x3ff]);
686                 
687                 
688                  UINT16 data = BITMAP_ADDR16(srcbitmap,
689                                          ((cy >> 16) - scroll) & ymask,
690                                           (cx >> 16) & xmask)[0];
691                                 
692                  if ((data & transmask)!=0)
693                     dest[0] = data;
694                 
695                  //destflags[0] = BITMAP_ADDR8(srcbitmapflags, ((cy >> 16) - scrollram[(cx>>16)&0x3ff]) & ymask, (cx >> 16) & xmask)[0];
696               }
697               else
698               #endif
699               {
700                  int scroll = 0;//scrollram[(cy>>16)&0x3ff]);
701                  UINT16 data =  BITMAP_ADDR16(srcbitmap,
702                                         (cy >> 16) & ymask,
703                                    ((cx >> 16) - scroll) & xmask)[0];
704               
705                 
706                  if ((data & transmask)!=0)
707                     dest[0] = data;
708                 
709                  //destflags[0] = BITMAP_ADDR8(srcbitmapflags, (cy >> 16) & ymask, ((cx >> 16) - scrollram[(cy>>16)&0x3ff]) & xmask)[0];
710               }
711            }
712
713            /* advance in X */
714            cx += incxx;
715            cy += incxy;
716            x++;
717            dest++;
718            destflags++;
719//              pri++;
720         }
721
722         /* advance in Y */
723         startx += incyx;
724         starty += incyy;
725         sy++;
726      }
727   }
970728}
971#endif
972729
730
731// VIDEO FLAGS                  ROZ MODE            TILEMAP FLAGS
732//
733//  Bit                         Bit                 Bit
734// 15-9: Unknown                15-13: Priority?    15-13: Priority?
735//    8: X ht. (256/320)        12: Unknown         12: Unknown
736//    7: Tilemap 0 enable       11-8: Dims          11-8: Dims
737//    6: Tilemap 1 enable       7-6: Unknown        7-6: Unknown
738//    5: Tilemap 2 enable?      5: Wrap             5: Wrap
739//    3: Sprite enable          4-2: Unknown        4-2: Mosaic
740//    2: ROZ enable             1-0: Bit Depth      1-0: Bit Depth
741//  1-0: Unknown
742
743//                      Video Flags                 ROZ Mode                    Tilemap 0   Tilemap 1   Tilemap 2   VF Unk0
744// A'Can logo:          120e: 0001 0010 0000 1110   4020: 0100 0000 0010 0000   4620        ----        ----        0x09
745// Boomzoo Intro:       9a82: 1001 1010 1000 0010   0402: 0000 0100 0000 0010   6400        6400        4400        0x4d
746// Boomzoo Title:       9acc: 1001 1010 1100 1100   0402: 0000 0100 0000 0010   6400        6400        4400        0x4d
747// C.U.G. Intro:        11c8: 0001 0001 1100 1000   0402: 0000 0100 0000 0010   2400        4400        6400        0x08
748// C.U.G. Title:        11cc: 0001 0001 1100 1100   0602: 0000 0110 0000 0010   2600        4600        ----        0x08
749// Speedy Dragon Logo:  0388: 0000 0011 1000 1000   4020: 0100 0000 0010 0000   6c20        6c20        2600        0x01
750// Speedy Dragon Title: 038c: 0000 0011 1000 1100   2603: 0010 0110 0000 0011   6c20        2c20        2600        0x01
751// Sango Fighter Intro: 03c8: 0000 0011 1100 1000   ----: ---- ---- ---- ----   6c20        4620        ----        0x01
752// Sango Fighter Game:  03ce: 0000 0011 1100 1110   0622: 0000 0110 0010 0010   2620        4620        ----        0x01
753
973754static VIDEO_UPDATE( supracan )
974755{
975756    supracan_state *state = (supracan_state *)screen->machine->driver_data<supracan_state>();
976757
977    bitmap_fill(bitmap, cliprect, 0);
978758
979    bitmap_fill(state->sprite_final_bitmap, cliprect, 0);
980    memset(state->sprite_pri, 9, 1024*1024 * sizeof(UINT8));
981759
982    // VIDEO FLAGS                  ROZ MODE            TILEMAP FLAGS
983    //
984    //  Bit                         Bit                 Bit
985    // 15-9: Unknown                15-13: Priority?    15-13: Priority?
986    //    8: X ht. (256/320)        12: Unknown         12: Unknown
987    //    7: Tilemap 0 enable       11-8: Dims          11-8: Dims
988    //    6: Tilemap 1 enable       7-6: Unknown        7-6: Unknown
989    //    5: Tilemap 2 enable?      5: Wrap             5: Wrap
990    //    3: Sprite enable          4-2: Unknown        4-2: Mosaic
991    //    2: ROZ enable             1-0: Bit Depth      1-0: Bit Depth
992    //  1-0: Unknown
760   // treat the sprites as frame-buffered and only update the buffer when drawing scanline 0 - this might not be true!
993761
994    //                      Video Flags                 ROZ Mode                    Tilemap 0   Tilemap 1   Tilemap 2   VF Unk0
995    // A'Can logo:          120e: 0001 0010 0000 1110   4020: 0100 0000 0010 0000   4620        ----        ----        0x09
996    // Boomzoo Intro:       9a82: 1001 1010 1000 0010   0402: 0000 0100 0000 0010   6400        6400        4400        0x4d
997    // Boomzoo Title:       9acc: 1001 1010 1100 1100   0402: 0000 0100 0000 0010   6400        6400        4400        0x4d
998    // C.U.G. Intro:        11c8: 0001 0001 1100 1000   0402: 0000 0100 0000 0010   2400        4400        6400        0x08
999    // C.U.G. Title:        11cc: 0001 0001 1100 1100   0602: 0000 0110 0000 0010   2600        4600        ----        0x08
1000    // Speedy Dragon Logo:  0388: 0000 0011 1000 1000   4020: 0100 0000 0010 0000   6c20        6c20        2600        0x01
1001    // Speedy Dragon Title: 038c: 0000 0011 1000 1100   2603: 0010 0110 0000 0011   6c20        2c20        2600        0x01
1002    // Sango Fighter Intro: 03c8: 0000 0011 1100 1000   ----: ---- ---- ---- ----   6c20        4620        ----        0x01
1003    // Sango Fighter Game:  03ce: 0000 0011 1100 1110   0622: 0000 0110 0010 0010   2620        4620        ----        0x01
762   if (0)
763   {
764      if (cliprect->min_y == 0x00)
765      {
766         const rectangle &visarea = screen->visible_area();
767     
768         bitmap_fill(state->sprite_final_bitmap, &visarea, 0x00);
769         bitmap_fill(bitmap, &visarea, 0x80);
770         
771         draw_sprites(screen->machine, state->sprite_final_bitmap, &visarea);
772         
1004773
1005    if(state->video_flags & 0x08)
1006    {
1007        draw_sprites(screen->machine, state->sprite_final_bitmap, cliprect);
1008    }
774      }
775   }
776   else
777   {
778   
779      bitmap_fill(state->sprite_final_bitmap, cliprect, 0x00);
780      bitmap_fill(bitmap, cliprect, 0x80);
781         
782      draw_sprites(screen->machine, state->sprite_final_bitmap, cliprect);
1009783
1010    for(int y = 0; y < 240; y++)
1011    {
1012        for(int x = 0; x < 320; x++)
1013        {
784   
785   }
786     
1014787
1015#if !(DEBUG_PRIORITY)
1016            /* Harmony 7/27: THIS CODE IS KNOWN TO BE COMPLETELY WRONG.  DO NOT USE IT AS-IS IN A STANDALONE EMULATOR. */
1017            int pri_order[5] = { 0, 0, 0, 0, 0 };
1018            bitmap_t *bitmaps[5] = { state->tilemap_final_bitmap[0], state->tilemap_final_bitmap[1], state->tilemap_final_bitmap[2], state->roz_final_bitmap, state->sprite_final_bitmap };
1019788
1020            pri_order[0] = state->tilemap_final_pri[0][y*320 + x];
1021            pri_order[1] = state->tilemap_final_pri[1][y*320 + x];
1022            pri_order[2] = state->tilemap_final_pri[2][y*320 + x];
1023            pri_order[3] = state->roz_final_pri[y*320 + x];
1024            pri_order[4] = 0;//HACK state->sprite_pri[y*1024 + x];
789   // mix screen
790   int xsize = 0, ysize = 0;
791   bitmap_t *src_bitmap = 0;
792   int tilemap_num;
793   int which_tilemap_size;
794   int priority = 0;
795   
1025796
1026            int current_priority = 9;
1027            for(int index = 0; index < 5; index++)
1028            {
1029                UINT16 pixel = *BITMAP_ADDR16(bitmaps[index], y, x) & 0x7fff;
1030                if(pixel)
1031                {
1032                    if(pri_order[index] < current_priority && pri_order[index] != 9)
1033                    {
1034                        *BITMAP_ADDR16(bitmap, y, x) = pixel;
1035                        current_priority = pri_order[index];
1036                    }
1037                }
1038            }
1039#else
1040            switch(0)
1041            {
1042                case 0:
1043                    *BITMAP_ADDR16(bitmap, y, x) = state->tilemap_pri[0][1024*y + x] + 2;
1044                    break;
1045                case 1:
1046                    *BITMAP_ADDR16(bitmap, y, x) = state->tilemap_pri[1][1024*y + x] + 2;
1047                    break;
1048                case 2:
1049                    *BITMAP_ADDR16(bitmap, y, x) = state->sprite_pri[1024*y + x] + 2;
1050                    break;
1051                case 3:
1052                    *BITMAP_ADDR16(bitmap, y, x) = state->roz_pri[1024*y + x] + 2;
1053                    break;
1054            }
1055#endif
1056        }
1057    }
797   for (int pri=7;pri>=0;pri--)
798   {
1058799
1059#if DRAW_DEBUG_ROZ
1060    draw_debug_roz(screen->machine,bitmap);
1061#endif
800      for (int layer = 3; layer >=0; layer--)
801      {
802      //   popmessage("%04x\n",state->video_flags);
803         int enabled = 0;
804         
805         if(state->video_flags & 0x04)
806            if (layer==3) enabled = 1;
807           
808         if(state->video_flags & 0x80)
809            if (layer==0) enabled = 1;
1062810
811         if(state->video_flags & 0x40)
812            if (layer==1) enabled = 1;
813
814         if(state->video_flags & 0x20)
815            if (layer==2) enabled = 1;
816         
817     
818         if (layer==3) priority = ((state->roz_mode >> 13) & 7); // roz case
819         else priority = ((state->tilemap_flags[layer] >> 13) & 7); // normal cases
820         
821         
822         if (priority==pri)
823         {
824            tilemap_num = layer;
825            which_tilemap_size = get_tilemap_dimensions(screen->machine, xsize, ysize, layer);
826            src_bitmap = tilemap_get_pixmap(state->tilemap_sizes[layer][which_tilemap_size]);           
827            int gfx_region = supracan_tilemap_get_region(screen->machine, layer);
828            int transmask = 0xff;
829                       
830            switch (gfx_region)
831            {
832               case 0:transmask = 0xff; break;
833               case 1:transmask = 0x0f; break;
834               case 2:transmask = 0x03; break;
835               case 3:transmask = 0x01; break;
836               case 4:transmask = 0x01; break;   
837            }
838         
839            if (enabled)
840            {
841               if (layer != 3) // standard layers, NOT roz
842               {
843               
844                  int wrap = (state->tilemap_flags[layer] & 0x20);
845               
846                  int scrollx = state->tilemap_scrollx[layer];
847                  int scrolly = state->tilemap_scrolly[layer];
848               
849                  if (scrollx&0x8000) scrollx-= 0x10000;
850                  if (scrolly&0x8000) scrolly-= 0x10000;
851               
852                  int y,x;
853                  // yes, it will draw a single line if you specify a cliprect as such (partial updates...)
854                 
855                  for (y=cliprect->min_y;y<=cliprect->max_y;y++)
856                  {   
857                     // these will have to change to ADDR32 etc. once alpha blending is supported
858                     UINT16* screen = BITMAP_ADDR16(bitmap, y, 0);
859                     
860                     int realy = y+scrolly;
861                                         
862                     if (!wrap)
863                        if (scrolly+y < 0 || scrolly+y > ((ysize*8)-1))
864                           continue;
865
866                     
867                     UINT16* src = BITMAP_ADDR16(src_bitmap, (realy)&((ysize*8)-1), 0);
868                     
869                     for (x=cliprect->min_x;x<=cliprect->max_x;x++)
870                     {
871                        int realx = x+scrollx;
872                       
873                        if (!wrap)
874                           if (scrollx+x < 0 || scrollx+x > ((xsize*8)-1))
875                              continue;
876                       
877                        UINT16 srcpix = src[(realx)&((xsize*8)-1)];
878                       
879                        if ((srcpix & transmask) != 0)
880                           screen[x] = srcpix;                 
881                     }   
882                  }
883               }
884               else
885               {
886                  int wrap = state->roz_mode & 0x20;
887                 
888                  int incxx = (state->roz_coeffa);
889                  int incyy = (state->roz_coeffd);
890                 
891                  int incxy = (state->roz_coeffc);
892                  int incyx = (state->roz_coeffb);
893                 
894                  if (incyx & 0x8000) incyx -= 0x10000;
895                  if (incxy & 0x8000) incxy -= 0x10000;
896                 
897                  if (incyy & 0x8000) incyy -= 0x10000;
898                  if (incxx & 0x8000) incxx -= 0x10000;
899
900                 
901                  supracan_suprnova_draw_roz(bitmap, cliprect, state->tilemap_sizes[layer][which_tilemap_size], (state->roz_scrollx)<<8, (state->roz_scrolly)<<8, incxx<<8, incxy<<8, incyx<<8, incyy<<8, wrap, transmask);
902               }
903            }
904         }
905      }   
906   }
907
908
909   // just draw the sprites on top for now
910   if(state->video_flags & 0x08)
911   {
912      for (int y=cliprect->min_y;y<=cliprect->max_y;y++)
913      {
914         UINT16* src = BITMAP_ADDR16( state->sprite_final_bitmap, y, 0);
915         UINT16* dst = BITMAP_ADDR16( bitmap, y, 0);
916     
917         for (int x=cliprect->min_x;x<=cliprect->max_x;x++)
918         {
919            UINT16 dat = src[x];
920            if (dat) dst[x] = dat;     
921         }
922      }
923   }
924   
1063925   return 0;
1064926}
1065927
r9078r9079
11501012}
11511013*/
11521014
1015// swap address around so that 64x64 tile can be decoded as 8x8 tiles..
1016void write_swapped_byte(running_machine* machine, int offset, UINT8 byte )
1017{
1018    supracan_state *state = (supracan_state *)machine->driver_data<supracan_state>();
1019   int swapped_offset = BITSWAP32(offset, 31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,2,1,0,6,5,4,3);
1020
1021   state->vram_addr_swapped[swapped_offset] = byte;
1022}
1023
1024
1025static READ16_HANDLER( supracan_vram_r )
1026{
1027    supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>();
1028   return state->vram[offset];
1029}
1030
1031
1032static WRITE16_HANDLER( supracan_vram_w )
1033{
1034    supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>();
1035   COMBINE_DATA(&state->vram[offset]);
1036
1037   // store a byteswapped vesrion for easier gfx-decode
1038   data = state->vram[offset];
1039   data = ((data & 0x00ff)<<8) | ((data & 0xff00)>>8);
1040   state->vram_swapped[offset] = data;
1041
1042   // hack for 1bpp layer at startup
1043   write_swapped_byte(space->machine, offset*2+1, (data & 0xff00)>>8);
1044   write_swapped_byte(space->machine, offset*2, (data & 0x00ff));
1045   
1046   // mark tiles of each depth as dirty
1047   gfx_element_mark_dirty(space->machine->gfx[0], (offset*2)/(64));
1048   gfx_element_mark_dirty(space->machine->gfx[1], (offset*2)/(32));
1049   gfx_element_mark_dirty(space->machine->gfx[2], (offset*2)/(16));
1050   gfx_element_mark_dirty(space->machine->gfx[3], (offset*2)/(512));
1051   gfx_element_mark_dirty(space->machine->gfx[4], (offset*2)/(8));
1052
1053}
1054
1055
11531056static ADDRESS_MAP_START( supracan_mem, ADDRESS_SPACE_PROGRAM, 16 )
11541057   AM_RANGE( 0x000000, 0x3fffff ) AM_ROM AM_REGION( "cart", 0 )
11551058   AM_RANGE( 0xe80200, 0xe80201 ) AM_READ_PORT("P1")
r9078r9079
11611064   AM_RANGE( 0xe90020, 0xe9003f ) AM_WRITE( supracan_dma_w )
11621065   AM_RANGE( 0xf00000, 0xf001ff ) AM_READWRITE( supracan_video_r, supracan_video_w )
11631066    AM_RANGE( 0xf00200, 0xf003ff ) AM_RAM_WRITE(paletteram16_xBBBBBGGGGGRRRRR_word_w) AM_BASE_GENERIC(paletteram)
1164   AM_RANGE( 0xf40000, 0xf5ffff ) AM_RAM AM_BASE_MEMBER(supracan_state,vram)
1067   AM_RANGE( 0xf40000, 0xf5ffff ) AM_READWRITE(supracan_vram_r, supracan_vram_w)
11651068   AM_RANGE( 0xfc0000, 0xfdffff ) AM_MIRROR(0x30000) AM_RAM /* System work ram */
11661069ADDRESS_MAP_END
11671070
r9078r9079
15701473   {
15711474   case 0:
15721475      state->video_regs[0] &= 0x7fff;
1476     
1477      // we really need better management of this
1478      mark_active_tilemap_all_dirty(machine, 0);
1479      mark_active_tilemap_all_dirty(machine, 1);
1480      mark_active_tilemap_all_dirty(machine, 2);
1481      mark_active_tilemap_all_dirty(machine, 3);
1482
1483     
15731484      break;
15741485   case 240:
15751486      state->video_regs[0] |= 0x8000;
r9078r9079
15831494
15841495    state->video_regs[1] = machine->primary_screen->vpos();
15851496
1586    if (vpos == 0)
1587    {
1588        bitmap_fill(state->roz_final_bitmap, NULL, 0);
1589        bitmap_fill(state->roz_bitmap, NULL, 0);
1590        bitmap_fill(state->tilemap_bitmap[0], NULL, 0);
1591        bitmap_fill(state->tilemap_bitmap[1], NULL, 0);
1592        bitmap_fill(state->tilemap_bitmap[2], NULL, 0);
1593        bitmap_fill(state->tilemap_final_bitmap[0], NULL, 0);
1594        bitmap_fill(state->tilemap_final_bitmap[1], NULL, 0);
1595        bitmap_fill(state->tilemap_final_bitmap[2], NULL, 0);
1596        memset(state->roz_pri, 9, 1024*1024 * sizeof(UINT8) );
1597        memset(state->tilemap_pri[0], 9, 1024*1024 * sizeof(UINT8));
1598        memset(state->tilemap_pri[1], 9, 1024*1024 * sizeof(UINT8));
1599        memset(state->tilemap_pri[2], 9, 1024*1024 * sizeof(UINT8));
1600        memset(state->tilemap_final_pri[0], 9, 320*240 * sizeof(UINT8));
1601        memset(state->tilemap_final_pri[1], 9, 320*240 * sizeof(UINT8));
1602        memset(state->tilemap_final_pri[2], 9, 320*240 * sizeof(UINT8));
1603        if(state->video_flags & 4)
1604        {
1605            draw_roz(machine, &machine->primary_screen->visible_area());
1606        }
1607
1608        if(state->video_flags & 0x80)
1609        {
1610            draw_tilemap(machine, state->tilemap_bitmap[0], &machine->primary_screen->visible_area(), 0);
1611        }
1612
1613        if(state->video_flags & 0x40)
1614        {
1615              draw_tilemap(machine, state->tilemap_bitmap[1], &machine->primary_screen->visible_area(), 1);
1616        }
1617
1618        if(state->video_flags & 0x20)
1619        {
1620            // Causes issues in Speedy Dragon; investigate later
1621            draw_tilemap(machine, state->tilemap_bitmap[2], &machine->primary_screen->visible_area(), 2);
1622        }
1623    }
1624
1625    if (vpos < 240)
1626    {
1627        UINT16 *scandata = BITMAP_ADDR16(state->roz_final_bitmap, vpos, 0);
1628        UINT8 *pridata = &state->roz_final_pri[vpos*320];
1629        if(state->video_flags & 4)
1630        {
1631            draw_roz_bitmap_scanline(machine, state->roz_bitmap, scandata, pridata, vpos, state->roz_scrollx, state->roz_scrolly, state->roz_coeffa, state->roz_coeffb, state->roz_coeffc, state->roz_coeffd, &state->roz_cx, &state->roz_cy, state->roz_changed);
1632        }
1633
1634        for(int index = 0; index < 3; index++)
1635        {
1636            if(index == 2)
1637            {
1638                // Tilemap 2 causes issues in Speedy Dragon; investigate later
1639                //break;
1640            }
1641            if(state->video_flags & (0x80 >> index) )
1642            {
1643                scandata = BITMAP_ADDR16(state->tilemap_final_bitmap[index], vpos, 0);
1644                pridata = &state->tilemap_final_pri[index][vpos*320];
1645                draw_tilemap_scanline(machine, scandata, pridata, vpos, index);
1646            }
1647        }
1648    }
1649
16501497    timer_adjust_oneshot( state->hbl_timer, machine->primary_screen->time_until_pos( vpos, 320 ), 0 );
16511498    timer_adjust_oneshot( state->video_timer, machine->primary_screen->time_until_pos( ( vpos + 1 ) % 256, 0 ), 0 );
16521499}
r9078r9079
16571504   acan_sprdma_regs_t *acan_sprdma_regs = &state->acan_sprdma_regs;
16581505   int i;
16591506
1507   // if any of this changes we need a partial update (see sango fighters intro)
1508   space->machine->primary_screen->update_partial(space->machine->primary_screen->vpos());
1509
16601510   switch(offset)
16611511   {
16621512        case 0x10/2: // Byte count
r9078r9079
17431593         break;
17441594        case 0x0a/2:
17451595            {
1596            // raster interrupt
17461597                verboselog("maincpu", space->machine, 0, "IRQ Trigger? = %04x\n", data);
17471598                if(data & 0x8000)
17481599                {
1749                    timer_adjust_oneshot(state->line_on_timer, space->machine->primary_screen->time_until_pos(data & 0x00ff, 0), 0);
1600                    timer_adjust_oneshot(state->line_on_timer, space->machine->primary_screen->time_until_pos((data & 0x00ff), 0), 0);
17501601                }
17511602                else
17521603                {
r9078r9079
18131664
18141665        case 0x1d0/2: state->unk_1d0 = data; verboselog("maincpu", space->machine, 3, "unk_1d0 = %04x\n", data); break;
18151666
1667
1668
1669
18161670      case 0x1f0/2: //FIXME: this register is mostly not understood
18171671         state->irq_mask = data;//(data & 8) ? 0 : 1;
18181672            /*
r9078r9079
18841738}
18851739
18861740/* gfxdecode is retained for reference purposes but not otherwise used by the driver */
1887#ifdef UNUSED_CODE
18881741static const gfx_layout supracan_gfx8bpp =
18891742{
18901743   8,8,
18911744   RGN_FRAC(1,1),
18921745   8,
1893   { STEP8(0,1) },
1894   { STEP8(0,8) },
1746   { 0,1,2,3,4,5,6,7 },
1747   { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
18951748   { STEP8(0,8*8) },
18961749   8*8*8
18971750};
18981751
1752
1753
18991754static const gfx_layout supracan_gfx4bpp =
19001755{
19011756   8,8,
r9078r9079
19181773   8*16
19191774};
19201775
1776
1777static const UINT32 xtexlayout_xoffset[64] = { 0,1,2,3,4,5,6,7,          8,9,10,11,12,13,14,15,
1778                                               16,17,18,19,20,21,22,23,  24,25,26,27,28,29,30,31,
1779                                    32,33,34,35,36,37,38,39,  40,41,42,43,44,45,46,47,
1780                                    48,49,50,51,52,53,54,55,  56,57,58,59,60,61,62,63 };
1781static const UINT32 xtexlayout_yoffset[64] = {  0*64,1*64,2*64,3*64,4*64,5*64,6*64,7*64,
1782                                                8*64,9*64,10*64,11*64,12*64,13*64,14*64,15*64,
1783                                    16*64,17*64,18*64,19*64,20*64,21*64,22*64,23*64,
1784                                    24*64,25*64,26*64,27*64,28*64,29*64,30*64,31*64,
1785                                    32*64,33*64,34*64,35*64,36*64,37*64,38*64,39*64,
1786                                    40*64,41*64,42*64,43*64,44*64,45*64,46*64,47*64,
1787                                    48*64,49*64,50*64,51*64,52*64,53*64,54*64,55*64,
1788                                    56*64,57*64,58*64,59*64,60*64,61*64,62*64,63*64 };
1789static const gfx_layout supracan_gfx1bpp =
1790{
1791   64,64,
1792   RGN_FRAC(1,1),
1793   1,
1794   { 0 },
1795   EXTENDED_XOFFS,
1796   EXTENDED_YOFFS,
1797   64*64,
1798   xtexlayout_xoffset,
1799   xtexlayout_yoffset
1800};
1801
1802static const gfx_layout supracan_gfx1bpp_alt =
1803{
1804   8,8,
1805   RGN_FRAC(1,1),
1806   1,
1807   { 0 },
1808   { 0,1,2,3,4,5,6,7 },
1809   { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
1810   8*8
1811};
1812
1813
19211814static GFXDECODE_START( supracan )
1922   GFXDECODE_ENTRY( "ram_gfx",  0, supracan_gfx8bpp,   0, 1 )
1923   GFXDECODE_ENTRY( "ram_gfx",  0, supracan_gfx4bpp,   0, 0x10 )
1924   GFXDECODE_ENTRY( "ram_gfx",  0, supracan_gfx2bpp,   0, 0x40 )
1815   GFXDECODE_ENTRY( "ram_gfx2",  0, supracan_gfx8bpp,   0, 1 )
1816   GFXDECODE_ENTRY( "ram_gfx2",  0, supracan_gfx4bpp,   0, 0x10 )
1817   GFXDECODE_ENTRY( "ram_gfx2",  0, supracan_gfx2bpp,   0, 0x40 )
1818   GFXDECODE_ENTRY( "ram_gfx2",  0, supracan_gfx1bpp,   0, 0x80 )
1819   GFXDECODE_ENTRY( "ram_gfx3",  0, supracan_gfx1bpp_alt,   0, 0x80 )
19251820GFXDECODE_END
1926#endif
19271821
19281822static INTERRUPT_GEN( supracan_irq )
19291823{
r9078r9079
19791873   MDRV_PALETTE_LENGTH( 32768 )
19801874   MDRV_PALETTE_INIT( supracan )
19811875
1876   MDRV_GFXDECODE(supracan)
1877
1878
19821879   MDRV_CARTSLOT_ADD("cart")
19831880   MDRV_CARTSLOT_EXTENSION_LIST("bin")
19841881   MDRV_CARTSLOT_MANDATORY
r9078r9079
19961893   ROM_REGION( 0x400000, "cart", ROMREGION_ERASEFF )
19971894
19981895   ROM_REGION( 0x20000, "ram_gfx", ROMREGION_ERASEFF )
1896   ROM_REGION( 0x20000, "ram_gfx2", ROMREGION_ERASEFF )
1897   ROM_REGION( 0x20000, "ram_gfx3", ROMREGION_ERASEFF )
1898
19991899ROM_END
20001900
20011901

Previous 15994 Revisions Next


© 1998-2018 The MESS Team