src/mess/drivers/supracan.c
| r9078 | r9079 | |
| 47 | 47 | - All: Priorities are largely unknown. |
| 48 | 48 | - C.U.G.: Gameplay backgrounds are broken. |
| 49 | 49 | - Sango Fighter: Possible missing masking on the upper edges of the screen during gameplay. |
| 50 | - Sango Fighter: Raster effects off by 1 line |
| 50 | 51 | - Speedy Dragon: Backgrounds are broken (wrong tile bank/region). |
| 51 | 52 | - Super Taiwanese Baseball League: Does not boot for unknown reasons. |
| 52 | 53 | - Super Taiwanese Baseball League: Missing window effect applied on tilemaps? |
| 53 | 54 | - The Son of Evil: Does not boot for unknown reasons. |
| 54 | 55 | - The Son of Evil: Many graphical issues. |
| 56 | |
| 57 | - All: are ALL the layers ROZ capable?? |
| 55 | 58 | |
| 56 | 59 | DEBUG TRICKS: |
| 57 | 60 | |
| r9078 | r9079 | |
| 130 | 133 | emu_timer *line_on_timer; |
| 131 | 134 | emu_timer *line_off_timer; |
| 132 | 135 | UINT16 *vram; |
| 136 | UINT16 *vram_swapped; |
| 137 | UINT8 *vram_addr_swapped; |
| 138 | |
| 133 | 139 | UINT16 *pram; |
| 134 | 140 | |
| 135 | | bitmap_t *sprite_final_bitmap; |
| 136 | | UINT8 sprite_pri[1024*1024]; |
| 137 | 141 | UINT16 sprite_count; |
| 138 | 142 | UINT32 sprite_base_addr; |
| 139 | 143 | UINT8 sprite_flags; |
| 140 | 144 | |
| 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]; |
| 146 | 146 | int tilemap_scrollx[3]; |
| 147 | 147 | int tilemap_scrolly[3]; |
| 148 | 148 | UINT16 video_flags; |
| r9078 | r9079 | |
| 151 | 151 | UINT16 irq_mask; |
| 152 | 152 | UINT16 hbl_mask; |
| 153 | 153 | |
| 154 | | bitmap_t *roz_bitmap; |
| 155 | | bitmap_t *roz_final_bitmap; |
| 156 | | UINT8 roz_pri[1024*1024]; |
| 157 | | UINT8 roz_final_pri[320*240]; |
| 158 | 154 | UINT32 roz_base_addr; |
| 159 | 155 | UINT16 roz_mode; |
| 160 | 156 | UINT32 roz_scrollx; |
| r9078 | r9079 | |
| 175 | 171 | UINT16 video_regs[256]; |
| 176 | 172 | |
| 177 | 173 | bool hack_68k_to_6502_access; |
| 174 | |
| 175 | tilemap_t *tilemap_sizes[4][4]; |
| 176 | bitmap_t *sprite_final_bitmap; |
| 177 | |
| 178 | |
| 179 | |
| 178 | 180 | }; |
| 179 | 181 | |
| 180 | 182 | static READ16_HANDLER( supracan_68k_soundram_r ); |
| r9078 | r9079 | |
| 202 | 204 | #define verboselog(w,x,y,z,...) |
| 203 | 205 | #endif |
| 204 | 206 | |
| 205 | | static VIDEO_START( supracan ) |
| 207 | int supracan_tilemap_get_region(running_machine* machine, int layer) |
| 206 | 208 | { |
| 207 | 209 | 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 | | } |
| 218 | 210 | |
| 219 | | static 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 |
| 223 | 221 | |
| 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; |
| 226 | 237 | |
| 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 | } |
| 229 | 248 | |
| 230 | | return (supracan_vram[address] >> shift) & 0x00ff; |
| 231 | 249 | } |
| 232 | 250 | |
| 233 | | static UINT16 fetch_4bpp_tile_pixel(running_machine *machine, int tile, int palette, bool xflip, bool yflip, int x, int y) |
| 251 | static void supracan_tilemap_get_info_common(running_machine* machine, int layer, tile_data *tileinfo, int count) |
| 234 | 252 | { |
| 235 | 253 | supracan_state *state = machine->driver_data<supracan_state>(); |
| 236 | | UINT16 *supracan_vram = state->vram; |
| 237 | 254 | |
| 238 | | if(xflip) x = 7 - x; |
| 239 | | if(yflip) y = 7 - y; |
| 255 | UINT16* supracan_vram = state->vram; |
| 240 | 256 | |
| 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 | | |
| 247 | | static 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 | | |
| 261 | | static 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 | | |
| 334 | | static 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 | | |
| 436 | | static 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]); |
| 475 | 258 | int gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12; |
| 259 | int region = supracan_tilemap_get_region(machine, layer); |
| 476 | 260 | |
| 477 | | int region = 1; |
| 261 | count += base; |
| 262 | |
| 478 | 263 | UINT16 tile_bank = 0; |
| 479 | 264 | UINT16 palette_bank = 0; |
| 480 | 265 | switch(gfx_mode) |
| 481 | 266 | { |
| 482 | 267 | case 7: |
| 483 | | region = 2; |
| 484 | 268 | tile_bank = 0x1c00; |
| 485 | 269 | palette_bank = 0x00; |
| 486 | 270 | break; |
| 487 | 271 | |
| 488 | 272 | case 4: |
| 489 | | region = 1; |
| 490 | 273 | tile_bank = 0x800; |
| 491 | 274 | palette_bank = 0x00; |
| 492 | 275 | break; |
| 493 | 276 | |
| 494 | 277 | case 2: |
| 495 | | region = 1; |
| 496 | 278 | tile_bank = 0x400; |
| 497 | 279 | palette_bank = 0x00; |
| 498 | 280 | break; |
| 499 | 281 | |
| 500 | 282 | case 0: |
| 501 | | region = 1; |
| 502 | 283 | tile_bank = 0; |
| 503 | 284 | palette_bank = 0x00; |
| 504 | 285 | break; |
| r9078 | r9079 | |
| 508 | 289 | break; |
| 509 | 290 | } |
| 510 | 291 | |
| 292 | |
| 511 | 293 | if(layer == 2) |
| 512 | 294 | { |
| 513 | | region = 2; |
| 514 | 295 | tile_bank = 0x1000; |
| 515 | 296 | } |
| 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; |
| 516 | 301 | |
| 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)); |
| 555 | 303 | } |
| 556 | 304 | |
| 557 | | static 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. |
| 306 | static void supracan_tilemap_get_info_roz(running_machine* machine, int layer, tile_data *tileinfo, int count) |
| 558 | 307 | { |
| 559 | 308 | 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; |
| 568 | 309 | |
| 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; |
| 573 | 313 | |
| 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 |
| 575 | 322 | { |
| 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 | } |
| 581 | 336 | |
| 582 | | if((state->roz_mode & 3) == 0) |
| 583 | | { |
| 584 | | sx = 64; |
| 585 | | sy = 32; |
| 586 | | } |
| 587 | 337 | |
| 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; |
| 594 | 341 | |
| 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; |
| 602 | 345 | |
| 603 | | if(ypos == 0) |
| 604 | | { |
| 605 | | changed = 3; |
| 346 | case 3: |
| 347 | tile_bank = (state->roz_tile_bank & 0xf000) >> 3; |
| 348 | break; |
| 606 | 349 | } |
| 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; |
| 607 | 356 | |
| 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 | } |
| 616 | 359 | |
| 617 | | if(changed & 2) |
| 618 | | { |
| 619 | | *currenty = starty; |
| 620 | | } |
| 621 | | else |
| 622 | | { |
| 623 | | *currenty += dmy; |
| 624 | | } |
| 625 | 360 | |
| 626 | | INT32 rx = *currentx; |
| 627 | | INT32 ry = *currenty; |
| 628 | 361 | |
| 629 | | //printf("%08x\n", ry); |
| 630 | | INT32 pixx = rx >> 8; |
| 631 | | INT32 pixy = ry >> 8; |
| 362 | static TILE_GET_INFO( get_supracan_tilemap0_tile_info ) |
| 363 | { |
| 632 | 364 | |
| 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 | } |
| 641 | 367 | |
| 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 | | } |
| 368 | static TILE_GET_INFO( get_supracan_tilemap1_tile_info ) |
| 369 | { |
| 370 | supracan_tilemap_get_info_common(machine, 1, tileinfo, tile_index); |
| 371 | } |
| 653 | 372 | |
| 654 | | rx += dx; |
| 655 | | ry += dy; |
| 373 | static TILE_GET_INFO( get_supracan_tilemap2_tile_info ) |
| 374 | { |
| 656 | 375 | |
| 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); |
| 662 | 377 | } |
| 663 | 378 | |
| 664 | | static void draw_roz_bitmap(running_machine *machine, const rectangle *cliprect) |
| 379 | static TILE_GET_INFO( get_supracan_roz_tile_info ) |
| 665 | 380 | { |
| 666 | | supracan_state *state = machine->driver_data<supracan_state>(); |
| 667 | | UINT16 *supracan_vram = state->vram; |
| 668 | | UINT32 addr = state->roz_tile_bank << 1; |
| 669 | 381 | |
| 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); |
| 699 | 383 | } |
| 700 | 384 | |
| 701 | | static void draw_roz(running_machine *machine, const rectangle *cliprect) |
| 385 | |
| 386 | static VIDEO_START( supracan ) |
| 702 | 387 | { |
| 703 | 388 | 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 |
| 708 | 394 | |
| 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); |
| 713 | 399 | |
| 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); |
| 718 | 404 | |
| 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); |
| 723 | 409 | |
| 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 | } |
| 729 | 415 | |
| 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; |
| 416 | static 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; |
| 738 | 433 | |
| 739 | | case 0xa00: |
| 740 | | xsize = 128; |
| 741 | | ysize = 32; |
| 742 | | break; |
| 434 | case 0xa00: |
| 435 | xsize = 128; |
| 436 | ysize = 32; |
| 437 | return 2; |
| 743 | 438 | |
| 744 | | case 0xc00: |
| 745 | | xsize = 64; |
| 746 | | ysize = 64; |
| 747 | | break; |
| 439 | case 0xc00: |
| 440 | xsize = 64; |
| 441 | ysize = 64; |
| 442 | return 3; |
| 748 | 443 | |
| 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 | } |
| 754 | 449 | |
| 755 | | UINT32 count = 0; |
| 756 | | UINT8 priority = ((state->roz_mode >> 13) & 7) + 1; |
| 757 | 450 | |
| 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; |
| 767 | 451 | |
| 768 | | draw_tile(machine, state->roz_pri, roz_bitmap, NULL, tile, palette, flipx, flipy, x*8, y*8, priority, region, 0); |
| 769 | 452 | |
| 770 | | count++; |
| 771 | | } |
| 772 | | } |
| 773 | | } |
| 774 | 453 | |
| 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 | | |
| 783 | 454 | static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect) |
| 784 | 455 | { |
| 785 | 456 | supracan_state *state = machine->driver_data<supracan_state>(); |
| 786 | 457 | UINT16 *supracan_vram = state->vram; |
| 787 | 458 | |
| 788 | | #if !(DRAW_DEBUG_UNK_SPRITE) |
| 789 | | int region = (state->sprite_flags & 1) ? 0 : 1; //8bpp : 4bpp |
| 790 | | #endif |
| 791 | | |
| 792 | 459 | // [0] |
| 793 | 460 | // ---h hhh- ---- ---- Y size (not always right) |
| 794 | 461 | // ---- ---y yyyy yyyy Y position |
| r9078 | r9079 | |
| 807 | 474 | UINT32 skip_count = 0; |
| 808 | 475 | UINT32 start_word = (state->sprite_base_addr >> 1) + skip_count * 4; |
| 809 | 476 | 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) |
| 811 | 480 | { |
| 812 | 481 | int x = supracan_vram[i+2] & 0x01ff; |
| 813 | 482 | int y = supracan_vram[i+0] & 0x01ff; |
| 483 | |
| 814 | 484 | int sprite_offset = supracan_vram[i+3] << 2; |
| 815 | 485 | 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; |
| 817 | 487 | bool hflip = (supracan_vram[i+1] & 0x0800) ? true : false; |
| 818 | 488 | 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]; |
| 823 | 491 | |
| 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; |
| 826 | 495 | |
| 827 | 496 | if(supracan_vram[i+3] != 0) |
| 828 | 497 | { |
| 829 | 498 | 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); |
| 832 | 499 | int ysize = ((supracan_vram[i+0] & 0x1e00) >> 9) + 1; |
| 833 | 500 | |
| 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 | | |
| 846 | 501 | if(vflip) |
| 847 | 502 | { |
| 848 | 503 | for(int ytile = (ysize - 1); ytile >= 0; ytile--) |
| r9078 | r9079 | |
| 856 | 511 | bool xflip = (data & 0x0800) ? false : true; |
| 857 | 512 | bool yflip = (data & 0x0400) ? false : true; |
| 858 | 513 | 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 | |
| 865 | 522 | } |
| 866 | 523 | } |
| 867 | 524 | else |
| r9078 | r9079 | |
| 873 | 530 | bool xflip = (data & 0x0800) ? true : false; |
| 874 | 531 | bool yflip = (data & 0x0400) ? false : true; |
| 875 | 532 | int palette = (data & 0xf000) >> 12; |
| 533 | |
| 534 | int xpos = x + xtile*8; |
| 535 | int ypos = y + ((ysize - 1) - ytile)*8; |
| 876 | 536 | |
| 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); |
| 882 | 541 | } |
| 883 | 542 | } |
| 884 | 543 | } |
| r9078 | r9079 | |
| 897 | 556 | bool yflip = (data & 0x0400) ? true : false; |
| 898 | 557 | int palette = (data & 0xf000) >> 12; |
| 899 | 558 | |
| 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); |
| 905 | 566 | } |
| 906 | 567 | } |
| 907 | 568 | else |
| r9078 | r9079 | |
| 914 | 575 | bool yflip = (data & 0x0400) ? true : false; |
| 915 | 576 | int palette = (data & 0xf000) >> 12; |
| 916 | 577 | |
| 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 | |
| 922 | 586 | } |
| 923 | 587 | } |
| 924 | 588 | } |
| 925 | 589 | } |
| 926 | 590 | |
| 591 | #if 0 |
| 927 | 592 | if(xscale == 0) continue; |
| 928 | 593 | UINT32 delta = (1 << 17) / xscale; |
| 929 | 594 | for(int sy = 0; sy < ysize*8; sy++) |
| r9078 | r9079 | |
| 937 | 602 | dx += delta; |
| 938 | 603 | } |
| 939 | 604 | } |
| 605 | #endif |
| 606 | |
| 940 | 607 | } |
| 941 | 608 | } |
| 942 | 609 | } |
| 943 | 610 | |
| 944 | | #if DRAW_DEBUG_ROZ |
| 945 | | static void draw_debug_roz(running_machine *machine, bitmap_t *bitmap) |
| 611 | |
| 612 | |
| 613 | void mark_active_tilemap_all_dirty(running_machine* machine, int layer) |
| 946 | 614 | { |
| 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; |
| 949 | 620 | |
| 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 | } |
| 954 | 626 | |
| 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 */ |
| 630 | static 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 | } |
| 970 | 728 | } |
| 971 | | #endif |
| 972 | 729 | |
| 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 | |
| 973 | 754 | static VIDEO_UPDATE( supracan ) |
| 974 | 755 | { |
| 975 | 756 | supracan_state *state = (supracan_state *)screen->machine->driver_data<supracan_state>(); |
| 976 | 757 | |
| 977 | | bitmap_fill(bitmap, cliprect, 0); |
| 978 | 758 | |
| 979 | | bitmap_fill(state->sprite_final_bitmap, cliprect, 0); |
| 980 | | memset(state->sprite_pri, 9, 1024*1024 * sizeof(UINT8)); |
| 981 | 759 | |
| 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! |
| 993 | 761 | |
| 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 | |
| 1004 | 773 | |
| 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); |
| 1009 | 783 | |
| 1010 | | for(int y = 0; y < 240; y++) |
| 1011 | | { |
| 1012 | | for(int x = 0; x < 320; x++) |
| 1013 | | { |
| 784 | |
| 785 | } |
| 786 | |
| 1014 | 787 | |
| 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 }; |
| 1019 | 788 | |
| 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 | |
| 1025 | 796 | |
| 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 | { |
| 1058 | 799 | |
| 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; |
| 1062 | 810 | |
| 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 | |
| 1063 | 925 | return 0; |
| 1064 | 926 | } |
| 1065 | 927 | |
| r9078 | r9079 | |
| 1150 | 1012 | } |
| 1151 | 1013 | */ |
| 1152 | 1014 | |
| 1015 | // swap address around so that 64x64 tile can be decoded as 8x8 tiles.. |
| 1016 | void 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 | |
| 1025 | static 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 | |
| 1032 | static 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 | |
| 1153 | 1056 | static ADDRESS_MAP_START( supracan_mem, ADDRESS_SPACE_PROGRAM, 16 ) |
| 1154 | 1057 | AM_RANGE( 0x000000, 0x3fffff ) AM_ROM AM_REGION( "cart", 0 ) |
| 1155 | 1058 | AM_RANGE( 0xe80200, 0xe80201 ) AM_READ_PORT("P1") |
| r9078 | r9079 | |
| 1161 | 1064 | AM_RANGE( 0xe90020, 0xe9003f ) AM_WRITE( supracan_dma_w ) |
| 1162 | 1065 | AM_RANGE( 0xf00000, 0xf001ff ) AM_READWRITE( supracan_video_r, supracan_video_w ) |
| 1163 | 1066 | 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) |
| 1165 | 1068 | AM_RANGE( 0xfc0000, 0xfdffff ) AM_MIRROR(0x30000) AM_RAM /* System work ram */ |
| 1166 | 1069 | ADDRESS_MAP_END |
| 1167 | 1070 | |
| r9078 | r9079 | |
| 1570 | 1473 | { |
| 1571 | 1474 | case 0: |
| 1572 | 1475 | 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 | |
| 1573 | 1484 | break; |
| 1574 | 1485 | case 240: |
| 1575 | 1486 | state->video_regs[0] |= 0x8000; |
| r9078 | r9079 | |
| 1583 | 1494 | |
| 1584 | 1495 | state->video_regs[1] = machine->primary_screen->vpos(); |
| 1585 | 1496 | |
| 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 | | |
| 1650 | 1497 | timer_adjust_oneshot( state->hbl_timer, machine->primary_screen->time_until_pos( vpos, 320 ), 0 ); |
| 1651 | 1498 | timer_adjust_oneshot( state->video_timer, machine->primary_screen->time_until_pos( ( vpos + 1 ) % 256, 0 ), 0 ); |
| 1652 | 1499 | } |
| r9078 | r9079 | |
| 1657 | 1504 | acan_sprdma_regs_t *acan_sprdma_regs = &state->acan_sprdma_regs; |
| 1658 | 1505 | int i; |
| 1659 | 1506 | |
| 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 | |
| 1660 | 1510 | switch(offset) |
| 1661 | 1511 | { |
| 1662 | 1512 | case 0x10/2: // Byte count |
| r9078 | r9079 | |
| 1743 | 1593 | break; |
| 1744 | 1594 | case 0x0a/2: |
| 1745 | 1595 | { |
| 1596 | // raster interrupt |
| 1746 | 1597 | verboselog("maincpu", space->machine, 0, "IRQ Trigger? = %04x\n", data); |
| 1747 | 1598 | if(data & 0x8000) |
| 1748 | 1599 | { |
| 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); |
| 1750 | 1601 | } |
| 1751 | 1602 | else |
| 1752 | 1603 | { |
| r9078 | r9079 | |
| 1813 | 1664 | |
| 1814 | 1665 | case 0x1d0/2: state->unk_1d0 = data; verboselog("maincpu", space->machine, 3, "unk_1d0 = %04x\n", data); break; |
| 1815 | 1666 | |
| 1667 | |
| 1668 | |
| 1669 | |
| 1816 | 1670 | case 0x1f0/2: //FIXME: this register is mostly not understood |
| 1817 | 1671 | state->irq_mask = data;//(data & 8) ? 0 : 1; |
| 1818 | 1672 | /* |
| r9078 | r9079 | |
| 1884 | 1738 | } |
| 1885 | 1739 | |
| 1886 | 1740 | /* gfxdecode is retained for reference purposes but not otherwise used by the driver */ |
| 1887 | | #ifdef UNUSED_CODE |
| 1888 | 1741 | static const gfx_layout supracan_gfx8bpp = |
| 1889 | 1742 | { |
| 1890 | 1743 | 8,8, |
| 1891 | 1744 | RGN_FRAC(1,1), |
| 1892 | 1745 | 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 }, |
| 1895 | 1748 | { STEP8(0,8*8) }, |
| 1896 | 1749 | 8*8*8 |
| 1897 | 1750 | }; |
| 1898 | 1751 | |
| 1752 | |
| 1753 | |
| 1899 | 1754 | static const gfx_layout supracan_gfx4bpp = |
| 1900 | 1755 | { |
| 1901 | 1756 | 8,8, |
| r9078 | r9079 | |
| 1918 | 1773 | 8*16 |
| 1919 | 1774 | }; |
| 1920 | 1775 | |
| 1776 | |
| 1777 | static 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 }; |
| 1781 | static 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 }; |
| 1789 | static 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 | |
| 1802 | static 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 | |
| 1921 | 1814 | static 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 ) |
| 1925 | 1820 | GFXDECODE_END |
| 1926 | | #endif |
| 1927 | 1821 | |
| 1928 | 1822 | static INTERRUPT_GEN( supracan_irq ) |
| 1929 | 1823 | { |
| r9078 | r9079 | |
| 1979 | 1873 | MDRV_PALETTE_LENGTH( 32768 ) |
| 1980 | 1874 | MDRV_PALETTE_INIT( supracan ) |
| 1981 | 1875 | |
| 1876 | MDRV_GFXDECODE(supracan) |
| 1877 | |
| 1878 | |
| 1982 | 1879 | MDRV_CARTSLOT_ADD("cart") |
| 1983 | 1880 | MDRV_CARTSLOT_EXTENSION_LIST("bin") |
| 1984 | 1881 | MDRV_CARTSLOT_MANDATORY |
| r9078 | r9079 | |
| 1996 | 1893 | ROM_REGION( 0x400000, "cart", ROMREGION_ERASEFF ) |
| 1997 | 1894 | |
| 1998 | 1895 | ROM_REGION( 0x20000, "ram_gfx", ROMREGION_ERASEFF ) |
| 1896 | ROM_REGION( 0x20000, "ram_gfx2", ROMREGION_ERASEFF ) |
| 1897 | ROM_REGION( 0x20000, "ram_gfx3", ROMREGION_ERASEFF ) |
| 1898 | |
| 1999 | 1899 | ROM_END |
| 2000 | 1900 | |
| 2001 | 1901 | |