From d9d16cc0e8a8c3dcca8d2f82ea71b9d27142dca1 Mon Sep 17 00:00:00 2001 From: hap Date: Fri, 20 Aug 2021 12:43:29 +0200 Subject: [PATCH] kncljoe: added sprite layer clipping [dink, hap] --- src/mame/drivers/kncljoe.cpp | 31 ++++++++---------- src/mame/includes/kncljoe.h | 13 +++++--- src/mame/video/kncljoe.cpp | 61 +++++++++++------------------------- 3 files changed, 40 insertions(+), 65 deletions(-) diff --git a/src/mame/drivers/kncljoe.cpp b/src/mame/drivers/kncljoe.cpp index d5581cbb948..c0eed4f5049 100644 --- a/src/mame/drivers/kncljoe.cpp +++ b/src/mame/drivers/kncljoe.cpp @@ -2,11 +2,10 @@ // copyright-holders:Ernesto Corvi /*************************************************************************** -Knuckle Joe - (c) 1985 Seibu Kaihatsu ( Taito License ) +Knuckle Joe - (c) 1985 Seibu Kaihatsu (Taito license) driver by Ernesto Corvi -Notes: This board seems to be an Irem design. The sound hardware is modified the 6803-based one used by the classic Irem games. There's only one AY 3-8910 chip and no MSM5205. There are also two @@ -15,15 +14,12 @@ The video hardware is pretty much like Irem games too. The only strange thing is that the screen is flipped vertically. TODO: -- sprite vs. sprite priority especially on ground level +- accurate screen timing (raw params), attract mode doesn't 1:1 match PCB -Updates: -- proper sound hw emulation (TS 070308) -- you can't play anymore after you die (clock speed too low, check XTAL) -- scrolling in bike levels (scroll register overflow) -- sprites disappearing at left screen edge (bad clipping) -- artifacts in stage 3 and others(clear sprite mem at bank switch?) -(081503AT) +BTANB: +- attract mode demo play stops playing and lets the timer run out +- player sprite 1-scanline glitch at the lower part of motorcycle level +- player sprite may briefly turn into garbage after a boss fight ***************************************************************************/ @@ -31,7 +27,6 @@ Updates: #include "includes/kncljoe.h" #include "cpu/z80/z80.h" -#include "cpu/m6800/m6801.h" #include "sound/sn76496.h" #include "speaker.h" @@ -256,13 +251,13 @@ void kncljoe_state::kncljoe(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &kncljoe_state::main_map); m_maincpu->set_vblank_int("screen", FUNC(kncljoe_state::irq0_line_hold)); - m6803_cpu_device &soundcpu(M6803(config, "soundcpu", XTAL(3'579'545))); /* verified on pcb */ - soundcpu.set_addrmap(AS_PROGRAM, &kncljoe_state::sound_map); - soundcpu.in_p1_cb().set(FUNC(kncljoe_state::m6803_port1_r)); - soundcpu.out_p1_cb().set(FUNC(kncljoe_state::m6803_port1_w)); - soundcpu.in_p2_cb().set(FUNC(kncljoe_state::m6803_port2_r)); - soundcpu.out_p2_cb().set(FUNC(kncljoe_state::m6803_port2_w)); - soundcpu.set_periodic_int(FUNC(kncljoe_state::sound_nmi), attotime::from_hz((double)3970)); //measured 3.970 kHz + M6803(config, m_soundcpu, XTAL(3'579'545)); /* verified on pcb */ + m_soundcpu->set_addrmap(AS_PROGRAM, &kncljoe_state::sound_map); + m_soundcpu->in_p1_cb().set(FUNC(kncljoe_state::m6803_port1_r)); + m_soundcpu->out_p1_cb().set(FUNC(kncljoe_state::m6803_port1_w)); + m_soundcpu->in_p2_cb().set(FUNC(kncljoe_state::m6803_port2_r)); + m_soundcpu->out_p2_cb().set(FUNC(kncljoe_state::m6803_port2_w)); + m_soundcpu->set_periodic_int(FUNC(kncljoe_state::sound_nmi), attotime::from_hz(3970)); // measured 3.970 kHz /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); diff --git a/src/mame/includes/kncljoe.h b/src/mame/includes/kncljoe.h index 331d95499c1..b73796af13f 100644 --- a/src/mame/includes/kncljoe.h +++ b/src/mame/includes/kncljoe.h @@ -2,16 +2,19 @@ // copyright-holders:Ernesto Corvi /************************************************************************* - Knuckle Joe + Knuckle Joe *************************************************************************/ -#ifndef MAME_INCLUDES_BLOODBRO_H -#define MAME_INCLUDES_BLOODBRO_H + +#ifndef MAME_INCLUDES_KNCLJOE_H +#define MAME_INCLUDES_KNCLJOE_H #pragma once +#include "cpu/m6800/m6801.h" #include "machine/gen_latch.h" #include "sound/ay8910.h" + #include "emupal.h" #include "screen.h" #include "tilemap.h" @@ -53,7 +56,7 @@ private: /* devices */ required_device m_maincpu; - required_device m_soundcpu; + required_device m_soundcpu; required_device m_gfxdecode; required_device m_screen; required_device m_palette; @@ -82,4 +85,4 @@ private: void sound_map(address_map &map); }; -#endif // MAME_INCLUDES_BLOODBRO_H +#endif // MAME_INCLUDES_KNCLJOE_H diff --git a/src/mame/video/kncljoe.cpp b/src/mame/video/kncljoe.cpp index ccbcc5ab44f..8293836e2ce 100644 --- a/src/mame/video/kncljoe.cpp +++ b/src/mame/video/kncljoe.cpp @@ -2,7 +2,7 @@ // copyright-holders:Ernesto Corvi /*************************************************************************** -Knuckle Joe - (c) 1985 Taito Corporation + Knuckle Joe ***************************************************************************/ @@ -120,7 +120,6 @@ void kncljoe_state::kncljoe_videoram_w(offs_t offset, uint8_t data) void kncljoe_state::kncljoe_control_w(uint8_t data) { - int i; /* 0x01 screen flip 0x02 coin counter#1 @@ -137,27 +136,19 @@ void kncljoe_state::kncljoe_control_w(uint8_t data) machine().bookkeeping().coin_counter_w(0, data & 0x02); machine().bookkeeping().coin_counter_w(1, data & 0x20); - i = (data & 0x10) >> 4; - if (m_tile_bank != i) + if (m_tile_bank != BIT(data, 4)) { - m_tile_bank = i; + m_tile_bank = BIT(data, 4); m_bg_tilemap->mark_all_dirty(); } - i = (data & 0x04) >> 2; - if (m_sprite_bank != i) - { - m_sprite_bank = i; - memset(memregion("maincpu")->base() + 0xf100, 0, 0x180); - } + m_sprite_bank = BIT(data, 2); } void kncljoe_state::kncljoe_scroll_w(offs_t offset, uint8_t data) { - int scrollx; - m_scrollregs[offset] = data; - scrollx = m_scrollregs[0] | m_scrollregs[1] << 8; + int scrollx = m_scrollregs[0] | m_scrollregs[1] << 8; m_bg_tilemap->set_scrollx(0, scrollx); m_bg_tilemap->set_scrollx(1, scrollx); m_bg_tilemap->set_scrollx(2, scrollx); @@ -174,48 +165,33 @@ void kncljoe_state::kncljoe_scroll_w(offs_t offset, uint8_t data) void kncljoe_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) { - uint8_t *spriteram = m_spriteram; - rectangle clip = cliprect; gfx_element *gfx = m_gfxdecode->gfx(1 + m_sprite_bank); - int i, j; - static const int pribase[4]={0x0180, 0x0080, 0x0100, 0x0000}; - const rectangle &visarea = m_screen->visible_area(); - /* score covers sprites */ - if (m_flipscreen) + for (int i = 0; i < 4; i++) { - if (clip.max_y > visarea.max_y - 64) - clip.max_y = visarea.max_y - 64; - } - else - { - if (clip.min_y < visarea.min_y + 64) - clip.min_y = visarea.min_y + 64; - } + // clip vertical strip for each layer + rectangle clip = cliprect; + clip.min_y = m_flipscreen ? (192 - i * 64) : (i * 64 + 1); + clip.max_y = clip.min_y + 64; + clip &= cliprect; - for (i = 0; i < 4; i++) - for (j = 0x7c; j >= 0; j -= 4) + for (int j = 0x7c; j >= 0; j -= 4) { - int offs = pribase[i] + j; - int sy = spriteram[offs]; - int sx = spriteram[offs + 3]; - int code = spriteram[offs + 2]; - int attr = spriteram[offs + 1]; + int offs = bitswap<2>(~i, 0, 1) << 7 | j; + int sy = m_spriteram[offs] + 1; + int sx = m_spriteram[offs + 3]; + int attr = m_spriteram[offs + 1]; + int code = m_spriteram[offs + 2] | ((attr & 0x10) << 5) | ((attr & 0x20) << 3); int flipx = attr & 0x40; int flipy = !(attr & 0x80); int color = attr & 0x0f; - if (attr & 0x10) - code += 512; - if (attr & 0x20) - code += 256; - if (m_flipscreen) { flipx = !flipx; flipy = !flipy; sx = 240 - sx; - sy = 240 - sy; + sy = 241 - sy; } if (sx >= 256-8) @@ -227,6 +203,7 @@ void kncljoe_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprec flipx,flipy, sx,sy,0); } + } } uint32_t kncljoe_state::screen_update_kncljoe(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)