psikyosh.cpp : Updates, Cleanups (#4354)

* psikyosh.cpp : Updates, Cleanups
Make tilemap draw routine related to cliprect, Fix tilemap size when enabled per-line effects, Remove MCFGs, ACCESSING_BITS, Runtime tag lookups, Minor code style fixes, Add seperated address map related to mahjong controller, Fix namings, Reduce unnecessary values / handlers, Add notes, Convert some arrays into std::unique_ptr, Fix some spacing
ymf278b.cpp : devcb3

* psikyosh.cpp : More fix namings, Add constant values instead macro
This commit is contained in:
cam900 2019-04-01 05:55:17 +09:00 committed by R. Belmont
parent d5344a7bba
commit 2dc938da29
3 changed files with 283 additions and 301 deletions

View File

@ -229,8 +229,8 @@ Psikyo PS5V2 hardware readme
Dragon Blaze, Psikyo, 2000 Dragon Blaze, Psikyo, 2000
Gunbarich, Psikyo, 2001 Gunbarich, Psikyo, 2001
Tetris The Grand Master 2 , Psikyo, 2000 Tetris The Grand Master 2, Arika / Psikyo, 2000
Tetris The Grand Master 2+, Psikyo, 2000 Tetris The Grand Master 2+, Arika / Psikyo, 2000
Mahjong G-Taste, Psikyo, 2002 Mahjong G-Taste, Psikyo, 2002
PCB Layout PCB Layout
@ -310,40 +310,24 @@ static GFXDECODE_START( gfx_psikyosh )
GFXDECODE_ENTRY( "gfx1", 0, layout_16x16x8, 0x000, 0x100 ) // 8bpp tiles GFXDECODE_ENTRY( "gfx1", 0, layout_16x16x8, 0x000, 0x100 ) // 8bpp tiles
GFXDECODE_END 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 & 0x20) ? 1 : 0);
{ m_eeprom->cs_write((data & 0x80) ? ASSERT_LINE : CLEAR_LINE);
m_eeprom->di_write((data & 0x20000000) ? 1 : 0); m_eeprom->clk_write((data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
m_eeprom->cs_write((data & 0x80000000) ? ASSERT_LINE : CLEAR_LINE);
m_eeprom->clk_write((data & 0x40000000) ? ASSERT_LINE : CLEAR_LINE);
return; if (data & ~0xe0)
} logerror("Unk EEPROM write %x mask %x\n", data, mem_mask);
logerror("Unk EEPROM write %x mask %x\n", data, mem_mask);
} }
READ32_MEMBER(psikyosh_state::psh_eeprom_r) INTERRUPT_GEN_MEMBER(psikyosh_state::interrupt)
{
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)
{ {
device.execute().set_input_line(4, ASSERT_LINE); device.execute().set_input_line(4, ASSERT_LINE);
} }
// VBL handler writes 0x00 on entry, 0xc0 on exit // VBL handler writes 0x00 on entry, 0xc0 on exit
// bit 0 controls game speed on readback, mechanism is a little weird // 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)) 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 (offset == 4) /* Configure bank for gfx test */
{ {
if (ACCESSING_BITS_0_15) // Bank if ((old ^ data) & 0xfff) // Bank
membank("gfxbank")->set_entry(m_vidregs[offset] & 0xfff); m_gfxrombank->set_entry(data & 0xfff);
} }
} }
@ -416,10 +401,11 @@ P1KEY11 29|30 P2KEY11
GND 55|56 GND GND 55|56 GND
*/ */
uint32_t controls = ioport("CONTROLLER")->read(); uint32_t const controls = m_controller_io->read();
uint32_t value = ioport("INPUTS")->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 // 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 // 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. // 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 KEY11 | KEY6, // Ron
KEY1 | KEY3 // Start KEY1 | KEY3 // Start
}; // generic Mahjong keyboard encoder, corresponds to ordering in input port }; // 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; uint32_t which_key = 0x1;
int count = 0; int count = 0;
// HACK: read IPT_START1 from "INPUTS" to avoid listing it twice or having two independent STARTs listed // 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 keys |= start_depressed ? 1 << (ARRAY_LENGTH(key_codes) - 1) : 0; // and bung it in at the end
value |= 0xFFFF0000; // set top word value |= 0xFFFF0000; // set top word
do { do {
// since we can't handle multiple keys, just return the first one depressed // 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 value &= ~((uint32_t)(key_codes[count]) << 16); // mask in selected word as IP_ACTIVE_LOW
break; break;
} }
@ -493,12 +480,11 @@ void psikyosh_state::ps3v1_map(address_map &map)
map(0x00000000, 0x000fffff).rom(); // program ROM (1 meg) map(0x00000000, 0x000fffff).rom(); // program ROM (1 meg)
map(0x02000000, 0x020fffff).rom().region("maincpu", 0x100000); // data ROM map(0x02000000, 0x020fffff).rom().region("maincpu", 0x100000); // data ROM
// video chip // video chip
map(0x03000000, 0x03003fff).ram().share("spriteram"); // video banks0-7 (sprites and sprite list) map(0x03000000, 0x0300ffff).ram().share("spriteram"); // sprite and backgrounds are share this area (video banks 0-1f)
map(0x03004000, 0x0300ffff).ram().share("bgram"); // video banks 7-0x1f (backgrounds and other effects)
map(0x03040000, 0x03044fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette"); // palette.. 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(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(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::psikyosh_vidregs_w)).share("vidregs"); // video registers 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 map(0x03060000, 0x0307ffff).bankr("gfxbank"); // data for rom tests (gfx), data is controlled by vidreg
// rom mapping // rom mapping
map(0x04060000, 0x0407ffff).bankr("gfxbank"); // data for rom tests (gfx) (Mirrored?) 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)); map(0x05000000, 0x05000007).rw("ymf", FUNC(ymf278b_device::read), FUNC(ymf278b_device::write));
// inputs/eeprom // inputs/eeprom
map(0x05800000, 0x05800003).portr("INPUTS"); 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 // ram
map(0x06000000, 0x060fffff).ram().share("ram"); // main RAM (1 meg) 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) map(0x00000000, 0x000fffff).rom(); // program ROM (1 meg)
// inputs/eeprom // inputs/eeprom
map(0x03000000, 0x03000003).portr("INPUTS"); 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 // sound chip
map(0x03100000, 0x03100007).rw("ymf", FUNC(ymf278b_device::read), FUNC(ymf278b_device::write)); map(0x03100000, 0x03100007).rw("ymf", FUNC(ymf278b_device::read), FUNC(ymf278b_device::write));
// video chip // video chip
map(0x04000000, 0x04003fff).ram().share("spriteram"); // video banks0-7 (sprites and sprite list) map(0x04000000, 0x0400ffff).ram().share("spriteram"); // sprite and backgrounds are share this area (video banks 0-1f)
map(0x04004000, 0x0400ffff).ram().share("bgram"); // video banks 7-0x1f (backgrounds and other effects)
map(0x04040000, 0x04044fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette"); map(0x04040000, 0x04044fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
map(0x04050000, 0x040501ff).ram().share("zoomram"); // sprite zoom lookup table 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(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::psikyosh_vidregs_w)).share("vidregs"); // video registers 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 map(0x04060000, 0x0407ffff).bankr("gfxbank"); // data for rom tests (gfx), data is controlled by vidreg
// rom mapping // rom mapping
map(0x05000000, 0x0507ffff).rom().region("maincpu", 0x100000); // data ROM 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"); 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 ) static INPUT_PORTS_START( common )
PORT_START("INPUTS") PORT_START("INPUTS")
@ -773,7 +768,7 @@ INPUT_PORTS_END
void psikyosh_state::machine_start() 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 */ /* basic machine hardware */
SH2(config, m_maincpu, MASTER_CLOCK/2); SH2(config, m_maincpu, MASTER_CLOCK/2);
m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps3v1_map); 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"); WATCHDOG_TIMER(config, "watchdog");
@ -795,8 +790,8 @@ void psikyosh_state::psikyo3v1(machine_config &config)
m_screen->set_refresh_hz(60); m_screen->set_refresh_hz(60);
m_screen->set_size(64*8, 32*8); m_screen->set_size(64*8, 32*8);
m_screen->set_visarea(0, 40*8-1, 0, 28*8-1); 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->set_screen_update(FUNC(psikyosh_state::screen_update));
m_screen->screen_vblank().set("spriteram", FUNC(buffered_spriteram32_device::vblank_copy_rising)); m_screen->screen_vblank().set(m_spriteram, FUNC(buffered_spriteram32_device::vblank_copy_rising));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_psikyosh); GFXDECODE(config, m_gfxdecode, m_palette, gfx_psikyosh);
PALETTE(config, m_palette).set_format(palette_device::RGBx_888, 0x5000 / 4); 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(); SPEAKER(config, "mono").front_center();
ymf278b_device &ymf(YMF278B(config, "ymf", MASTER_CLOCK/2)); 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); ymf.add_route(ALL_OUTPUTS, "mono", 1.0);
} }
void psikyosh_state::psikyo5(machine_config &config) void psikyosh_state::psikyo5(machine_config &config)
{ {
psikyo3v1(config); psikyo3v1(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps5_map); m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps5_map);
} }
void psikyosh_state::psikyo5_mahjong(machine_config &config)
{
psikyo5(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps5_mahjong_map);
}
void psikyosh_state::psikyo5_240(machine_config &config) void psikyosh_state::psikyo5_240(machine_config &config)
{ {
psikyo3v1(config); psikyo5(config);
m_maincpu->set_addrmap(AS_PROGRAM, &psikyosh_state::ps5_map);
/* Measured Hsync 16.165 KHz, Vsync 61.68 Hz */ /* 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 */ /* 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() void psikyosh_state::init_ps3()
{ {
m_maincpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); 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(0x03050000, 0x030501ff, 0, &m_zoomram[0]);
m_maincpu->sh2drc_add_fastram(0x06000000, 0x060fffff, 0, &m_ram[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() void psikyosh_state::init_ps5()
{ {
m_maincpu->sh2drc_set_options(SH2DRC_FASTEST_OPTIONS); 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(0x04050000, 0x040501ff, 0, &m_zoomram[0]);
m_maincpu->sh2drc_add_fastram(0x06000000, 0x060fffff, 0, &m_ram[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 */ // YEAR NAME PARENT MACHINE INPUT STATE INIT MONITOR COMPANY FULLNAME FLAGS */
/* ps3-v1 */ /* 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, 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, 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( 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, 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, 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( 1998, sbombera, sbomber, psikyo3v1, sbomberb, psikyosh_state, init_ps3, ROT270, "Psikyo", "Space Bomber", MACHINE_SUPPORTS_SAVE )
/* ps5 */ /* ps5 */
GAME( 1998, gunbird2, 0, psikyo5, gunbird2, psikyosh_state, init_ps5, ROT270, "Psikyo", "Gunbird 2 (set 1)", 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( 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( 1999, s1945iii, 0, psikyo5, s1945iii, psikyosh_state, init_ps5, ROT270, "Psikyo", "Strikers 1945 III (World) / Strikers 1999 (Japan)", MACHINE_SUPPORTS_SAVE )
/* ps5v2 */ /* ps5v2 */
GAME( 2000, dragnblz, 0, psikyo5, dragnblz, psikyosh_state, init_ps5, ROT270, "Psikyo", "Dragon Blaze", 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, 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( 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( 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( 2002, mjgtaste, 0, psikyo5_mahjong, mjgtaste, psikyosh_state, init_ps5, ROT0, "Psikyo", "Mahjong G-Taste", MACHINE_SUPPORTS_SAVE )

View File

@ -15,18 +15,7 @@
#define MASTER_CLOCK 57272700 // main oscillator frequency #define MASTER_CLOCK 57272700 // main oscillator frequency
/* Psikyo PS6406B */ /* 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 class psikyosh_state : public driver_device
@ -34,11 +23,14 @@ class psikyosh_state : public driver_device
public: public:
psikyosh_state(const machine_config &mconfig, device_type type, const char *tag) : psikyosh_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag), driver_device(mconfig, type, tag),
m_spriteram(*this, "spriteram") , m_spriteram(*this, "spriteram"),
m_bgram(*this, "bgram"),
m_zoomram(*this, "zoomram"), m_zoomram(*this, "zoomram"),
m_vidregs(*this, "vidregs"), m_vidregs(*this, "vidregs"),
m_ram(*this, "ram"), 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_maincpu(*this, "maincpu"),
m_eeprom(*this, "eeprom"), m_eeprom(*this, "eeprom"),
m_gfxdecode(*this, "gfxdecode"), m_gfxdecode(*this, "gfxdecode"),
@ -48,26 +40,31 @@ public:
void psikyo3v1(machine_config &config); void psikyo3v1(machine_config &config);
void psikyo5(machine_config &config); void psikyo5(machine_config &config);
void psikyo5_mahjong(machine_config &config);
void psikyo5_240(machine_config &config); void psikyo5_240(machine_config &config);
void init_ps3(); void init_ps3();
void init_ps5(); void init_ps5();
void init_mjgtaste();
private: private:
/* memory pointers */ /* memory pointers */
required_device<buffered_spriteram32_device> m_spriteram; 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_zoomram;
required_shared_ptr<uint32_t> m_vidregs; required_shared_ptr<uint32_t> m_vidregs;
required_shared_ptr<uint32_t> m_ram; 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 */ /* video-related */
bitmap_ind8 m_zoom_bitmap; bitmap_ind8 m_zoom_bitmap;
bitmap_ind16 m_z_bitmap; bitmap_ind16 m_z_bitmap;
bitmap_rgb32 m_bg_bitmap; bitmap_rgb32 m_bg_bitmap;
std::unique_ptr<uint16_t[]> m_bg_zoom; std::unique_ptr<uint16_t[]> m_bg_zoom;
uint8_t m_alphatable[256]; std::unique_ptr<uint8_t[]> m_alphatable;
/* devices */ /* devices */
required_device<sh2_device> m_maincpu; required_device<sh2_device> m_maincpu;
@ -76,30 +73,41 @@ private:
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
required_device<palette_device> m_palette; required_device<palette_device> m_palette;
DECLARE_WRITE32_MEMBER(psikyosh_irqctrl_w); bool const FLIPSCREEN() { return ((m_vidregs[3] & 0x0000c000) == 0x0000c000); } // currently ignored
DECLARE_WRITE32_MEMBER(psikyosh_vidregs_w);
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_READ32_MEMBER(mjgtaste_input_r);
DECLARE_WRITE32_MEMBER(psh_eeprom_w); DECLARE_WRITE8_MEMBER(eeprom_w);
DECLARE_READ32_MEMBER(psh_eeprom_r);
virtual void machine_start() override; virtual void machine_start() override;
virtual void video_start() override; virtual void video_start() override;
uint32_t screen_update_psikyosh(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(psikyosh_interrupt); 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_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_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_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 draw_bglayer(uint8_t const layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri);
void cache_bitmap(int scanline, gfx_element *gfx, int size, int tilebank, int alpha, int *last_bank); 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( int layer, bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ); 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 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 req_pri); void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t const req_pri);
void psikyosh_prelineblend( bitmap_rgb32 &bitmap, const rectangle &cliprect ); void prelineblend(bitmap_rgb32 &bitmap, const rectangle &cliprect );
void psikyosh_postlineblend( bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t req_pri ); 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, 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, uint32_t const code, uint16_t const color, uint8_t const flipx, uint8_t const flipy, int16_t const offsx, int16_t const offsy,
int alpha, int zoomx, int zoomy, int wide, int high, uint32_t z); 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 ps3v1_map(address_map &map);
void ps5_map(address_map &map); void ps5_map(address_map &map);
void ps5_mahjong_map(address_map &map);
}; };
#endif // MAME_INCLUDES_PSIKYOSH_H #endif // MAME_INCLUDES_PSIKYOSH_H

View File

@ -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 "drawgfxm.h"
#include "includes/psikyosh.h" #include "includes/psikyosh.h"
static constexpr uint32_t BG_TRANSPEN = 0x00ff00ff; // used for representing transparency in temporary bitmaps
//#define DEBUG_KEYS //#define DEBUG_KEYS
//#define DEBUG_MESSAGE //#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. /* 'Normal' layers, no line/columnscroll. No per-line effects.
Zooming isn't supported just because it's not used and it would be slow */ 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)); assert(!BG_LINE(layer));
gfx = BG_DEPTH_8BPP(layer) ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0); gfx_element *gfx = BG_DEPTH_8BPP(layer) ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0);
size = BG_LARGE(layer) ? 32 : 16; uint8_t const size = BG_LARGE(layer) ? 32 : 16;
width = 16 * size; 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; uint16_t const scrollx = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x3f0 / 4 + (layer * 0x04) / 4] & 0x000001ff) >> 0;
scrolly = (m_bgram[(regbank * 0x800) / 4 + 0x3f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x03ff0000) >> 16; 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; uint8_t const tilebank = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x000000ff) >> 0;
alpha = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x00003f00) >> 8; int16_t alpha = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x00003f00) >> 8;
alphamap = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x00008000) >> 15; uint8_t const alphamap = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x00008000) >> 15;
zoom = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0x00ff0000) >> 16; uint8_t const zoom = (m_spriteram->live()[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4] & 0x00ff0000) >> 16;
pri = (m_bgram[(regbank * 0x800) / 4 + 0x7f0 / 4 + (layer * 0x04) / 4 - 0x4000 / 4] & 0xff000000) >> 24; 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 */ if (alphamap) /* alpha values are per-pen */
alpha = -1; alpha = -1;
else else
alpha = pal6bit(0x3f - alpha); /* 0x3f-0x00 maps to 0x00-0xff */ alpha = pal6bit(0x3f - alpha); /* 0x3f-0x00 maps to 0x00-0xff */
if(zoom) { if (zoom)
popmessage("draw_bglayer() zoom not implemented\nContact MAMEDEV"); popmessage("draw_bglayer() zoom not implemented\nContact MAMEDEV");
}
if ((tilebank >= 0x0a) && (tilebank <= 0x1f)) /* 20 banks of 0x800 bytes. filter garbage. */ 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 */ gfx->alphatable(bitmap, cliprect, tileno, colour, 0, 0, (16 * sx) + (scrollx & 0xf), (16 * sy) + (scrolly & 0xf), alpha, m_alphatable.get()); /* normal */
colour = (m_bgram[(tilebank * 0x800) / 4 + offs - 0x4000 / 4] & 0xff000000) >> 24;
gfx->alphatable(bitmap, cliprect, tileno, colour, 0, 0, (16 * sx + scrollx) & 0x1ff, ((16 * sy + scrolly) & (width - 1)), alpha, m_alphatable); /* normal */ basex++;
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++;
} }
basey = ((basey + 1) & ((height >> 4) - 1));
} }
} }
} }
/* populate bg_bitmap for the given bank if it's not already */ /* 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 // 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); assert(sy >= 0 && sy < 32);
if(tilebank != last_bank[sy]) if (tilebank != last_bank[sy])
{ {
rectangle cliprect; rectangle cliprect;
int minsy = sy * 16; uint16_t const minsy = sy * 16;
int maxsy = minsy + 16 - 1; uint16_t const maxsy = minsy + 16 - 1;
cliprect.set(0, m_bg_bitmap.width() - 1, minsy, maxsy ); cliprect.set(0, m_bg_bitmap.width() - 1, minsy, maxsy );
cliprect &= m_bg_bitmap.cliprect(); cliprect &= m_bg_bitmap.cliprect();
m_bg_bitmap.fill(BG_TRANSPEN, cliprect); m_bg_bitmap.fill(BG_TRANSPEN, cliprect);
int width = size * 16; uint16_t const height = size * 16;
int offs = size * sy; uint32_t offs = 32 * sy;
int sx; for (int sx = 0; sx < 32; sx++)
for (sx = 0; sx < 32; sx++)
{ {
int tileno, colour; 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;
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;
int need_alpha = alpha < 0 ? -1 : 0xff; // store per-pen alpha in bitmap, otherwise don't since we'll need it per-line 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? 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); 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++; 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). 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 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 */ 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)); assert(BG_LINE(layer));
gfx_element *gfx = BG_DEPTH_8BPP(layer) ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0); gfx_element *gfx = BG_DEPTH_8BPP(layer) ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0);
int size = BG_LARGE(layer) ? 32 : 16; uint8_t const size = BG_LARGE(layer) ? 32 : 16;
int width = size * 16; uint16_t const height = size * 16;
int linebank = BG_TYPE(layer); uint8_t linebank = BG_TYPE(layer);
/* cache rendered bitmap */ /* 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 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; for (auto & elem : last_bank) elem = -1;
int scr_width = cliprect.width(); int scr_width = cliprect.width();
int scr_height = cliprect.height(); uint32_t *scroll_reg = &m_spriteram->live()[(linebank * 0x800) / 4 + cliprect.top()];
uint32_t *scroll_reg = &m_bgram[(linebank * 0x800) / 4 - 0x4000 / 4]; uint32_t *pzab_reg = &m_spriteram->live()[(linebank * 0x800) / 4 + cliprect.top() + 0x400 / 4]; // pri, zoom, alpha, bank
uint32_t *pzab_reg = &m_bgram[(linebank * 0x800) / 4 - 0x4000 / 4 + 0x400 / 4]; // pri, zoom, alpha, bank
// now, for each scanline, check priority, // now, for each scanline, check priority,
// extract the relevant scanline from the bitmap, after applying per-scanline vscroll, // extract the relevant scanline from the bitmap, after applying per-scanline vscroll,
// stretch it and scroll it into another buffer // stretch it and scroll it into another buffer
// write it with alpha // 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; uint16_t const scrollx = (*scroll_reg & 0x000001ff) >> 0;
int scrolly = (*scroll_reg & 0x03ff0000) >> 16; uint16_t const scrolly = (*scroll_reg & 0x03ff0000) >> 16;
int zoom = (*pzab_reg & 0x00ff0000) >> 16; uint8_t const zoom = (*pzab_reg & 0x00ff0000) >> 16;
int alphamap = (*pzab_reg & 0x00008000) >> 15; uint8_t const alphamap = (*pzab_reg & 0x00008000) >> 15;
int alpha = (*pzab_reg & 0x00003f00) >> 8; int16_t alpha = (*pzab_reg & 0x00003f00) >> 8;
int tilebank = (*pzab_reg & 0x000000ff) >> 0; uint8_t const tilebank = (*pzab_reg & 0x000000ff) >> 0;
if(alphamap) /* alpha values are per-pen */ if (alphamap) /* alpha values are per-pen */
alpha = -1; alpha = -1;
else else
alpha = pal6bit(0x3f - alpha); alpha = pal6bit(0x3f - alpha);
if ((tilebank >= 0x0a) && (tilebank <= 0x1f)) /* 20 banks of 0x800 bytes. filter garbage. */ 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 // 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); 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); g_profiler.start(PROFILER_USER2);
uint32_t tilemap_line[32 * 16]; uint32_t tilemap_line[32 * 16];
uint32_t scr_line[64 * 8]; 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(); g_profiler.stop();
/* slow bit, needs optimising. apply scrollx and zoomx by assembling scanline from row */ /* slow bit, needs optimising. apply scrollx and zoomx by assembling scanline from row */
g_profiler.start(PROFILER_USER3); g_profiler.start(PROFILER_USER3);
if(zoom) { if (zoom)
int step = m_bg_zoom[zoom]; {
int jj = 0x400 << 10; // ensure +ve for mod uint16_t const step = m_bg_zoom[zoom];
for(int ii = 0; ii < scr_width; ii++) { int jj = (0x400 << 10) + (step * cliprect.left()); // ensure +ve for mod
scr_line[ii] = tilemap_line[((jj>>10) - scrollx) % width]; for (int ii = cliprect.left(); ii <= cliprect.right(); ii++)
{
scr_line[ii] = tilemap_line[((jj>>10) - scrollx) & 0x1ff];
jj += step; jj += step;
} }
} }
else { else
for(int ii = 0; ii < scr_width; ii++) { {
scr_line[ii] = tilemap_line[(ii - scrollx + 0x400) % width]; for (int ii = cliprect.left(); ii <= cliprect.right(); ii++)
} scr_line[ii] = tilemap_line[(ii - scrollx + 0x400) & 0x1ff];
} }
g_profiler.stop(); g_profiler.stop();
/* blend line into output */ /* blend line into output */
g_profiler.start(PROFILER_USER4); g_profiler.start(PROFILER_USER4);
if(alpha == 0xff) { if (alpha == 0xff)
draw_scanline32_transpen(bitmap, 0, scanline, scr_width, scr_line); draw_scanline32_transpen(bitmap, cliprect.left(), scanline, scr_width, &scr_line[cliprect.left()]);
} else if (alpha > 0)
else if (alpha > 0) { draw_scanline32_alpha(bitmap, cliprect.left(), scanline, scr_width, &scr_line[cliprect.left()], alpha);
draw_scanline32_alpha(bitmap, 0, scanline, scr_width, scr_line, alpha); else if (alpha < 0)
} draw_scanline32_argb(bitmap, cliprect.left(), scanline, scr_width, &scr_line[cliprect.left()]);
else if (alpha < 0) {
draw_scanline32_argb(bitmap, 0, scanline, scr_width, scr_line);
}
g_profiler.stop(); g_profiler.stop();
} }
} }
@ -342,7 +328,7 @@ void psikyosh_state::draw_bglayerscroll( int layer, bitmap_rgb32 &bitmap, const
} }
/* 3 BG layers, with priority */ /* 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; int i;
@ -351,9 +337,9 @@ void psikyosh_state::draw_background( bitmap_rgb32 &bitmap, const rectangle &cli
bool lay_debug = false; bool lay_debug = false;
for (i = 0; i <= 3; i++) 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; lay_debug = true;
}
} }
#endif #endif
@ -361,21 +347,18 @@ void psikyosh_state::draw_background( bitmap_rgb32 &bitmap, const rectangle &cli
for (i = 0; i <= 3; i++) for (i = 0; i <= 3; i++)
{ {
#ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
if(lay_debug && !machine().input().code_pressed(lay_keys[i])) if (lay_debug && !machine().input().code_pressed(lay_keys[i]))
continue; continue;
#endif #endif
if (!BG_LAYER_ENABLE(i)) if (!BG_LAYER_ENABLE(i))
continue; continue;
if(BG_LINE(i)) { if (BG_LINE(i)) /* per-line alpha, scroll, zoom etc. check the priority for the first scanline */
/* per-line alpha, scroll, zoom etc. check the priority for the first scanline */
draw_bglayerscroll(i, bitmap, cliprect, req_pri); 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); 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 */ /* 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 */ /* 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] */ /* 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, 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, uint32_t const code, uint16_t const color, uint8_t const flipx, uint8_t const flipy, int16_t const offsx, int16_t const offsy,
int alpha, int zoomx, int zoomy, int wide, int high, uint32_t z) 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 */ rectangle myclip; /* Clip to screen boundaries */
int code_offset = 0; int code_offset = 0;
int xtile, ytile, xpixel, ypixel; int xtile, ytile, xpixel, ypixel;
@ -445,27 +427,27 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang
ex = sx + gfx->width(); ex = sx + gfx->width();
ey = sy + gfx->height(); ey = sy + gfx->height();
if (sx < myclip.min_x) if (sx < myclip.left())
{ /* clip left */ { /* clip left */
int pixels = myclip.min_x - sx; int pixels = myclip.left() - sx;
sx += pixels; sx += pixels;
x_index_base += xinc * pixels; x_index_base += xinc * pixels;
} }
if (sy < myclip.min_y) if (sy < myclip.top())
{ /* clip top */ { /* clip top */
int pixels = myclip.min_y - sy; int pixels = myclip.top() - sy;
sy += pixels; sy += pixels;
y_index += yinc * pixels; y_index += yinc * pixels;
} }
/* NS 980211 - fixed incorrect clipping */ /* NS 980211 - fixed incorrect clipping */
if (ex > myclip.max_x + 1) if (ex > myclip.right() + 1)
{ /* clip right */ { /* clip right */
int pixels = ex - myclip.max_x - 1; int pixels = ex - myclip.right() - 1;
ex -= pixels; ex -= pixels;
} }
if (ey > myclip.max_y + 1) if (ey > myclip.bottom() + 1)
{ /* clip bottom */ { /* clip bottom */
int pixels = ey - myclip.max_y - 1; int pixels = ey - myclip.bottom() - 1;
ey -= pixels; ey -= pixels;
} }
@ -613,10 +595,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang
int c = *source; int c = *source;
if (c != 0) if (c != 0)
{ {
if (alphatable[c] == 0xff) if (m_alphatable[c] == 0xff)
*dest = pal[c]; *dest = pal[c];
else else
*dest = alpha_blend_r32(*dest, pal[c], alphatable[c]); *dest = alpha_blend_r32(*dest, pal[c], m_alphatable[c]);
*pri = z; *pri = z;
} }
@ -645,10 +627,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang
int c = *source; int c = *source;
if (c != 0) if (c != 0)
{ {
if (alphatable[c] == 0xff) if (m_alphatable[c] == 0xff)
*dest = pal[c]; *dest = pal[c];
else else
*dest = alpha_blend_r32(*dest, pal[c], alphatable[c]); *dest = alpha_blend_r32(*dest, pal[c], m_alphatable[c]);
} }
dest++; dest++;
source += xinc; 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; } if (flipy) { y_index = (sprite_screen_height - 1) * zoomy; dy = -zoomy; }
else { y_index = 0; dy = zoomy; } else { y_index = 0; dy = zoomy; }
if (sx < myclip.min_x) if (sx < myclip.left())
{ /* clip left */ { /* clip left */
int pixels = myclip.min_x - sx; int pixels = myclip.left() - sx;
sx += pixels; sx += pixels;
x_index_base += pixels * dx; x_index_base += pixels * dx;
} }
if (sy < myclip.min_y) if (sy < myclip.top())
{ /* clip top */ { /* clip top */
int pixels = myclip.min_y - sy; int pixels = myclip.top() - sy;
sy += pixels; sy += pixels;
y_index += pixels * dy; y_index += pixels * dy;
} }
/* NS 980211 - fixed incorrect clipping */ /* NS 980211 - fixed incorrect clipping */
if (ex > myclip.max_x + 1) if (ex > myclip.right() + 1)
{ /* clip right */ { /* clip right */
int pixels = ex-myclip.max_x - 1; int pixels = ex-myclip.right() - 1;
ex -= pixels; ex -= pixels;
} }
if (ey > myclip.max_y + 1) if (ey > myclip.bottom() + 1)
{ /* clip bottom */ { /* clip bottom */
int pixels = ey-myclip.max_y - 1; int pixels = ey-myclip.bottom() - 1;
ey -= pixels; ey -= pixels;
} }
@ -862,10 +844,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang
int c = source[x_index >> 10]; int c = source[x_index >> 10];
if (c != 0) if (c != 0)
{ {
if (alphatable[c] == 0xff) if (m_alphatable[c] == 0xff)
dest[x] = pal[c]; dest[x] = pal[c];
else 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; pri[x] = z;
} }
@ -889,10 +871,10 @@ void psikyosh_state:: psikyosh_drawgfxzoom( bitmap_rgb32 &dest_bmp,const rectang
int c = source[x_index >> 10]; int c = source[x_index >> 10];
if (c != 0) if (c != 0)
{ {
if (alphatable[c] == 0xff) if (m_alphatable[c] == 0xff)
dest[x] = pal[c]; dest[x] = pal[c];
else 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; 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 -** /*- Sprite Format 0x0000 - 0x37ff -**
@ -948,9 +930,9 @@ void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec
#ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
for (int i = 0; i <= 3; i++) 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; spr_debug = true;
}
} }
#endif #endif
@ -965,42 +947,38 @@ void psikyosh_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec
uint16_t listcntr = 0; uint16_t listcntr = 0;
while (listcntr < listlen) while (listcntr < listlen)
{ {
uint32_t listdat, sprnum, xpos, ypos, high, wide, flpx, flpy, zoomx, zoomy, tnum, colr, dpth; uint16_t const listdat = list[BYTE_XOR_BE(listcntr)];
uint8_t bg_pri, spr_pri, alphamap; uint16_t const sprnum = (listdat & 0x03ff) * 4;
int alpha;
listdat = list[BYTE_XOR_BE(listcntr)]; uint8_t bg_pri = (src[sprnum + 1] & 0x00003000) >> 12;
sprnum = (listdat & 0x03ff) * 4;
bg_pri = (src[sprnum + 1] & 0x00003000) >> 12;
bg_pri = SPRITE_PRI(bg_pri); bg_pri = SPRITE_PRI(bg_pri);
// sprite vs backgrounds pri // sprite vs backgrounds pri
if (bg_pri == req_pri) if (bg_pri == req_pri)
{ {
ypos = (src[sprnum + 0] & 0x03ff0000) >> 16; int16_t ypos = (src[sprnum + 0] & 0x03ff0000) >> 16;
xpos = (src[sprnum + 0] & 0x000003ff) >> 00; int16_t xpos = (src[sprnum + 0] & 0x000003ff) >> 00;
if (ypos & 0x200) ypos -= 0x400; if (ypos & 0x200) ypos -= 0x400;
if (xpos & 0x200) xpos -= 0x400; if (xpos & 0x200) xpos -= 0x400;
high = ((src[sprnum + 1] & 0x0f000000) >> 24) + 1; uint8_t const high = ((src[sprnum + 1] & 0x0f000000) >> 24) + 1;
wide = ((src[sprnum + 1] & 0x00000f00) >> 8) + 1; uint8_t const wide = ((src[sprnum + 1] & 0x00000f00) >> 8) + 1;
flpy = (src[sprnum + 1] & 0x80000000) >> 31; uint8_t const flpy = (src[sprnum + 1] & 0x80000000) >> 31;
spr_pri = (src[sprnum + 1] & 0x30000000) >> 28; uint8_t const spr_pri = (src[sprnum + 1] & 0x30000000) >> 28;
flpx = (src[sprnum + 1] & 0x00008000) >> 15; uint8_t const flpx = (src[sprnum + 1] & 0x00008000) >> 15;
zoomy = (src[sprnum + 1] & 0x00ff0000) >> 16; uint8_t const zoomy = (src[sprnum + 1] & 0x00ff0000) >> 16;
zoomx = (src[sprnum + 1] & 0x000000ff) >> 00; uint8_t const zoomx = (src[sprnum + 1] & 0x000000ff) >> 00;
tnum = (src[sprnum + 2] & 0x0007ffff) >> 00; uint32_t const tnum = (src[sprnum + 2] & 0x0007ffff) >> 00;
dpth = (src[sprnum + 2] & 0x00800000) >> 23; uint8_t const dpth = (src[sprnum + 2] & 0x00800000) >> 23;
colr = (src[sprnum + 2] & 0xff000000) >> 24; 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; alpha = alpha_table[BYTE4_XOR_BE(alpha)] & 0x3f;
gfx = dpth ? m_gfxdecode->gfx(1) : m_gfxdecode->gfx(0); 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 else
alpha = pal6bit(0x3f - alpha); /* 0x3f-0x00 maps to 0x00-0xff */ 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 */ /* 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) */ 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 */ /* 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 /* 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. 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. */ tgm2 sets it to 0x00 on warning screen. Likely has no effect. */
uint32_t *dstline; uint32_t *dstline;
int bank = (m_vidregs[7] & 0xff000000) >> 24; /* bank is always 8 (0x4000) except for daraku/soldivid */ uint8_t const 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 */ uint32_t *linefill = &m_spriteram->live()[(bank * 0x800) / 4]; /* Per row */
int x, y;
assert(bitmap.bpp() == 32); assert(bitmap.bpp() == 32);
g_profiler.start(PROFILER_USER8); 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); dstline = &bitmap.pix32(y);
/* linefill[y] & 0xff does what? */ /* 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; dstline[x] = linefill[y] >> 8;
} }
g_profiler.stop(); 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 */ /* There are 224 values for post-lineblending. Using one for every row currently */
uint32_t *dstline; uint32_t *dstline;
int bank = (m_vidregs[7] & 0xff000000) >> 24; /* bank is always 8 (i.e. 0x4000) except for daraku/soldivid */ uint8_t const 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 */ uint32_t *lineblend = &m_spriteram->live()[(bank * 0x800) / 4 + 0x400 / 4]; /* Per row */
int x, y;
assert(bitmap.bpp() == 32); assert(bitmap.bpp() == 32);
if ((m_vidregs[2] & 0xf) != req_pri) { if ((m_vidregs[2] & 0xf) != req_pri)
return; return;
}
g_profiler.start(PROFILER_USER8); 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); dstline = &bitmap.pix32(y);
if (lineblend[y] & 0x80) /* solid */ 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; dstline[x] = lineblend[y] >> 8;
} }
else if (lineblend[y] & 0x7f) /* blended */ 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)); 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() void psikyosh_state::video_start()
{ {
uint8_t *alphatable = m_alphatable;
m_screen->register_screen_bitmap(m_z_bitmap); /* z-buffer */ m_screen->register_screen_bitmap(m_z_bitmap); /* z-buffer */
m_zoom_bitmap.allocate(16*16, 16*16); /* temp buffer for assembling sprites */ 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_bitmap.allocate(32*16, 32*16); /* temp buffer for assembling tilemaps */
m_bg_zoom = std::make_unique<uint16_t[]>(256); 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 */ 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 */ /* Pens 0xc0-0xff have a gradient of alpha values associated with them */
int i; int i;
for (i = 0; i < 0xc0; i++) { for (i = 0; i < 0xc0; i++)
alphatable[i] = 0xff; {
m_alphatable[i] = 0xff;
} }
for (i = 0; i < 0x40; i++) for (i = 0; i < 0x40; i++)
{ {
int alpha = pal6bit(0x3f - i); int alpha = pal6bit(0x3f - i);
alphatable[i + 0xc0] = alpha; m_alphatable[i + 0xc0] = alpha;
} }
/* precompute the background zoom table. verified against hardware. /* precompute the background zoom table. verified against hardware.
unsure of the precision, we use .10 fixed point like the sprites */ 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); 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; int i;
@ -1133,16 +1111,16 @@ uint32_t psikyosh_state::screen_update_psikyosh(screen_device &screen, bitmap_rg
#ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
for (i = 0; i <= 7; i++) 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; pri_debug = true;
}
} }
if(machine().input().code_pressed(KEYCODE_G)) { if (machine().input().code_pressed(KEYCODE_G))
sprites = false; sprites = false;
}
if(machine().input().code_pressed(KEYCODE_H)) { if (machine().input().code_pressed(KEYCODE_H))
backgrounds = false; backgrounds = false;
}
#endif #endif
#ifdef DEBUG_MESSAGE #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 */ 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++) 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 draw_sprites(bitmap, cliprect, i); // When same priority bg's have higher pri
}
if(backgrounds) { if (backgrounds)
draw_background(bitmap, cliprect, i); 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; return 0;