trunk/src/mame/drivers/ninjakd2.c
| r18282 | r18283 | |
| 220 | 220 | * |
| 221 | 221 | *************************************/ |
| 222 | 222 | |
| 223 | | static void omegaf_io_protection_reset(running_machine &machine) |
| 223 | void ninjakd2_state::omegaf_io_protection_reset() |
| 224 | 224 | { |
| 225 | | ninjakd2_state *state = machine.driver_data<ninjakd2_state>(); |
| 226 | 225 | // make sure protection starts in a known state |
| 227 | | state->m_omegaf_io_protection[0] = 0; |
| 228 | | state->m_omegaf_io_protection[1] = 0; |
| 229 | | state->m_omegaf_io_protection[2] = 0; |
| 230 | | state->m_omegaf_io_protection_input = 0; |
| 231 | | state->m_omegaf_io_protection_tic = 0; |
| 226 | m_omegaf_io_protection[0] = 0; |
| 227 | m_omegaf_io_protection[1] = 0; |
| 228 | m_omegaf_io_protection[2] = 0; |
| 229 | m_omegaf_io_protection_input = 0; |
| 230 | m_omegaf_io_protection_tic = 0; |
| 232 | 231 | } |
| 233 | 232 | |
| 234 | 233 | READ8_MEMBER(ninjakd2_state::omegaf_io_protection_r) |
| r18282 | r18283 | |
| 916 | 915 | |
| 917 | 916 | MACHINE_RESET_MEMBER(ninjakd2_state,omegaf) |
| 918 | 917 | { |
| 919 | | omegaf_io_protection_reset(machine()); |
| 918 | omegaf_io_protection_reset(); |
| 920 | 919 | |
| 921 | 920 | machine_reset(); |
| 922 | 921 | } |
| r18282 | r18283 | |
| 1393 | 1392 | |
| 1394 | 1393 | /************************************* |
| 1395 | 1394 | * |
| 1396 | | * Gfx ROM swizzling |
| 1395 | * Driver initialization |
| 1397 | 1396 | * |
| 1398 | 1397 | *************************************/ |
| 1399 | 1398 | |
| r18282 | r18283 | |
| 1410 | 1409 | static void lineswap_gfx_roms(running_machine &machine, const char *region, const int bit) |
| 1411 | 1410 | { |
| 1412 | 1411 | const int length = machine.root_device().memregion(region)->bytes(); |
| 1413 | | |
| 1414 | 1412 | UINT8* const src = machine.root_device().memregion(region)->base(); |
| 1415 | | |
| 1416 | 1413 | UINT8* const temp = auto_alloc_array(machine, UINT8, length); |
| 1417 | | |
| 1418 | 1414 | const int mask = (1 << (bit + 1)) - 1; |
| 1419 | 1415 | |
| 1420 | | int sa; |
| 1421 | | |
| 1422 | | for (sa = 0; sa < length; sa++) |
| 1416 | for (int sa = 0; sa < length; sa++) |
| 1423 | 1417 | { |
| 1424 | 1418 | const int da = (sa & ~mask) | ((sa << 1) & mask) | ((sa >> bit) & 1); |
| 1425 | | |
| 1426 | 1419 | temp[da] = src[sa]; |
| 1427 | 1420 | } |
| 1428 | 1421 | |
| 1429 | 1422 | memcpy(src, temp, length); |
| 1430 | | |
| 1431 | 1423 | auto_free(machine, temp); |
| 1432 | 1424 | } |
| 1433 | 1425 | |
| r18282 | r18283 | |
| 1439 | 1431 | } |
| 1440 | 1432 | |
| 1441 | 1433 | |
| 1442 | | |
| 1443 | | /************************************* |
| 1444 | | * |
| 1445 | | * Driver initialization |
| 1446 | | * |
| 1447 | | *************************************/ |
| 1448 | | |
| 1449 | 1434 | DRIVER_INIT_MEMBER(ninjakd2_state,ninjakd2) |
| 1450 | 1435 | { |
| 1451 | 1436 | mc8123_decrypt_rom(machine(), "soundcpu", "user1", NULL, 0); |
| r18282 | r18283 | |
| 1466 | 1451 | gfx_unscramble(machine()); |
| 1467 | 1452 | } |
| 1468 | 1453 | |
| 1454 | /*****************************************************************************/ |
| 1469 | 1455 | |
| 1470 | | static void robokid_motion_error_kludge(UINT8 *ROM) |
| 1456 | READ8_MEMBER(ninjakd2_state::robokid_motion_error_verbose_r) |
| 1471 | 1457 | { |
| 1458 | popmessage("%s MOTION ERROR, contact MAMEdev", machine().system().name); |
| 1459 | logerror("maincpu %04x MOTION ERROR\n", space.device().safe_pc()); |
| 1460 | return 0xe6; |
| 1461 | } |
| 1462 | |
| 1463 | void ninjakd2_state::robokid_motion_error_kludge(UINT16 offset) |
| 1464 | { |
| 1472 | 1465 | // patch out rare "5268 MOTION ERROR" (MT 05024) |
| 1473 | 1466 | // It looks like it's due to a buggy random number generator, |
| 1474 | 1467 | // then it possibly happens on the real arcade cabinet too. |
| 1475 | 1468 | // I doubt it is protection related, but you can never be sure. |
| 1469 | UINT8 *ROM = memregion("maincpu")->base() + offset; |
| 1476 | 1470 | ROM[0] = 0xe6; |
| 1477 | 1471 | ROM[1] = 0x03; // and 3 |
| 1478 | 1472 | ROM[2] = 0x18; |
| 1479 | 1473 | ROM[3] = 0xf6; // jr $-8 |
| 1474 | |
| 1475 | m_maincpu->space(AS_PROGRAM).install_read_handler(offset, offset, read8_delegate(FUNC(ninjakd2_state::robokid_motion_error_verbose_r), this)); |
| 1480 | 1476 | } |
| 1481 | 1477 | |
| 1482 | 1478 | DRIVER_INIT_MEMBER(ninjakd2_state,robokid) |
| 1483 | 1479 | { |
| 1484 | | robokid_motion_error_kludge(memregion("maincpu")->base() + 0x5247); |
| 1480 | robokid_motion_error_kludge(0x5247); |
| 1485 | 1481 | } |
| 1486 | 1482 | |
| 1487 | 1483 | DRIVER_INIT_MEMBER(ninjakd2_state,robokidj) |
| 1488 | 1484 | { |
| 1489 | | robokid_motion_error_kludge(memregion("maincpu")->base() + 0x5266); |
| 1485 | robokid_motion_error_kludge(0x5266); |
| 1490 | 1486 | } |
| 1491 | 1487 | |
| 1492 | 1488 | |
trunk/src/mame/video/ninjakd2.c
| r18282 | r18283 | |
| 1 | /****************************************************************************** |
| 2 | |
| 3 | UPL "sprite framebuffer" hardware |
| 4 | |
| 5 | ******************************************************************************/ |
| 6 | |
| 1 | 7 | #include "emu.h" |
| 2 | 8 | #include "includes/ninjakd2.h" |
| 3 | 9 | |
| r18282 | r18283 | |
| 2 | 8 | |
| 3 | | #define TRANSPARENTCODE (15) |
| 4 | | |
| 5 | 9 | /************************************* |
| r18282 | r18283 | |
| 115 | 119 | state->m_robokid_bg2_videoram = auto_alloc_array_clear(machine, UINT8, size); |
| 116 | 120 | } |
| 117 | 121 | |
| 118 | | machine.primary_screen->register_screen_bitmap(state->m_sp_bitmap); |
| 122 | machine.primary_screen->register_screen_bitmap(state->m_sprites_bitmap); |
| 119 | 123 | } |
| 120 | 124 | |
| 121 | 125 | static int stencil_ninjakd2( UINT16 pal ); |
| r18282 | r18283 | |
| 131 | 135 | m_fg_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); |
| 132 | 136 | m_bg_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::ninjakd2_get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32); |
| 133 | 137 | |
| 134 | | m_fg_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 138 | m_fg_tilemap->set_transparent_pen(0xf); |
| 135 | 139 | |
| 136 | 140 | m_robokid_sprites = 0; |
| 137 | 141 | m_stencil_compare_function = stencil_ninjakd2; |
| r18282 | r18283 | |
| 144 | 148 | m_fg_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); |
| 145 | 149 | m_bg_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::mnight_get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32); |
| 146 | 150 | |
| 147 | | m_fg_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 151 | m_fg_tilemap->set_transparent_pen(0xf); |
| 148 | 152 | |
| 149 | 153 | m_robokid_sprites = 0; |
| 150 | 154 | m_stencil_compare_function = stencil_mnight; |
| r18282 | r18283 | |
| 157 | 161 | m_fg_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); |
| 158 | 162 | m_bg_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::mnight_get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32); |
| 159 | 163 | |
| 160 | | m_fg_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 164 | m_fg_tilemap->set_transparent_pen(0xf); |
| 161 | 165 | |
| 162 | 166 | m_robokid_sprites = 0; |
| 163 | 167 | m_stencil_compare_function = stencil_arkarea; |
| r18282 | r18283 | |
| 174 | 178 | m_bg1_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::robokid_get_bg1_tile_info),this), tilemap_mapper_delegate(FUNC(ninjakd2_state::robokid_bg_scan),this), 16, 16, 32, 32); |
| 175 | 179 | m_bg2_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::robokid_get_bg2_tile_info),this), tilemap_mapper_delegate(FUNC(ninjakd2_state::robokid_bg_scan),this), 16, 16, 32, 32); |
| 176 | 180 | |
| 177 | | m_fg_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 178 | | m_bg1_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 179 | | m_bg2_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 181 | m_fg_tilemap->set_transparent_pen(0xf); |
| 182 | m_bg1_tilemap->set_transparent_pen(0xf); |
| 183 | m_bg2_tilemap->set_transparent_pen(0xf); |
| 180 | 184 | |
| 181 | 185 | m_robokid_sprites = 1; |
| 182 | 186 | m_stencil_compare_function = stencil_robokid; |
| r18282 | r18283 | |
| 193 | 197 | m_bg1_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::robokid_get_bg1_tile_info),this), tilemap_mapper_delegate(FUNC(ninjakd2_state::omegaf_bg_scan),this), 16, 16, 128, 32); |
| 194 | 198 | m_bg2_tilemap = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(ninjakd2_state::robokid_get_bg2_tile_info),this), tilemap_mapper_delegate(FUNC(ninjakd2_state::omegaf_bg_scan),this), 16, 16, 128, 32); |
| 195 | 199 | |
| 196 | | m_fg_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 197 | | m_bg0_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 198 | | m_bg1_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 199 | | m_bg2_tilemap->set_transparent_pen(TRANSPARENTCODE); |
| 200 | m_fg_tilemap->set_transparent_pen(0xf); |
| 201 | m_bg0_tilemap->set_transparent_pen(0xf); |
| 202 | m_bg1_tilemap->set_transparent_pen(0xf); |
| 203 | m_bg2_tilemap->set_transparent_pen(0xf); |
| 200 | 204 | |
| 201 | 205 | m_robokid_sprites = 1; |
| 202 | 206 | m_stencil_compare_function = stencil_omegaf; |
| r18282 | r18283 | |
| 291 | 295 | case 1: scrollx = ((scrollx & 0x0ff) | (data << 8)); break; |
| 292 | 296 | case 2: scrolly = ((scrolly & 0x100) | data); break; |
| 293 | 297 | case 3: scrolly = ((scrolly & 0x0ff) | (data << 8)); break; |
| 294 | | case 4: tilemap->enable(data & 1); break; |
| 298 | case 4: tilemap->enable(data & 1); break; |
| 295 | 299 | } |
| 296 | 300 | |
| 297 | 301 | tilemap->set_scrollx(0, scrollx); |
| r18282 | r18283 | |
| 319 | 323 | } |
| 320 | 324 | |
| 321 | 325 | |
| 322 | | |
| 323 | 326 | WRITE8_MEMBER(ninjakd2_state::ninjakd2_sprite_overdraw_w) |
| 324 | 327 | { |
| 325 | 328 | m_next_sprite_overdraw_enabled = data & 1; |
| r18282 | r18283 | |
| 390 | 393 | tile, |
| 391 | 394 | color, |
| 392 | 395 | flipx,flipy, |
| 393 | | sx + 16*x, sy + 16*y, TRANSPARENTCODE); |
| 396 | sx + 16*x, sy + 16*y, 0xf); |
| 394 | 397 | |
| 395 | 398 | ++sprites_drawn; |
| 396 | 399 | if (sprites_drawn >= 96) |
| r18282 | r18283 | |
| 428 | 431 | static void erase_sprites(running_machine& machine, bitmap_ind16 &bitmap) |
| 429 | 432 | { |
| 430 | 433 | ninjakd2_state *state = machine.driver_data<ninjakd2_state>(); |
| 434 | |
| 431 | 435 | // if sprite overdraw is disabled, clear the sprite framebuffer |
| 432 | 436 | if (!state->m_next_sprite_overdraw_enabled) |
| 433 | | state->m_sp_bitmap.fill(TRANSPARENTCODE); |
| 437 | { |
| 438 | state->m_sprites_bitmap.fill(0xf); |
| 439 | } |
| 434 | 440 | else |
| 435 | | for (int y = 0; y < state->m_sp_bitmap.height(); ++y) |
| 441 | { |
| 442 | for (int y = 0; y < state->m_sprites_bitmap.height(); ++y) |
| 436 | 443 | { |
| 437 | | for (int x = 0; x < state->m_sp_bitmap.width(); ++x) |
| 444 | for (int x = 0; x < state->m_sprites_bitmap.width(); ++x) |
| 438 | 445 | { |
| 439 | | UINT16* const ptr = &state->m_sp_bitmap.pix16(y, x); |
| 446 | UINT16* const ptr = &state->m_sprites_bitmap.pix16(y, x); |
| 440 | 447 | |
| 441 | | if ( (*state->m_stencil_compare_function)(*ptr) ) *ptr = TRANSPARENTCODE ; |
| 448 | if ( (*state->m_stencil_compare_function)(*ptr) ) *ptr = 0xf; |
| 442 | 449 | } |
| 443 | 450 | } |
| 451 | } |
| 444 | 452 | } |
| 445 | 453 | |
| 446 | 454 | |
| 447 | 455 | static void update_sprites(running_machine& machine) |
| 448 | 456 | { |
| 449 | 457 | ninjakd2_state *state = machine.driver_data<ninjakd2_state>(); |
| 450 | | erase_sprites(machine, state->m_sp_bitmap); |
| 451 | | draw_sprites(machine, state->m_sp_bitmap); |
| 452 | | } |
| 458 | |
| 453 | 459 | ////// Before modified, this was written. |
| 454 | 460 | // we want to erase the sprites with the old setting and draw them with the |
| 455 | 461 | // new one. Not doing this causes a glitch in Ninja Kid II when taking the top |
| 456 | 462 | // exit from stage 3. |
| 457 | 463 | ////// The glitch is correct behavior. |
| 464 | erase_sprites(machine, state->m_sprites_bitmap); |
| 465 | draw_sprites(machine, state->m_sprites_bitmap); |
| 466 | } |
| 458 | 467 | |
| 459 | 468 | |
| 460 | 469 | UINT32 ninjakd2_state::screen_update_ninjakd2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| r18282 | r18283 | |
| 467 | 476 | bitmap.fill(0, cliprect); |
| 468 | 477 | |
| 469 | 478 | m_bg_tilemap->draw(bitmap, cliprect, 0, 0); |
| 470 | | |
| 471 | | copybitmap_trans(bitmap, m_sp_bitmap, 0, 0, 0, 0, cliprect, TRANSPARENTCODE); |
| 472 | | |
| 479 | copybitmap_trans(bitmap, m_sprites_bitmap, 0, 0, 0, 0, cliprect, 0xf); |
| 473 | 480 | m_fg_tilemap->draw(bitmap, cliprect, 0, 0); |
| 474 | 481 | |
| 475 | 482 | return 0; |
| r18282 | r18283 | |
| 483 | 490 | bitmap.fill(0, cliprect); |
| 484 | 491 | |
| 485 | 492 | m_bg0_tilemap->draw(bitmap, cliprect, 0, 0); |
| 486 | | |
| 487 | 493 | m_bg1_tilemap->draw(bitmap, cliprect, 0, 0); |
| 488 | | |
| 489 | | copybitmap_trans(bitmap, m_sp_bitmap, 0, 0, 0, 0, cliprect, TRANSPARENTCODE); |
| 490 | | |
| 494 | copybitmap_trans(bitmap, m_sprites_bitmap, 0, 0, 0, 0, cliprect, 0xf); |
| 491 | 495 | m_bg2_tilemap->draw(bitmap, cliprect, 0, 0); |
| 492 | | |
| 493 | 496 | m_fg_tilemap->draw(bitmap, cliprect, 0, 0); |
| 494 | 497 | |
| 495 | 498 | return 0; |
| r18282 | r18283 | |
| 503 | 506 | bitmap.fill(0, cliprect); |
| 504 | 507 | |
| 505 | 508 | m_bg0_tilemap->draw(bitmap, cliprect, 0, 0); |
| 506 | | |
| 507 | 509 | m_bg1_tilemap->draw(bitmap, cliprect, 0, 0); |
| 508 | | |
| 509 | 510 | m_bg2_tilemap->draw(bitmap, cliprect, 0, 0); |
| 510 | | |
| 511 | | copybitmap_trans(bitmap, m_sp_bitmap, 0, 0, 0, 0, cliprect, TRANSPARENTCODE); |
| 512 | | |
| 511 | copybitmap_trans(bitmap, m_sprites_bitmap, 0, 0, 0, 0, cliprect, 0xf); |
| 513 | 512 | m_fg_tilemap->draw(bitmap, cliprect, 0, 0); |
| 514 | 513 | |
| 515 | 514 | return 0; |