From d4b6f7ded7dc3b969c0325ab81dff42b2fd4a7d9 Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 25 Jan 2018 12:16:31 +0900 Subject: Improved Nitro Ball priority / alpha mixing (#3110) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Demote Nitro Ball/Gun Ball with MACHINE_IMPERFECT… …_GRAPHICS, because it has wrong/unemulated alpha/priority functions. * rohga : Various improvements of Nitro Ball / Gun Ball Priority / Alpha blend. * rohga.cpp : typo * fix compile * rohga : Nitro Ball / Gun Ball priority fix * rohga : Nitro Ball / Gun Ball priority update * rohga.cpp : priority update, notes * rohga : update * rohga.cpp : update priority mode 0x20 * rohga : priority update * rohga : Nitro Ball/ Gun Ball priority update --- src/mame/drivers/rohga.cpp | 6 +- src/mame/includes/rohga.h | 3 +- src/mame/video/rohga.cpp | 187 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 184 insertions(+), 12 deletions(-) diff --git a/src/mame/drivers/rohga.cpp b/src/mame/drivers/rohga.cpp index cd867048adb..1b6f44eacff 100644 --- a/src/mame/drivers/rohga.cpp +++ b/src/mame/drivers/rohga.cpp @@ -1951,9 +1951,9 @@ GAME( 1992, wizdfire, 0, wizdfire, wizdfire, rohga_state, wizdfire, ROT0 GAME( 1992, wizdfireu, wizdfire, wizdfire, wizdfire, rohga_state, wizdfire, ROT0, "Data East Corporation", "Wizard Fire (US v1.1)", MACHINE_SUPPORTS_SAVE ) GAME( 1992, darkseal2, wizdfire, wizdfire, wizdfire, rohga_state, wizdfire, ROT0, "Data East Corporation", "Dark Seal 2 (Japan v2.1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1992, nitrobal, 0, nitrobal, nitrobal, rohga_state, nitrobal, ROT270, "Data East Corporation", "Nitro Ball (World, set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1992, nitrobala, nitrobal, nitrobal, nitrobal, rohga_state, nitrobal, ROT270, "Data East Corporation", "Nitro Ball (World, set 2)", MACHINE_SUPPORTS_SAVE ) // was marked 'US' but doesn't seem to have a 'Winners Don't Use Drugs' screen, so unlikely -GAME( 1992, gunball, nitrobal, nitrobal, nitrobal, rohga_state, nitrobal, ROT270, "Data East Corporation", "Gun Ball (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1992, nitrobal, 0, nitrobal, nitrobal, rohga_state, nitrobal, ROT270, "Data East Corporation", "Nitro Ball (World, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, nitrobala, nitrobal, nitrobal, nitrobal, rohga_state, nitrobal, ROT270, "Data East Corporation", "Nitro Ball (World, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // was marked 'US' but doesn't seem to have a 'Winners Don't Use Drugs' screen, so unlikely +GAME( 1992, gunball, nitrobal, nitrobal, nitrobal, rohga_state, nitrobal, ROT270, "Data East Corporation", "Gun Ball (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1993, schmeisr, 0, schmeisr, schmeisr, rohga_state, schmeisr, ROT0, "Hot-B", "Schmeiser Robo (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL ) GAME( 1992, hangzo, 0, hangzo, hangzo, rohga_state, hangzo, ROT0, "Hot-B", "Hangzo (Japan, prototype)", MACHINE_SUPPORTS_SAVE ) // ROM contains a '(c)1992 Data East Corporation' string, but other sources indicate the game is by Hot-B diff --git a/src/mame/includes/rohga.h b/src/mame/includes/rohga.h index 5d6399e481c..c079b2d2c4e 100644 --- a/src/mame/includes/rohga.h +++ b/src/mame/includes/rohga.h @@ -76,7 +76,8 @@ public: uint32_t screen_update_rohga(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_wizdfire(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); uint32_t screen_update_nitrobal(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void mixwizdfirelayer(bitmap_rgb32 &bitmap, const rectangle &cliprect, int gfxregion, uint16_t pri, uint16_t primask); + void mixwizdfirelayer(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t pri, uint16_t primask); + void mixnitroballlayer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); DECO16IC_BANK_CB_MEMBER(bank_callback); DECOSPR_PRIORITY_CB_MEMBER(rohga_pri_callback); DECOSPR_COLOUR_CB_MEMBER(rohga_col_callback); diff --git a/src/mame/video/rohga.cpp b/src/mame/video/rohga.cpp index 6bf0442bc33..4ced2a33e06 100644 --- a/src/mame/video/rohga.cpp +++ b/src/mame/video/rohga.cpp @@ -78,7 +78,7 @@ VIDEO_START_MEMBER(rohga_state,wizdfire) } // not amazingly efficient, called multiple times to pull a layer out of the sprite bitmaps, but keeps correct sprite<->sprite priorities -void rohga_state::mixwizdfirelayer(bitmap_rgb32 &bitmap, const rectangle &cliprect, int gfxregion, uint16_t pri, uint16_t primask) +void rohga_state::mixwizdfirelayer(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t pri, uint16_t primask) { int y, x; const pen_t *paldata = m_palette->pens(); @@ -153,16 +153,180 @@ uint32_t rohga_state::screen_update_wizdfire(screen_device &screen, bitmap_rgb32 m_sprgen1->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0400, 0x400, 0x1ff); // 0x000 and 0x200 of 0x600 - mixwizdfirelayer(bitmap, cliprect, 4, 0x000, 0x000); + mixwizdfirelayer(bitmap, cliprect, 0x000, 0x000); m_deco_tilegen1->tilemap_1_draw(screen, bitmap, cliprect, 0, 0); return 0; } +void rohga_state::mixnitroballlayer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + int y, x; + const pen_t *paldata = &m_palette->pen(0); + bitmap_ind16 *sprite_bitmap1, *sprite_bitmap2; + bitmap_ind8* priority_bitmap; + + uint16_t priority = m_decocomn->priority_r(); + + sprite_bitmap1 = &m_sprgen1->get_sprite_temp_bitmap(); + sprite_bitmap2 = &m_sprgen2->get_sprite_temp_bitmap(); + priority_bitmap = &screen.priority(); + + uint32_t* dstline; + uint16_t *srcline1, *srcline2; + uint8_t *srcpriline; + + for (y=cliprect.min_y;y<=cliprect.max_y;y++) + { + srcline1=&sprite_bitmap1->pix16(y,0); + srcline2=&sprite_bitmap2->pix16(y,0); + srcpriline=&priority_bitmap->pix8(y,0); + + dstline=&bitmap.pix32(y,0); + + for (x=cliprect.min_x;x<=cliprect.max_x;x++) + { + uint16_t pix1 = srcline1[x]; + uint16_t pix2 = srcline2[x]; + + /* Here we have + pix1 - raw pixel / colour / priority data from first 1st chip + pix2 - raw pixel / colour / priority data from first 2nd chip + */ + + int pri1, pri2; + + // pix1 sprite vs playfield + switch (priority) // TODO : Verify this from real pcb + { + case 0x00: + default: + { + switch (pix1 & 0xe00) + { + case 0x000: + default: + pri1 = 0x200; + break; + case 0x200: + pri1 = 0x020; + break; + case 0x400: + pri1 = 0x008; + break; + case 0x600: + pri1 = 0x002; + break; + case 0x800: + pri1 = 0x100; + break; + case 0xa00: + pri1 = 0x040; + break; + case 0xc00: + pri1 = 0x004; + break; + case 0xe00: + pri1 = 0x001; + break; + } + } + break; + case 0x20: + { + switch (pix1 & 0xe00) + { + case 0x000: + default: + pri1 = 0x080; + break; + case 0x200: + pri1 = 0x004; + break; + case 0x400: + pri1 = 0x002; + break; + case 0x600: + pri1 = 0x001; + break; + case 0x800: + pri1 = 0x100; + break; + case 0xa00: + pri1 = 0x020; + break; + case 0xc00: + pri1 = 0x008; + break; + case 0xe00: + pri1 = 0x200; + break; + } + } + break; + } + + // pix2 sprite vs pix1 sprite + pri2 = 0x080; + switch (priority) + { + case 0x00: + default: + pri2 = 0x080; + break; + case 0x20: + pri2 = 0x010; + break; + } + + uint8_t bgpri = srcpriline[x]; + /* once we get here we have + + pri1 - 1/2/4/8/16/64 (sprite chip 1 pixel priority relative to bg) + pri2 - 8/16 (sprite chip 2 pixel priority relative to bg) + + bgpri - 4/32 (from drawing tilemaps earlier, to compare above pri1/pri2 priorities against) + pix1 - same as before (ready to extract just colour data from) + pix2 - same as before ^^ + */ + + int drawnpixe1 = 0; + if (pix1 & 0xf) + { + if (pri1 > bgpri) + { + dstline[x] = paldata[(pix1&0x1ff)+0x400]; + drawnpixe1 = 1; + } + } + + if (pix2 & 0xf) + { + if (pri2 > bgpri) + { + if ((!drawnpixe1) || (pri2 > pri1)) + { + if (pix2 & 0x100) + { + uint32_t base = dstline[x]; + dstline[x] = alpha_blend_r32(base, paldata[(pix2&0xff)+0x600], 0x80); + } + else + { + dstline[x] = paldata[(pix2&0xff)+0x600]; + } + } + } + } + } + } +} + uint32_t rohga_state::screen_update_nitrobal(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { address_space &space = machine().dummy_space(); uint16_t flip = m_deco_tilegen1->pf_control_r(space, 0, 0xffff); + uint16_t priority = m_decocomn->priority_r(); /* draw sprite gfx to temp bitmaps */ m_sprgen1->set_alt_format(true); @@ -181,13 +345,20 @@ uint32_t rohga_state::screen_update_nitrobal(screen_device &screen, bitmap_rgb32 /* pf3 and pf4 are combined into a single 8bpp bitmap */ m_deco_tilegen2->tilemap_12_combine_draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); + + switch (priority) + { + case 0: + default: + m_deco_tilegen1->tilemap_2_draw(screen, bitmap, cliprect, 0, 0x008); + break; + case 0x20: + m_deco_tilegen1->tilemap_2_draw(screen, bitmap, cliprect, 0, 0x040); + break; + } - m_deco_tilegen1->tilemap_2_draw(screen, bitmap, cliprect, 0, 16); - - /* ToDo reimplement priorities + mixing / alpha, it was busted worse than this before anyway, so no big loss that we don't do it for now ;-) */ - m_sprgen2->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0000, 0x600, 0xff); - m_sprgen1->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0000, 0x400, 0x1ff); - + /* TODO verify priorities + mixing / alpha */ + mixnitroballlayer(screen,bitmap,cliprect); m_deco_tilegen1->tilemap_1_draw(screen, bitmap, cliprect, 0, 0); return 0; -- cgit v1.2.3