diff options
-rw-r--r-- | src/mame/drivers/psikyosh.cpp | 150 | ||||
-rw-r--r-- | src/mame/includes/psikyosh.h | 80 | ||||
-rw-r--r-- | src/mame/video/psikyosh.cpp | 354 |
3 files changed, 283 insertions, 301 deletions
diff --git a/src/mame/drivers/psikyosh.cpp b/src/mame/drivers/psikyosh.cpp index 57308ca514f..70a1dcbf426 100644 --- a/src/mame/drivers/psikyosh.cpp +++ b/src/mame/drivers/psikyosh.cpp @@ -229,8 +229,8 @@ Psikyo PS5V2 hardware readme Dragon Blaze, Psikyo, 2000 Gunbarich, Psikyo, 2001 -Tetris The Grand Master 2 , Psikyo, 2000 -Tetris The Grand Master 2+, Psikyo, 2000 +Tetris The Grand Master 2, Arika / Psikyo, 2000 +Tetris The Grand Master 2+, Arika / Psikyo, 2000 Mahjong G-Taste, Psikyo, 2002 PCB Layout @@ -310,40 +310,24 @@ static GFXDECODE_START( gfx_psikyosh ) GFXDECODE_ENTRY( "gfx1", 0, layout_16x16x8, 0x000, 0x100 ) // 8bpp tiles GFXDECODE_END -WRITE32_MEMBER(psikyosh_state::psh_eeprom_w) +WRITE8_MEMBER(psikyosh_state::eeprom_w) { - if (ACCESSING_BITS_24_31) - { - m_eeprom->di_write((data & 0x20000000) ? 1 : 0); - m_eeprom->cs_write((data & 0x80000000) ? ASSERT_LINE : CLEAR_LINE); - m_eeprom->clk_write((data & 0x40000000) ? ASSERT_LINE : CLEAR_LINE); - - return; - } + m_eeprom->di_write((data & 0x20) ? 1 : 0); + m_eeprom->cs_write((data & 0x80) ? ASSERT_LINE : CLEAR_LINE); + m_eeprom->clk_write((data & 0x40) ? ASSERT_LINE : CLEAR_LINE); - logerror("Unk EEPROM write %x mask %x\n", data, mem_mask); + if (data & ~0xe0) + logerror("Unk EEPROM write %x mask %x\n", data, mem_mask); } -READ32_MEMBER(psikyosh_state::psh_eeprom_r) -{ - if (ACCESSING_BITS_24_31) - { - return ioport("JP4")->read(); - } - - logerror("Unk EEPROM read mask %x\n", mem_mask); - - return 0; -} - -INTERRUPT_GEN_MEMBER(psikyosh_state::psikyosh_interrupt) +INTERRUPT_GEN_MEMBER(psikyosh_state::interrupt) { device.execute().set_input_line(4, ASSERT_LINE); } // VBL handler writes 0x00 on entry, 0xc0 on exit // bit 0 controls game speed on readback, mechanism is a little weird -WRITE32_MEMBER(psikyosh_state::psikyosh_irqctrl_w) +WRITE32_MEMBER(psikyosh_state::irqctrl_w) { if (!(data & 0x00c00000)) { @@ -352,14 +336,15 @@ WRITE32_MEMBER(psikyosh_state::psikyosh_irqctrl_w) } -WRITE32_MEMBER(psikyosh_state::psikyosh_vidregs_w) +WRITE32_MEMBER(psikyosh_state::vidregs_w) { - COMBINE_DATA(&m_vidregs[offset]); + uint32_t const old = m_vidregs[offset]; + data = COMBINE_DATA(&m_vidregs[offset]); if (offset == 4) /* Configure bank for gfx test */ { - if (ACCESSING_BITS_0_15) // Bank - membank("gfxbank")->set_entry(m_vidregs[offset] & 0xfff); + if ((old ^ data) & 0xfff) // Bank + m_gfxrombank->set_entry(data & 0xfff); } } @@ -416,10 +401,11 @@ P1KEY11 29|30 P2KEY11 GND 55|56 GND */ - uint32_t controls = ioport("CONTROLLER")->read(); - uint32_t value = ioport("INPUTS")->read(); + uint32_t const controls = m_controller_io->read(); + uint32_t value = m_inputs->read(); - if(controls) { + if (controls) + { // Clearly has ghosting, game will only recognise one key depressed at once, and keyboard can only represent keys with distinct rows and columns // Since the game can't accept conflicting inputs e.g. PL1 Up and 'A' or 'B' we have to // make the user choose the input method. Especially since in test mode both sets are usable. @@ -462,18 +448,19 @@ P1KEY11 29|30 P2KEY11 KEY11 | KEY6, // Ron KEY1 | KEY3 // Start }; // generic Mahjong keyboard encoder, corresponds to ordering in input port - uint32_t keys = ioport("MAHJONG")->read(); + uint32_t keys = m_mahjong_io->read(); uint32_t which_key = 0x1; int count = 0; // HACK: read IPT_START1 from "INPUTS" to avoid listing it twice or having two independent STARTs listed - int start_depressed = ~value & 0x01000000; + uint32_t const start_depressed = ~value & 0x01000000; keys |= start_depressed ? 1 << (ARRAY_LENGTH(key_codes) - 1) : 0; // and bung it in at the end value |= 0xFFFF0000; // set top word do { // since we can't handle multiple keys, just return the first one depressed - if((keys & which_key) && (count < ARRAY_LENGTH(key_codes))) { + if((keys & which_key) && (count < ARRAY_LENGTH(key_codes))) + { value &= ~((uint32_t)(key_codes[count]) << 16); // mask in selected word as IP_ACTIVE_LOW break; } @@ -493,12 +480,11 @@ void psikyosh_state::ps3v1_map(address_map &map) map(0x00000000, 0x000fffff).rom(); // program ROM (1 meg) map(0x02000000, 0x020fffff).rom().region("maincpu", 0x100000); // data ROM // video chip - map(0x03000000, 0x03003fff).ram().share("spriteram"); // video banks0-7 (sprites and sprite list) - map(0x03004000, 0x0300ffff).ram().share("bgram"); // video banks 7-0x1f (backgrounds and other effects) + map(0x03000000, 0x0300ffff).ram().share("spriteram"); // sprite and backgrounds are share this area (video banks 0-1f) map(0x03040000, 0x03044fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette"); // palette.. map(0x03050000, 0x030501ff).ram().share("zoomram"); // sprite zoom lookup table - map(0x0305ffdc, 0x0305ffdf).r("watchdog", FUNC(watchdog_timer_device::reset32_r)).w(FUNC(psikyosh_state::psikyosh_irqctrl_w)); // also writes to this address - might be vblank reads? - map(0x0305ffe0, 0x0305ffff).ram().w(FUNC(psikyosh_state::psikyosh_vidregs_w)).share("vidregs"); // video registers + map(0x0305ffdc, 0x0305ffdf).r("watchdog", FUNC(watchdog_timer_device::reset32_r)).w(FUNC(psikyosh_state::irqctrl_w)); // also writes to this address - might be vblank reads? + map(0x0305ffe0, 0x0305ffff).ram().w(FUNC(psikyosh_state::vidregs_w)).share("vidregs"); // video registers map(0x03060000, 0x0307ffff).bankr("gfxbank"); // data for rom tests (gfx), data is controlled by vidreg // rom mapping map(0x04060000, 0x0407ffff).bankr("gfxbank"); // data for rom tests (gfx) (Mirrored?) @@ -506,7 +492,8 @@ void psikyosh_state::ps3v1_map(address_map &map) map(0x05000000, 0x05000007).rw("ymf", FUNC(ymf278b_device::read), FUNC(ymf278b_device::write)); // inputs/eeprom map(0x05800000, 0x05800003).portr("INPUTS"); - map(0x05800004, 0x05800007).rw(FUNC(psikyosh_state::psh_eeprom_r), FUNC(psikyosh_state::psh_eeprom_w)); + map(0x05800004, 0x05800007).portr("JP4"); + map(0x05800004, 0x05800004).w(FUNC(psikyosh_state::eeprom_w)); // ram map(0x06000000, 0x060fffff).ram().share("ram"); // main RAM (1 meg) } @@ -518,16 +505,16 @@ void psikyosh_state::ps5_map(address_map &map) map(0x00000000, 0x000fffff).rom(); // program ROM (1 meg) // inputs/eeprom map(0x03000000, 0x03000003).portr("INPUTS"); - map(0x03000004, 0x03000007).rw(FUNC(psikyosh_state::psh_eeprom_r), FUNC(psikyosh_state::psh_eeprom_w)); + map(0x03000004, 0x03000007).portr("JP4"); + map(0x03000004, 0x03000004).w(FUNC(psikyosh_state::eeprom_w)); // sound chip map(0x03100000, 0x03100007).rw("ymf", FUNC(ymf278b_device::read), FUNC(ymf278b_device::write)); // video chip - map(0x04000000, 0x04003fff).ram().share("spriteram"); // video banks0-7 (sprites and sprite list) - map(0x04004000, 0x0400ffff).ram().share("bgram"); // video banks 7-0x1f (backgrounds and other effects) + map(0x04000000, 0x0400ffff).ram().share("spriteram"); // sprite and backgrounds are share this area (video banks 0-1f) map(0x04040000, 0x04044fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette"); map(0x04050000, 0x040501ff).ram().share("zoomram"); // sprite zoom lookup table - map(0x0405ffdc, 0x0405ffdf).nopr().w(FUNC(psikyosh_state::psikyosh_irqctrl_w)); // also writes to this address - might be vblank reads? - map(0x0405ffe0, 0x0405ffff).ram().w(FUNC(psikyosh_state::psikyosh_vidregs_w)).share("vidregs"); // video registers + map(0x0405ffdc, 0x0405ffdf).nopr().w(FUNC(psikyosh_state::irqctrl_w)); // also writes to this address - might be vblank reads? + map(0x0405ffe0, 0x0405ffff).ram().w(FUNC(psikyosh_state::vidregs_w)).share("vidregs"); // video registers map(0x04060000, 0x0407ffff).bankr("gfxbank"); // data for rom tests (gfx), data is controlled by vidreg // rom mapping map(0x05000000, 0x0507ffff).rom().region("maincpu", 0x100000); // data ROM @@ -535,6 +522,14 @@ void psikyosh_state::ps5_map(address_map &map) map(0x06000000, 0x060fffff).ram().share("ram"); } +// mahjong +void psikyosh_state::ps5_mahjong_map(address_map &map) +{ + ps5_map(map); + /* needs to install mahjong controls too (can select joystick in test mode tho) */ + map(0x03000000, 0x03000003).r(FUNC(psikyosh_state::mjgtaste_input_r)); +} + static INPUT_PORTS_START( common ) PORT_START("INPUTS") @@ -773,7 +768,7 @@ INPUT_PORTS_END void psikyosh_state::machine_start() { - membank("gfxbank")->configure_entries(0, 0x1000, memregion("gfx1")->base(), 0x20000); + m_gfxrombank->configure_entries(0, 0x1000, memregion("gfx1")->base(), 0x20000); } @@ -782,7 +777,7 @@ void psikyosh_state::psikyo3v1(machine_config &config) /* basic machine hardware */ SH2(config, m_maincpu, MASTER_CLOCK/2); m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps3v1_map); - m_maincpu->set_vblank_int("screen", FUNC(psikyosh_state::psikyosh_interrupt)); + m_maincpu->set_vblank_int("screen", FUNC(psikyosh_state::interrupt)); WATCHDOG_TIMER(config, "watchdog"); @@ -795,8 +790,8 @@ void psikyosh_state::psikyo3v1(machine_config &config) m_screen->set_refresh_hz(60); m_screen->set_size(64*8, 32*8); m_screen->set_visarea(0, 40*8-1, 0, 28*8-1); - m_screen->set_screen_update(FUNC(psikyosh_state::screen_update_psikyosh)); - m_screen->screen_vblank().set("spriteram", FUNC(buffered_spriteram32_device::vblank_copy_rising)); + m_screen->set_screen_update(FUNC(psikyosh_state::screen_update)); + m_screen->screen_vblank().set(m_spriteram, FUNC(buffered_spriteram32_device::vblank_copy_rising)); GFXDECODE(config, m_gfxdecode, m_palette, gfx_psikyosh); PALETTE(config, m_palette).set_format(palette_device::RGBx_888, 0x5000 / 4); @@ -805,21 +800,29 @@ void psikyosh_state::psikyo3v1(machine_config &config) SPEAKER(config, "mono").front_center(); ymf278b_device &ymf(YMF278B(config, "ymf", MASTER_CLOCK/2)); - ymf.irq_handler().set_inputline("maincpu", 12); + ymf.irq_handler().set_inputline(m_maincpu, 12); ymf.add_route(ALL_OUTPUTS, "mono", 1.0); } void psikyosh_state::psikyo5(machine_config &config) { psikyo3v1(config); + + /* basic machine hardware */ m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps5_map); } -void psikyosh_state::psikyo5_240(machine_config &config) +void psikyosh_state::psikyo5_mahjong(machine_config &config) { - psikyo3v1(config); + psikyo5(config); - m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps5_map); + /* basic machine hardware */ + m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps5_mahjong_map); +} + +void psikyosh_state::psikyo5_240(machine_config &config) +{ + psikyo5(config); /* Measured Hsync 16.165 KHz, Vsync 61.68 Hz */ /* Ideally this would be driven off the video register. However, it doesn't changeat runtime and MAME will pick a better screen resolution if it knows upfront */ @@ -1230,7 +1233,7 @@ ROM_END void psikyosh_state::init_ps3() { m_maincpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); - m_maincpu->sh2drc_add_fastram(0x03004000, 0x0300ffff, 0, &m_bgram[0]); + m_maincpu->sh2drc_add_fastram(0x03000000, 0x0300ffff, 0, &m_spriteram->live()[0]); m_maincpu->sh2drc_add_fastram(0x03050000, 0x030501ff, 0, &m_zoomram[0]); m_maincpu->sh2drc_add_fastram(0x06000000, 0x060fffff, 0, &m_ram[0]); } @@ -1238,37 +1241,30 @@ void psikyosh_state::init_ps3() void psikyosh_state::init_ps5() { m_maincpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); - m_maincpu->sh2drc_add_fastram(0x04004000, 0x0400ffff, 0, &m_bgram[0]); + m_maincpu->sh2drc_add_fastram(0x04000000, 0x0400ffff, 0, &m_spriteram->live()[0]); m_maincpu->sh2drc_add_fastram(0x04050000, 0x040501ff, 0, &m_zoomram[0]); m_maincpu->sh2drc_add_fastram(0x06000000, 0x060fffff, 0, &m_ram[0]); } -void psikyosh_state::init_mjgtaste() -{ - /* needs to install mahjong controls too (can select joystick in test mode tho) */ - m_maincpu->space(AS_PROGRAM).install_read_handler(0x03000000, 0x03000003, read32_delegate(FUNC(psikyosh_state::mjgtaste_input_r),this)); - init_ps5(); -} - // YEAR NAME PARENT MACHINE INPUT STATE INIT MONITOR COMPANY FULLNAME FLAGS */ /* ps3-v1 */ -GAME( 1997, soldivid, 0, psikyo3v1, soldivid, psikyosh_state, init_ps3, ROT0, "Psikyo", "Sol Divide - The Sword Of Darkness", MACHINE_SUPPORTS_SAVE ) -GAME( 1997, soldividk, soldivid, psikyo3v1, soldividk,psikyosh_state, init_ps3, ROT0, "Psikyo", "Sol Divide - The Sword Of Darkness (Korea)", MACHINE_SUPPORTS_SAVE ) -GAME( 1997, s1945ii, 0, psikyo3v1, s1945ii, psikyosh_state, init_ps3, ROT270, "Psikyo", "Strikers 1945 II", MACHINE_SUPPORTS_SAVE ) -GAME( 1998, daraku, 0, psikyo3v1, daraku, psikyosh_state, init_ps3, ROT0, "Psikyo", "Daraku Tenshi - The Fallen Angels", MACHINE_SUPPORTS_SAVE ) -GAME( 1998, sbomber, 0, psikyo3v1, sbomberb, psikyosh_state, init_ps3, ROT270, "Psikyo", "Space Bomber (ver. B)", MACHINE_SUPPORTS_SAVE ) -GAME( 1998, sbombera, sbomber, psikyo3v1, sbomberb, psikyosh_state, init_ps3, ROT270, "Psikyo", "Space Bomber", MACHINE_SUPPORTS_SAVE ) +GAME( 1997, soldivid, 0, psikyo3v1, soldivid, psikyosh_state, init_ps3, ROT0, "Psikyo", "Sol Divide - The Sword Of Darkness", MACHINE_SUPPORTS_SAVE ) +GAME( 1997, soldividk, soldivid, psikyo3v1, soldividk,psikyosh_state, init_ps3, ROT0, "Psikyo", "Sol Divide - The Sword Of Darkness (Korea)", MACHINE_SUPPORTS_SAVE ) +GAME( 1997, s1945ii, 0, psikyo3v1, s1945ii, psikyosh_state, init_ps3, ROT270, "Psikyo", "Strikers 1945 II", MACHINE_SUPPORTS_SAVE ) +GAME( 1998, daraku, 0, psikyo3v1, daraku, psikyosh_state, init_ps3, ROT0, "Psikyo", "Daraku Tenshi - The Fallen Angels", MACHINE_SUPPORTS_SAVE ) +GAME( 1998, sbomber, 0, psikyo3v1, sbomberb, psikyosh_state, init_ps3, ROT270, "Psikyo", "Space Bomber (ver. B)", MACHINE_SUPPORTS_SAVE ) +GAME( 1998, sbombera, sbomber, psikyo3v1, sbomberb, psikyosh_state, init_ps3, ROT270, "Psikyo", "Space Bomber", MACHINE_SUPPORTS_SAVE ) /* ps5 */ -GAME( 1998, gunbird2, 0, psikyo5, gunbird2, psikyosh_state, init_ps5, ROT270, "Psikyo", "Gunbird 2 (set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1998, gunbird2a, gunbird2, psikyo5, gunbird2, psikyosh_state, init_ps5, ROT270, "Psikyo", "Gunbird 2 (set 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1999, s1945iii, 0, psikyo5, s1945iii, psikyosh_state, init_ps5, ROT270, "Psikyo", "Strikers 1945 III (World) / Strikers 1999 (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1998, gunbird2, 0, psikyo5, gunbird2, psikyosh_state, init_ps5, ROT270, "Psikyo", "Gunbird 2 (set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1998, gunbird2a, gunbird2, psikyo5, gunbird2, psikyosh_state, init_ps5, ROT270, "Psikyo", "Gunbird 2 (set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1999, s1945iii, 0, psikyo5, s1945iii, psikyosh_state, init_ps5, ROT270, "Psikyo", "Strikers 1945 III (World) / Strikers 1999 (Japan)", MACHINE_SUPPORTS_SAVE ) /* ps5v2 */ -GAME( 2000, dragnblz, 0, psikyo5, dragnblz, psikyosh_state, init_ps5, ROT270, "Psikyo", "Dragon Blaze", MACHINE_SUPPORTS_SAVE ) -GAME( 2000, tgm2, 0, psikyo5_240, tgm2, psikyosh_state, init_ps5, ROT0, "Arika", "Tetris the Absolute The Grand Master 2", MACHINE_SUPPORTS_SAVE ) -GAME( 2000, tgm2p, tgm2, psikyo5_240, tgm2, psikyosh_state, init_ps5, ROT0, "Arika", "Tetris the Absolute The Grand Master 2 Plus", MACHINE_SUPPORTS_SAVE ) -GAME( 2001, gnbarich, 0, psikyo5, gnbarich, psikyosh_state, init_ps5, ROT270, "Psikyo", "Gunbarich", MACHINE_SUPPORTS_SAVE ) -GAME( 2002, mjgtaste, 0, psikyo5, mjgtaste, psikyosh_state, init_mjgtaste, ROT0, "Psikyo", "Mahjong G-Taste", MACHINE_SUPPORTS_SAVE ) +GAME( 2000, dragnblz, 0, psikyo5, dragnblz, psikyosh_state, init_ps5, ROT270, "Psikyo", "Dragon Blaze", MACHINE_SUPPORTS_SAVE ) +GAME( 2000, tgm2, 0, psikyo5_240, tgm2, psikyosh_state, init_ps5, ROT0, "Arika", "Tetris the Absolute The Grand Master 2", MACHINE_SUPPORTS_SAVE ) +GAME( 2000, tgm2p, tgm2, psikyo5_240, tgm2, psikyosh_state, init_ps5, ROT0, "Arika", "Tetris the Absolute The Grand Master 2 Plus", MACHINE_SUPPORTS_SAVE ) +GAME( 2001, gnbarich, 0, psikyo5, gnbarich, psikyosh_state, init_ps5, ROT270, "Psikyo", "Gunbarich", MACHINE_SUPPORTS_SAVE ) +GAME( 2002, mjgtaste, 0, psikyo5_mahjong, mjgtaste, psikyosh_state, init_ps5, ROT0, "Psikyo", "Mahjong G-Taste", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/psikyosh.h b/src/mame/includes/psikyosh.h index 4888a0db224..670cde3e0bf 100644 --- a/src/mame/includes/psikyosh.h +++ b/src/mame/includes/psikyosh.h @@ -15,18 +15,7 @@ #define MASTER_CLOCK 57272700 // main oscillator frequency /* Psikyo PS6406B */ -#define FLIPSCREEN (((m_vidregs[3] & 0x0000c000) == 0x0000c000) ? 1:0) -#define DISPLAY_DISABLE (((m_vidregs[2] & 0x0000000f) == 0x00000006) ? 1:0) -#define BG_LARGE(n) (((m_vidregs[7] << (4*n)) & 0x00001000 ) ? 1:0) -#define BG_DEPTH_8BPP(n) (((m_vidregs[7] << (4*n)) & 0x00004000 ) ? 1:0) -#define BG_LAYER_ENABLE(n) (((m_vidregs[7] << (4*n)) & 0x00008000 ) ? 1:0) -#define BG_TYPE(n) (((m_vidregs[6] << (8*n)) & 0x7f000000 ) >> 24) -#define BG_LINE(n) (((m_vidregs[6] << (8*n)) & 0x80000000 ) ? 1:0) - -#define BG_TRANSPEN rgb_t(0x00,0xff,0x00,0xff) // used for representing transparency in temporary bitmaps - -#define SPRITE_PRI(n) (((m_vidregs[2] << (4*n)) & 0xf0000000 ) >> 28) class psikyosh_state : public driver_device @@ -34,11 +23,14 @@ class psikyosh_state : public driver_device public: psikyosh_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_spriteram(*this, "spriteram") , - m_bgram(*this, "bgram"), + m_spriteram(*this, "spriteram"), m_zoomram(*this, "zoomram"), m_vidregs(*this, "vidregs"), m_ram(*this, "ram"), + m_gfxrombank(*this, "gfxbank"), + m_controller_io(*this, "CONTROLLER"), + m_inputs(*this, "INPUTS"), + m_mahjong_io(*this, "MAHJONG"), m_maincpu(*this, "maincpu"), m_eeprom(*this, "eeprom"), m_gfxdecode(*this, "gfxdecode"), @@ -48,26 +40,31 @@ public: void psikyo3v1(machine_config &config); void psikyo5(machine_config &config); + void psikyo5_mahjong(machine_config &config); void psikyo5_240(machine_config &config); void init_ps3(); void init_ps5(); - void init_mjgtaste(); private: /* memory pointers */ required_device<buffered_spriteram32_device> m_spriteram; - required_shared_ptr<uint32_t> m_bgram; required_shared_ptr<uint32_t> m_zoomram; required_shared_ptr<uint32_t> m_vidregs; required_shared_ptr<uint32_t> m_ram; + required_memory_bank m_gfxrombank; + + optional_ioport m_controller_io; + optional_ioport m_inputs; + optional_ioport m_mahjong_io; + /* video-related */ - bitmap_ind8 m_zoom_bitmap; - bitmap_ind16 m_z_bitmap; - bitmap_rgb32 m_bg_bitmap; - std::unique_ptr<uint16_t[]> m_bg_zoom; - uint8_t m_alphatable[256]; + bitmap_ind8 m_zoom_bitmap; + bitmap_ind16 m_z_bitmap; + bitmap_rgb32 m_bg_bitmap; + std::unique_ptr<uint16_t[]> m_bg_zoom; + std::unique_ptr<uint8_t[]> m_alphatable; /* devices */ required_device<sh2_device> m_maincpu; @@ -76,30 +73,41 @@ private: required_device<screen_device> m_screen; required_device<palette_device> m_palette; - DECLARE_WRITE32_MEMBER(psikyosh_irqctrl_w); - DECLARE_WRITE32_MEMBER(psikyosh_vidregs_w); + bool const FLIPSCREEN() { return ((m_vidregs[3] & 0x0000c000) == 0x0000c000); } // currently ignored + + bool const BG_LARGE(uint8_t const n) { return ((m_vidregs[7] << (4 * n)) & 0x00001000); } + bool const BG_DEPTH_8BPP(uint8_t const n) { return ((m_vidregs[7] << (4 * n)) & 0x00004000); } + bool const BG_LAYER_ENABLE(uint8_t const n) { return ((m_vidregs[7] << (4 * n)) & 0x00008000); } + + uint8_t const BG_TYPE(uint8_t const n) { return ((m_vidregs[6] << (8 * n)) & 0x7f000000) >> 24; } + bool const BG_LINE(uint8_t const n) { return ((m_vidregs[6] << (8 * n)) & 0x80000000); } + + uint8_t const SPRITE_PRI(uint8_t const n) { return ((m_vidregs[2] << (4 * n)) & 0xf0000000) >> 28; } + + DECLARE_WRITE32_MEMBER(irqctrl_w); + DECLARE_WRITE32_MEMBER(vidregs_w); DECLARE_READ32_MEMBER(mjgtaste_input_r); - DECLARE_WRITE32_MEMBER(psh_eeprom_w); - DECLARE_READ32_MEMBER(psh_eeprom_r); + DECLARE_WRITE8_MEMBER(eeprom_w); virtual void machine_start() override; virtual void video_start() override; - uint32_t screen_update_psikyosh(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(psikyosh_interrupt); + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + INTERRUPT_GEN_MEMBER(interrupt); void draw_scanline32_alpha(bitmap_rgb32 &bitmap, int32_t destx, int32_t desty, int32_t length, const uint32_t *srcptr, int alpha); void draw_scanline32_argb(bitmap_rgb32 &bitmap, int32_t destx, int32_t desty, int32_t length, const uint32_t *srcptr); void draw_scanline32_transpen(bitmap_rgb32 &bitmap, int32_t destx, int32_t desty, int32_t length, const uint32_t *srcptr); - void draw_bglayer( int layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ); - void cache_bitmap(int scanline, gfx_element *gfx, int size, int tilebank, int alpha, int *last_bank); - void draw_bglayerscroll( int layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ); - void draw_background( bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ); - void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri); - void psikyosh_prelineblend( bitmap_rgb32 &bitmap, const rectangle &cliprect ); - void psikyosh_postlineblend( bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ); - void psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, - uint32_t code,uint32_t color,int flipx,int flipy,int offsx,int offsy, - int alpha, int zoomx, int zoomy, int wide, int high, uint32_t z); + void draw_bglayer(uint8_t const layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri); + void cache_bitmap(int16_t const scanline, gfx_element *gfx, uint8_t const size, uint8_t const tilebank, int16_t const alpha, uint8_t *last_bank); + void draw_bglayerscroll(uint8_t const layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri); + void draw_background(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri); + void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri); + void prelineblend(bitmap_rgb32 &bitmap, const rectangle &cliprect ); + void postlineblend(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri); + void psikyosh_drawgfxzoom(bitmap_rgb32 &dest_bmp, const rectangle &clip, gfx_element *gfx, + uint32_t const code, uint16_t const color, uint8_t const flipx, uint8_t const flipy, int16_t const offsx, int16_t const offsy, + int16_t const alpha, uint32_t const zoomx, uint32_t const zoomy, uint8_t const wide, uint8_t const high, uint16_t const z); void ps3v1_map(address_map &map); void ps5_map(address_map &map); + void ps5_mahjong_map(address_map &map); }; #endif // MAME_INCLUDES_PSIKYOSH_H diff --git a/src/mame/video/psikyosh.cpp b/src/mame/video/psikyosh.cpp index a0f87ca5676..49a342363e9 100644 --- a/src/mame/video/psikyosh.cpp +++ b/src/mame/video/psikyosh.cpp @@ -68,6 +68,8 @@ The only viable way to do this is to have one tilemap per bank (0x0a-0x20), and #include "drawgfxm.h" #include "includes/psikyosh.h" +static constexpr uint32_t BG_TRANSPEN = 0x00ff00ff; // used for representing transparency in temporary bitmaps + //#define DEBUG_KEYS //#define DEBUG_MESSAGE @@ -141,101 +143,86 @@ void psikyosh_state::draw_scanline32_transpen(bitmap_rgb32 &bitmap, int32_t dest /* 'Normal' layers, no line/columnscroll. No per-line effects. Zooming isn't supported just because it's not used and it would be slow */ -void psikyosh_state::draw_bglayer( int layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ) +void psikyosh_state::draw_bglayer(uint8_t const layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri) { - gfx_element *gfx; - int offs = 0, sx, sy; - int scrollx, scrolly, regbank, tilebank, alpha, alphamap, zoom, pri, size, width; - assert(!BG_LINE(layer)); - gfx = BG_DEPTH_8BPP(layer) ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0); - size = BG_LARGE(layer) ? 32 : 16; - width = 16 * size; + gfx_element *gfx = BG_DEPTH_8BPP(layer) ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0); + uint8_t const size = BG_LARGE(layer) ? 32 : 16; + uint16_t const height = 16 * size; - regbank = BG_TYPE(layer); + uint8_t const regbank = BG_TYPE(layer); - scrollx = (m_bgram[(regbank * 0x800) / 4 + 0x3f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x000001ff) >> 0; - scrolly = (m_bgram[(regbank * 0x800) / 4 + 0x3f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x03ff0000) >> 16; + uint16_t const scrollx = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x3f0 / 4 + (layer * 0x04) / 4] & 0x000001ff) >> 0; + uint16_t const scrolly = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x3f0 / 4 + (layer * 0x04) / 4] & 0x03ff0000) >> 16; - tilebank = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x000000ff) >> 0; - alpha = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x00003f00) >> 8; - alphamap = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x00008000) >> 15; - zoom = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x00ff0000) >> 16; - pri = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0xff000000) >> 24; + uint8_t const tilebank = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x000000ff) >> 0; + int16_t alpha = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x00003f00) >> 8; + uint8_t const alphamap = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x00008000) >> 15; + uint8_t const zoom = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x00ff0000) >> 16; + uint8_t const pri = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0xff000000) >> 24; - if(pri != req_pri) return; + if (pri != req_pri) + return; if (alphamap) /* alpha values are per-pen */ alpha = -1; else alpha = pal6bit(0x3f - alpha); /* 0x3f-0x00 maps to 0x00-0xff */ - if(zoom) { + if (zoom) popmessage("draw_bglayer() zoom not implemented\nContact MAMEDEV"); - } if ((tilebank >= 0x0a) && (tilebank <= 0x1f)) /* 20 banks of 0x800 bytes. filter garbage. */ { - for (sy = 0; sy < size; sy++) + uint8_t basey = ((0x400 - scrolly + cliprect.top() - 1) & (height - 1)) >> 4; + for (int sy = (cliprect.top() - 1) >> 4; sy <= cliprect.bottom() >> 4; sy++) { - for (sx = 0; sx < 32; sx++) + uint8_t basex = ((0x200 - scrollx + cliprect.left() - 1) & 0x1ff) >> 4; + for (int sx = (cliprect.left() - 1) >> 4; sx <= cliprect.right() >> 4; sx++) { - int tileno, colour; + uint32_t const tileno = (m_spriteram->live()[(tilebank * 0x800) / 4 + (((basey & 0x1f) << 5) | (basex & 0x1f))] & 0x0007ffff); + uint8_t const colour = (m_spriteram->live()[(tilebank * 0x800) / 4 + (((basey & 0x1f) << 5) | (basex & 0x1f))] & 0xff000000) >> 24; - tileno = (m_bgram[(tilebank * 0x800) / 4 + offs - 0x4000 / 4] & 0x0007ffff); /* seems to take into account spriteram, hence -0x4000 */ - colour = (m_bgram[(tilebank * 0x800) / 4 + offs - 0x4000 / 4] & 0xff000000) >> 24; + gfx->alphatable(bitmap, cliprect, tileno, colour, 0, 0, (16 * sx) + (scrollx & 0xf), (16 * sy) + (scrolly & 0xf), alpha, m_alphatable.get()); /* normal */ - gfx->alphatable(bitmap, cliprect, tileno, colour, 0, 0, (16 * sx + scrollx) & 0x1ff, ((16 * sy + scrolly) & (width - 1)), alpha, m_alphatable); /* normal */ - - if (scrollx) - gfx->alphatable(bitmap, cliprect, tileno, colour, 0, 0, ((16 * sx + scrollx) & 0x1ff) - 0x200, ((16 * sy + scrolly) & (width - 1)), alpha, m_alphatable); /* wrap x */ - if (scrolly) - gfx->alphatable(bitmap, cliprect, tileno, colour, 0, 0, (16 * sx + scrollx) & 0x1ff, ((16 * sy + scrolly) & (width - 1)) - width, alpha, m_alphatable); /* wrap y */ - if (scrollx && scrolly) - gfx->alphatable(bitmap, cliprect, tileno, colour, 0, 0, ((16 * sx + scrollx) & 0x1ff) - 0x200, ((16 * sy + scrolly) & (width - 1)) - width, alpha, m_alphatable); /* wrap xy */ - - offs++; + basex++; } + basey = ((basey + 1) & ((height >> 4) - 1)); } } } /* populate bg_bitmap for the given bank if it's not already */ -void psikyosh_state::cache_bitmap(int scanline, gfx_element *gfx, int size, int tilebank, int alpha, int *last_bank) +void psikyosh_state::cache_bitmap(int16_t const scanline, gfx_element *gfx, uint8_t const size, uint8_t const tilebank, int16_t const alpha, uint8_t *last_bank) { // test if the tile row is the cached one or not - int sy = scanline / 16; + uint8_t const sy = scanline / 16; assert(sy >= 0 && sy < 32); - if(tilebank != last_bank[sy]) + if (tilebank != last_bank[sy]) { rectangle cliprect; - int minsy = sy * 16; - int maxsy = minsy + 16 - 1; + uint16_t const minsy = sy * 16; + uint16_t const maxsy = minsy + 16 - 1; cliprect.set(0, m_bg_bitmap.width() - 1, minsy, maxsy ); cliprect &= m_bg_bitmap.cliprect(); m_bg_bitmap.fill(BG_TRANSPEN, cliprect); - int width = size * 16; - - int offs = size * sy; - int sx; + uint16_t const height = size * 16; - for (sx = 0; sx < 32; sx++) + uint32_t offs = 32 * sy; + for (int sx = 0; sx < 32; sx++) { - int tileno, colour; - - tileno = (m_bgram[(tilebank * 0x800) / 4 + offs - 0x4000 / 4] & 0x0007ffff); /* seems to take into account spriteram, hence -0x4000 */ - colour = (m_bgram[(tilebank * 0x800) / 4 + offs - 0x4000 / 4] & 0xff000000) >> 24; + uint32_t const tileno = (m_spriteram->live()[(tilebank * 0x800) / 4 + offs] & 0x0007ffff); + uint32_t const colour = (m_spriteram->live()[(tilebank * 0x800) / 4 + offs] & 0xff000000) >> 24; int need_alpha = alpha < 0 ? -1 : 0xff; // store per-pen alpha in bitmap, otherwise don't since we'll need it per-line - if(tileno) { // valid tile, but blank in all games? - gfx->alphastore(m_bg_bitmap, m_bg_bitmap.cliprect(), tileno, colour, 0, 0, (16 * sx) & 0x1ff, ((16 * sy) & (width - 1)), need_alpha, m_alphatable); - } + if (tileno) // valid tile, but blank in all games? + gfx->alphastore(m_bg_bitmap, m_bg_bitmap.cliprect(), tileno, colour, 0, 0, (16 * sx) & 0x1ff, ((16 * sy) & (height - 1)), need_alpha, m_alphatable.get()); offs++; } @@ -248,51 +235,50 @@ void psikyosh_state::cache_bitmap(int scanline, gfx_element *gfx, int size, int Bitmap is first rendered to an ARGB image, taking into account the per-pen alpha (if used). From there we extract data as we compose the image, one scanline at a time, blending the ARGB pixels into the RGB32 bitmap (with either the alpha information from the ARGB, or per-line alpha */ -void psikyosh_state::draw_bglayerscroll( int layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ) +void psikyosh_state::draw_bglayerscroll(uint8_t const layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri) { assert(BG_LINE(layer)); gfx_element *gfx = BG_DEPTH_8BPP(layer) ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0); - int size = BG_LARGE(layer) ? 32 : 16; - int width = size * 16; + uint8_t const size = BG_LARGE(layer) ? 32 : 16; + uint16_t const height = size * 16; - int linebank = BG_TYPE(layer); + uint8_t linebank = BG_TYPE(layer); /* cache rendered bitmap */ - int last_bank[32]; // corresponds to bank of bitmap in m_bg_bitmap. bg_bitmap is split into 16/32-rows of one-tile high each - for(auto & elem : last_bank) elem = -1; + uint8_t last_bank[32]; // corresponds to bank of bitmap in m_bg_bitmap. bg_bitmap is split into 16/32-rows of one-tile high each + for (auto & elem : last_bank) elem = -1; int scr_width = cliprect.width(); - int scr_height = cliprect.height(); - uint32_t *scroll_reg = &m_bgram[(linebank * 0x800) / 4 - 0x4000 / 4]; - uint32_t *pzab_reg = &m_bgram[(linebank * 0x800) / 4 - 0x4000 / 4 + 0x400 / 4]; // pri, zoom, alpha, bank + uint32_t *scroll_reg = &m_spriteram->live()[(linebank * 0x800) / 4 + cliprect.top()]; + uint32_t *pzab_reg = &m_spriteram->live()[(linebank * 0x800) / 4 + cliprect.top() + 0x400 / 4]; // pri, zoom, alpha, bank // now, for each scanline, check priority, // extract the relevant scanline from the bitmap, after applying per-scanline vscroll, // stretch it and scroll it into another buffer // write it with alpha - for(int scanline = 0; scanline < scr_height; scanline++) + for (int scanline = cliprect.top(); scanline <= cliprect.bottom(); scanline++) { - int pri = (*pzab_reg & 0xff000000) >> 24; + uint8_t pri = (*pzab_reg & 0xff000000) >> 24; - if(pri == req_pri) + if (pri == req_pri) { - int scrollx = (*scroll_reg & 0x000001ff) >> 0; - int scrolly = (*scroll_reg & 0x03ff0000) >> 16; + uint16_t const scrollx = (*scroll_reg & 0x000001ff) >> 0; + uint16_t const scrolly = (*scroll_reg & 0x03ff0000) >> 16; - int zoom = (*pzab_reg & 0x00ff0000) >> 16; - int alphamap = (*pzab_reg & 0x00008000) >> 15; - int alpha = (*pzab_reg & 0x00003f00) >> 8; - int tilebank = (*pzab_reg & 0x000000ff) >> 0; + uint8_t const zoom = (*pzab_reg & 0x00ff0000) >> 16; + uint8_t const alphamap = (*pzab_reg & 0x00008000) >> 15; + int16_t alpha = (*pzab_reg & 0x00003f00) >> 8; + uint8_t const tilebank = (*pzab_reg & 0x000000ff) >> 0; - if(alphamap) /* alpha values are per-pen */ + if (alphamap) /* alpha values are per-pen */ alpha = -1; else alpha = pal6bit(0x3f - alpha); if ((tilebank >= 0x0a) && (tilebank <= 0x1f)) /* 20 banks of 0x800 bytes. filter garbage. */ { - int tilemap_scanline = (scanline - scrolly + 0x400) % 0x200; + int16_t const tilemap_scanline = (scanline - scrolly + 0x400) & (height - 1); // render reelvant tiles to temp bitmap, assume bank changes infrequently/never. render alpha as per-pen cache_bitmap(tilemap_scanline, gfx, size, tilebank, alpha, last_bank); @@ -301,37 +287,37 @@ void psikyosh_state::draw_bglayerscroll( int layer, bitmap_rgb32 &bitmap, const g_profiler.start(PROFILER_USER2); uint32_t tilemap_line[32 * 16]; uint32_t scr_line[64 * 8]; - extract_scanline32(m_bg_bitmap, 0, tilemap_scanline, width, tilemap_line); + extract_scanline32(m_bg_bitmap, 0, tilemap_scanline, 0x200, tilemap_line); g_profiler.stop(); /* slow bit, needs optimising. apply scrollx and zoomx by assembling scanline from row */ g_profiler.start(PROFILER_USER3); - if(zoom) { - int step = m_bg_zoom[zoom]; - int jj = 0x400 << 10; // ensure +ve for mod - for(int ii = 0; ii < scr_width; ii++) { - scr_line[ii] = tilemap_line[((jj>>10) - scrollx) % width]; + if (zoom) + { + uint16_t const step = m_bg_zoom[zoom]; + int jj = (0x400 << 10) + (step * cliprect.left()); // ensure +ve for mod + for (int ii = cliprect.left(); ii <= cliprect.right(); ii++) + { + scr_line[ii] = tilemap_line[((jj>>10) - scrollx) & 0x1ff]; jj += step; } } - else { - for(int ii = 0; ii < scr_width; ii++) { - scr_line[ii] = tilemap_line[(ii - scrollx + 0x400) % width]; - } + else + { + for (int ii = cliprect.left(); ii <= cliprect.right(); ii++) + scr_line[ii] = tilemap_line[(ii - scrollx + 0x400) & 0x1ff]; } g_profiler.stop(); /* blend line into output */ g_profiler.start(PROFILER_USER4); - if(alpha == 0xff) { - draw_scanline32_transpen(bitmap, 0, scanline, scr_width, scr_line); - } - else if (alpha > 0) { - draw_scanline32_alpha(bitmap, 0, scanline, scr_width, scr_line, alpha); - } - else if (alpha < 0) { - draw_scanline32_argb(bitmap, 0, scanline, scr_width, scr_line); - } + if (alpha == 0xff) + draw_scanline32_transpen(bitmap, cliprect.left(), scanline, scr_width, &scr_line[cliprect.left()]); + else if (alpha > 0) + draw_scanline32_alpha(bitmap, cliprect.left(), scanline, scr_width, &scr_line[cliprect.left()], alpha); + else if (alpha < 0) + draw_scanline32_argb(bitmap, cliprect.left(), scanline, scr_width, &scr_line[cliprect.left()]); + g_profiler.stop(); } } @@ -342,7 +328,7 @@ void psikyosh_state::draw_bglayerscroll( int layer, bitmap_rgb32 &bitmap, const } /* 3 BG layers, with priority */ -void psikyosh_state::draw_background( bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ) +void psikyosh_state::draw_background(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri) { int i; @@ -351,9 +337,9 @@ void psikyosh_state::draw_background( bitmap_rgb32 &bitmap, const rectangle &cli bool lay_debug = false; for (i = 0; i <= 3; i++) { - if(machine().input().code_pressed(lay_keys[i])) { + if (machine().input().code_pressed(lay_keys[i])) lay_debug = true; - } + } #endif @@ -361,21 +347,18 @@ void psikyosh_state::draw_background( bitmap_rgb32 &bitmap, const rectangle &cli for (i = 0; i <= 3; i++) { #ifdef DEBUG_KEYS - if(lay_debug && !machine().input().code_pressed(lay_keys[i])) + if (lay_debug && !machine().input().code_pressed(lay_keys[i])) continue; #endif if (!BG_LAYER_ENABLE(i)) continue; - if(BG_LINE(i)) { - /* per-line alpha, scroll, zoom etc. check the priority for the first scanline */ + if (BG_LINE(i)) /* per-line alpha, scroll, zoom etc. check the priority for the first scanline */ draw_bglayerscroll(i, bitmap, cliprect, req_pri); - } - else { - /* not per-line alpha, scroll, zoom etc. */ + else /* not per-line alpha, scroll, zoom etc. */ draw_bglayer(i, bitmap, cliprect, req_pri); - } + } } @@ -388,11 +371,10 @@ void psikyosh_state::draw_background( bitmap_rgb32 &bitmap, const rectangle &cli /* sx and sy is top-left of entire sprite regardless of flip */ /* Note that Level 5-4 of sbomberb boss is perfect! (Alpha blended zoomed) as well as S1945II logo */ /* pixel is only plotted if z is >= priority_buffer[y][x] */ -void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, - uint32_t code,uint32_t color,int flipx,int flipy,int offsx,int offsy, - int alpha, int zoomx, int zoomy, int wide, int high, uint32_t z) +void psikyosh_state::psikyosh_drawgfxzoom(bitmap_rgb32 &dest_bmp, const rectangle &clip, gfx_element *gfx, + uint32_t const code, uint16_t const color, uint8_t const flipx, uint8_t const flipy, int16_t const offsx, int16_t const offsy, + int16_t const alpha, uint32_t const zoomx, uint32_t const zoomy, uint8_t const wide, uint8_t const high, uint16_t const z) { - uint8_t *alphatable = m_alphatable; rectangle myclip; /* Clip to screen boundaries */ int code_offset = 0; int xtile, ytile, xpixel, ypixel; @@ -445,27 +427,27 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang ex = sx + gfx->width(); ey = sy + gfx->height(); - if (sx < myclip.min_x) + if (sx < myclip.left()) { /* clip left */ - int pixels = myclip.min_x - sx; + int pixels = myclip.left() - sx; sx += pixels; x_index_base += xinc * pixels; } - if (sy < myclip.min_y) + if (sy < myclip.top()) { /* clip top */ - int pixels = myclip.min_y - sy; + int pixels = myclip.top() - sy; sy += pixels; y_index += yinc * pixels; } /* NS 980211 - fixed incorrect clipping */ - if (ex > myclip.max_x + 1) + if (ex > myclip.right() + 1) { /* clip right */ - int pixels = ex - myclip.max_x - 1; + int pixels = ex - myclip.right() - 1; ex -= pixels; } - if (ey > myclip.max_y + 1) + if (ey > myclip.bottom() + 1) { /* clip bottom */ - int pixels = ey - myclip.max_y - 1; + int pixels = ey - myclip.bottom() - 1; ey -= pixels; } @@ -613,10 +595,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang int c = *source; if (c != 0) { - if (alphatable[c] == 0xff) + if (m_alphatable[c] == 0xff) *dest = pal[c]; else - *dest = alpha_blend_r32(*dest, pal[c], alphatable[c]); + *dest = alpha_blend_r32(*dest, pal[c], m_alphatable[c]); *pri = z; } @@ -645,10 +627,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang int c = *source; if (c != 0) { - if (alphatable[c] == 0xff) + if (m_alphatable[c] == 0xff) *dest = pal[c]; else - *dest = alpha_blend_r32(*dest, pal[c], alphatable[c]); + *dest = alpha_blend_r32(*dest, pal[c], m_alphatable[c]); } dest++; source += xinc; @@ -715,27 +697,27 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang if (flipy) { y_index = (sprite_screen_height - 1) * zoomy; dy = -zoomy; } else { y_index = 0; dy = zoomy; } - if (sx < myclip.min_x) + if (sx < myclip.left()) { /* clip left */ - int pixels = myclip.min_x - sx; + int pixels = myclip.left() - sx; sx += pixels; x_index_base += pixels * dx; } - if (sy < myclip.min_y) + if (sy < myclip.top()) { /* clip top */ - int pixels = myclip.min_y - sy; + int pixels = myclip.top() - sy; sy += pixels; y_index += pixels * dy; } /* NS 980211 - fixed incorrect clipping */ - if (ex > myclip.max_x + 1) + if (ex > myclip.right() + 1) { /* clip right */ - int pixels = ex-myclip.max_x - 1; + int pixels = ex-myclip.right() - 1; ex -= pixels; } - if (ey > myclip.max_y + 1) + if (ey > myclip.bottom() + 1) { /* clip bottom */ - int pixels = ey-myclip.max_y - 1; + int pixels = ey-myclip.bottom() - 1; ey -= pixels; } @@ -862,10 +844,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang int c = source[x_index >> 10]; if (c != 0) { - if (alphatable[c] == 0xff) + if (m_alphatable[c] == 0xff) dest[x] = pal[c]; else - dest[x] = alpha_blend_r32(dest[x], pal[c], alphatable[c]); + dest[x] = alpha_blend_r32(dest[x], pal[c], m_alphatable[c]); pri[x] = z; } @@ -889,10 +871,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang int c = source[x_index >> 10]; if (c != 0) { - if (alphatable[c] == 0xff) + if (m_alphatable[c] == 0xff) dest[x] = pal[c]; else - dest[x] = alpha_blend_r32(dest[x], pal[c], alphatable[c]); + dest[x] = alpha_blend_r32(dest[x], pal[c], m_alphatable[c]); } x_index += dx; } @@ -909,7 +891,7 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang } -void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri) +void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri) { /*- Sprite Format 0x0000 - 0x37ff -** @@ -948,9 +930,9 @@ void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec #ifdef DEBUG_KEYS for (int i = 0; i <= 3; i++) { - if(machine().input().code_pressed(spr_keys[i])) { + if (machine().input().code_pressed(spr_keys[i])) spr_debug = true; - } + } #endif @@ -965,42 +947,38 @@ void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec uint16_t listcntr = 0; while (listcntr < listlen) { - uint32_t listdat, sprnum, xpos, ypos, high, wide, flpx, flpy, zoomx, zoomy, tnum, colr, dpth; - uint8_t bg_pri, spr_pri, alphamap; - int alpha; - - listdat = list[BYTE_XOR_BE(listcntr)]; - sprnum = (listdat & 0x03ff) * 4; + uint16_t const listdat = list[BYTE_XOR_BE(listcntr)]; + uint16_t const sprnum = (listdat & 0x03ff) * 4; - bg_pri = (src[sprnum + 1] & 0x00003000) >> 12; + uint8_t bg_pri = (src[sprnum + 1] & 0x00003000) >> 12; bg_pri = SPRITE_PRI(bg_pri); // sprite vs backgrounds pri if (bg_pri == req_pri) { - ypos = (src[sprnum + 0] & 0x03ff0000) >> 16; - xpos = (src[sprnum + 0] & 0x000003ff) >> 00; + int16_t ypos = (src[sprnum + 0] & 0x03ff0000) >> 16; + int16_t xpos = (src[sprnum + 0] & 0x000003ff) >> 00; if (ypos & 0x200) ypos -= 0x400; if (xpos & 0x200) xpos -= 0x400; - high = ((src[sprnum + 1] & 0x0f000000) >> 24) + 1; - wide = ((src[sprnum + 1] & 0x00000f00) >> 8) + 1; + uint8_t const high = ((src[sprnum + 1] & 0x0f000000) >> 24) + 1; + uint8_t const wide = ((src[sprnum + 1] & 0x00000f00) >> 8) + 1; - flpy = (src[sprnum + 1] & 0x80000000) >> 31; - spr_pri = (src[sprnum + 1] & 0x30000000) >> 28; - flpx = (src[sprnum + 1] & 0x00008000) >> 15; + uint8_t const flpy = (src[sprnum + 1] & 0x80000000) >> 31; + uint8_t const spr_pri = (src[sprnum + 1] & 0x30000000) >> 28; + uint8_t const flpx = (src[sprnum + 1] & 0x00008000) >> 15; - zoomy = (src[sprnum + 1] & 0x00ff0000) >> 16; - zoomx = (src[sprnum + 1] & 0x000000ff) >> 00; + uint8_t const zoomy = (src[sprnum + 1] & 0x00ff0000) >> 16; + uint8_t const zoomx = (src[sprnum + 1] & 0x000000ff) >> 00; - tnum = (src[sprnum + 2] & 0x0007ffff) >> 00; - dpth = (src[sprnum + 2] & 0x00800000) >> 23; - colr = (src[sprnum + 2] & 0xff000000) >> 24; + uint32_t const tnum = (src[sprnum + 2] & 0x0007ffff) >> 00; + uint8_t const dpth = (src[sprnum + 2] & 0x00800000) >> 23; + uint16_t const colr = (src[sprnum + 2] & 0xff000000) >> 24; - alpha = (src[sprnum + 2] & 0x00700000) >> 20; + int16_t alpha = (src[sprnum + 2] & 0x00700000) >> 20; - alphamap = (alpha_table[BYTE4_XOR_BE(alpha)] & 0x80)? 1:0; + uint8_t const alphamap = (alpha_table[BYTE4_XOR_BE(alpha)] & 0x80)? 1:0; alpha = alpha_table[BYTE4_XOR_BE(alpha)] & 0x3f; gfx = dpth ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0); @@ -1010,7 +988,7 @@ void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec else alpha = pal6bit(0x3f - alpha); /* 0x3f-0x00 maps to 0x00-0xff */ - if(!spr_debug || machine().input().code_pressed(spr_keys[spr_pri])) + if (!spr_debug || machine().input().code_pressed(spr_keys[spr_pri])) { /* start drawing */ if (zoom_table[BYTE_XOR_BE(zoomy)] && zoom_table[BYTE_XOR_BE(zoomx)]) /* Avoid division-by-zero when table contains 0 (Uninitialised/Bug) */ @@ -1028,57 +1006,56 @@ void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec } -void psikyosh_state::psikyosh_prelineblend( bitmap_rgb32 &bitmap, const rectangle &cliprect ) +void psikyosh_state::prelineblend(bitmap_rgb32 &bitmap, const rectangle &cliprect ) { /* There are 224 values for pre-lineblending. Using one for every row currently */ /* I suspect that it should be blended against black by the amount specified as gnbarich sets the 0x000000ff to 0x7f in test mode whilst the others use 0x80. tgm2 sets it to 0x00 on warning screen. Likely has no effect. */ uint32_t *dstline; - int bank = (m_vidregs[7] & 0xff000000) >> 24; /* bank is always 8 (0x4000) except for daraku/soldivid */ - uint32_t *linefill = &m_bgram[(bank * 0x800) / 4 - 0x4000 / 4]; /* Per row */ - int x, y; + uint8_t const bank = (m_vidregs[7] & 0xff000000) >> 24; /* bank is always 8 (0x4000) except for daraku/soldivid */ + uint32_t *linefill = &m_spriteram->live()[(bank * 0x800) / 4]; /* Per row */ assert(bitmap.bpp() == 32); g_profiler.start(PROFILER_USER8); - for (y = cliprect.min_y; y <= cliprect.max_y; y += 1) { + for (int y = cliprect.top(); y <= cliprect.bottom(); y++) + { dstline = &bitmap.pix32(y); /* linefill[y] & 0xff does what? */ - for (x = cliprect.min_x; x <= cliprect.max_x; x += 1) + for (int x = cliprect.left(); x <= cliprect.right(); x++) dstline[x] = linefill[y] >> 8; } g_profiler.stop(); } -void psikyosh_state::psikyosh_postlineblend( bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ) +void psikyosh_state::postlineblend(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri) { /* There are 224 values for post-lineblending. Using one for every row currently */ uint32_t *dstline; - int bank = (m_vidregs[7] & 0xff000000) >> 24; /* bank is always 8 (i.e. 0x4000) except for daraku/soldivid */ - uint32_t *lineblend = &m_bgram[(bank * 0x800) / 4 - 0x4000 / 4 + 0x400 / 4]; /* Per row */ - int x, y; + uint8_t const bank = (m_vidregs[7] & 0xff000000) >> 24; /* bank is always 8 (i.e. 0x4000) except for daraku/soldivid */ + uint32_t *lineblend = &m_spriteram->live()[(bank * 0x800) / 4 + 0x400 / 4]; /* Per row */ assert(bitmap.bpp() == 32); - if ((m_vidregs[2] & 0xf) != req_pri) { + if ((m_vidregs[2] & 0xf) != req_pri) return; - } g_profiler.start(PROFILER_USER8); - for (y = cliprect.min_y; y <= cliprect.max_y; y += 1) { + for (int y = cliprect.top(); y <= cliprect.bottom(); y++) + { dstline = &bitmap.pix32(y); if (lineblend[y] & 0x80) /* solid */ { - for (x = cliprect.min_x; x <= cliprect.max_x; x += 1) + for (int x = cliprect.left(); x <= cliprect.right(); x++) dstline[x] = lineblend[y] >> 8; } else if (lineblend[y] & 0x7f) /* blended */ { - for (x = cliprect.min_x; x <= cliprect.max_x; x += 1) + for (int x = cliprect.left(); x <= cliprect.right(); x++) dstline[x] = alpha_blend_r32(dstline[x], lineblend[y] >> 8, 2 * (lineblend[y] & 0x7f)); } } @@ -1088,29 +1065,30 @@ void psikyosh_state::psikyosh_postlineblend( bitmap_rgb32 &bitmap, const rectang void psikyosh_state::video_start() { - uint8_t *alphatable = m_alphatable; - m_screen->register_screen_bitmap(m_z_bitmap); /* z-buffer */ m_zoom_bitmap.allocate(16*16, 16*16); /* temp buffer for assembling sprites */ m_bg_bitmap.allocate(32*16, 32*16); /* temp buffer for assembling tilemaps */ m_bg_zoom = std::make_unique<uint16_t[]>(256); + m_alphatable = std::make_unique<uint8_t[]>(256); m_gfxdecode->gfx(1)->set_granularity(16); /* 256 colour sprites with palette selectable on 16 colour boundaries */ /* Pens 0xc0-0xff have a gradient of alpha values associated with them */ int i; - for (i = 0; i < 0xc0; i++) { - alphatable[i] = 0xff; + for (i = 0; i < 0xc0; i++) + { + m_alphatable[i] = 0xff; } for (i = 0; i < 0x40; i++) { int alpha = pal6bit(0x3f - i); - alphatable[i + 0xc0] = alpha; + m_alphatable[i + 0xc0] = alpha; } /* precompute the background zoom table. verified against hardware. unsure of the precision, we use .10 fixed point like the sprites */ - for(i = 0; i < 0x100; i++) { + for (i = 0; i < 0x100; i++) + { m_bg_zoom[i] = (64 * 0x400) / (i + 64); } @@ -1121,7 +1099,7 @@ void psikyosh_state::video_start() } -uint32_t psikyosh_state::screen_update_psikyosh(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)/* Note the z-buffer on each sprite to get correct priority */ +uint32_t psikyosh_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)/* Note the z-buffer on each sprite to get correct priority */ { int i; @@ -1133,16 +1111,16 @@ uint32_t psikyosh_state::screen_update_psikyosh(screen_device &screen, bitmap_rg #ifdef DEBUG_KEYS for (i = 0; i <= 7; i++) { - if(machine().input().code_pressed(pri_keys[i])) { + if (machine().input().code_pressed(pri_keys[i])) pri_debug = true; - } + } - if(machine().input().code_pressed(KEYCODE_G)) { + if (machine().input().code_pressed(KEYCODE_G)) sprites = false; - } - if(machine().input().code_pressed(KEYCODE_H)) { + + if (machine().input().code_pressed(KEYCODE_H)) backgrounds = false; - } + #endif #ifdef DEBUG_MESSAGE @@ -1155,18 +1133,18 @@ popmessage ("%08x %08x %08x %08x\n%08x %08x %08x %08x", m_z_bitmap.fill(0, cliprect); /* z-buffer */ - psikyosh_prelineblend(bitmap, cliprect); // fills screen + prelineblend(bitmap, cliprect); // fills screen for (i = 0; i <= 7; i++) { - if(!pri_debug || machine().input().code_pressed(pri_keys[i])) + if (!pri_debug || machine().input().code_pressed(pri_keys[i])) { - if(sprites) { + if (sprites) draw_sprites(bitmap, cliprect, i); // When same priority bg's have higher pri - } - if(backgrounds) { + + if (backgrounds) draw_background(bitmap, cliprect, i); - } - psikyosh_postlineblend(bitmap, cliprect, i); // assume this has highest priority at same priority level + + postlineblend(bitmap, cliprect, i); // assume this has highest priority at same priority level } } return 0; |