diff options
author | Angelo Salese <angelosa@users.noreply.github.com> | 2011-03-22 20:57:27 +0000 |
---|---|---|
committer | Angelo Salese <angelosa@users.noreply.github.com> | 2011-03-22 20:57:27 +0000 |
commit | 235b0d2e01aec1e6aa71aeb66ac6d026c169e6ac (patch) | |
tree | 60bc1cd4c4db9ba73470687125424e0c3753932a | |
parent | 4a8673b63966d80b5a60f4f1e0a04872e7ec4bea (diff) |
Moved Kaneko Super Nova sprite chip emulation inside its own file [David Haywood]
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | src/mame/drivers/galpani3.c | 13 | ||||
-rw-r--r-- | src/mame/drivers/jchan.c | 28 | ||||
-rw-r--r-- | src/mame/drivers/suprnova.c | 49 | ||||
-rw-r--r-- | src/mame/includes/suprnova.h | 11 | ||||
-rw-r--r-- | src/mame/mame.mak | 1 | ||||
-rw-r--r-- | src/mame/video/sknsspr.c | 575 | ||||
-rw-r--r-- | src/mame/video/sknsspr.h | 36 | ||||
-rw-r--r-- | src/mame/video/suprnova.c | 556 |
9 files changed, 685 insertions, 586 deletions
diff --git a/.gitattributes b/.gitattributes index f76f30680c5..f9eec5ab0f6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4215,6 +4215,8 @@ src/mame/video/sidepckt.c svneol=native#text/plain src/mame/video/silkroad.c svneol=native#text/plain src/mame/video/simpl156.c svneol=native#text/plain src/mame/video/simpsons.c svneol=native#text/plain +src/mame/video/sknsspr.c svneol=native#text/plain +src/mame/video/sknsspr.h svneol=native#text/plain src/mame/video/skullxbo.c svneol=native#text/plain src/mame/video/skydiver.c svneol=native#text/plain src/mame/video/skyfox.c svneol=native#text/plain diff --git a/src/mame/drivers/galpani3.c b/src/mame/drivers/galpani3.c index 8ab432e6deb..eafaef6a791 100644 --- a/src/mame/drivers/galpani3.c +++ b/src/mame/drivers/galpani3.c @@ -65,9 +65,8 @@ Dumped by Uki #include "cpu/m68000/m68000.h" #include "deprecat.h" #include "sound/ymz280b.h" -#include "includes/suprnova.h" #include "includes/kaneko16.h" - +#include "video/sknsspr.h" class galpani3_state : public driver_device { @@ -115,6 +114,8 @@ public: UINT16 regs1_address_regs[0x20]; UINT16 regs2_address_regs[0x20]; UINT16 regs3_address_regs[0x20]; + + sknsspr_device* spritegen; }; @@ -146,11 +147,11 @@ static VIDEO_START(galpani3) state->spriteram32 = auto_alloc_array(machine, UINT32, 0x4000/4); machine->generic.spriteram_size = 0x4000; state->spc_regs = auto_alloc_array(machine, UINT32, 0x40/4); - suprnova_alt_enable_sprites = 1; - state->sprite_bitmap_1 = auto_bitmap_alloc(machine,1024,1024,BITMAP_FORMAT_INDEXED16); + state->spritegen = machine->device<sknsspr_device>("spritegen"); + state->spritegen->skns_sprite_kludge(0,0); } @@ -346,7 +347,7 @@ static SCREEN_UPDATE(galpani3) bitmap_fill(state->sprite_bitmap_1, cliprect, 0x0000); - skns_draw_sprites(screen->machine, state->sprite_bitmap_1, cliprect, state->spriteram32, screen->machine->generic.spriteram_size, screen->machine->region("gfx1")->base(), screen->machine->region ("gfx1")->bytes(), state->spc_regs ); + state->spritegen->skns_draw_sprites(screen->machine, state->sprite_bitmap_1, cliprect, state->spriteram32, screen->machine->generic.spriteram_size, screen->machine->region("gfx1")->base(), screen->machine->region ("gfx1")->bytes(), state->spc_regs ); // ignoring priority bits for now.. for (y=0;y<240;y++) @@ -963,6 +964,8 @@ static MACHINE_CONFIG_START( galpani3, galpani3_state ) MCFG_VIDEO_START(galpani3) + MCFG_DEVICE_ADD("spritegen", sknsspr_, 0) + /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/drivers/jchan.c b/src/mame/drivers/jchan.c index 455f980012f..d03f9976819 100644 --- a/src/mame/drivers/jchan.c +++ b/src/mame/drivers/jchan.c @@ -172,9 +172,8 @@ there are 9 PALS on the pcb (not dumped) #include "deprecat.h" #include "machine/nvram.h" #include "sound/ymz280b.h" -#include "includes/suprnova.h" #include "includes/kaneko16.h" - +#include "video/sknsspr.h" class jchan_state : public driver_device { @@ -198,20 +197,15 @@ public: UINT16 *mcu_ram; UINT16 mcu_com[4]; UINT16 *ctrl; + + sknsspr_device* spritegen1; + sknsspr_device* spritegen2; }; /*************************************************************************** MCU Code Simulation - (follows the implementation of kaneko16.c) - -Provided we find a working PCB, trojan code will help: -- to get this game working (but there are many #4 sub-commands!) -- to have more patterns and eventualy defeat the MCU 'encryption' -- decapping and manually recovering the interal ROM is being persued - -This will benefit galpani3 and other kaneko16 games with TOYBOX MCU. ***************************************************************************/ @@ -359,7 +353,12 @@ static VIDEO_START(jchan) state->sprite_bitmap_1 = auto_bitmap_alloc(machine,1024,1024,BITMAP_FORMAT_INDEXED16); state->sprite_bitmap_2 = auto_bitmap_alloc(machine,1024,1024,BITMAP_FORMAT_INDEXED16); - suprnova_alt_enable_sprites = 1; + state->spritegen1 = machine->device<sknsspr_device>("spritegen1"); + state->spritegen2 = machine->device<sknsspr_device>("spritegen2"); + + + state->spritegen1->skns_sprite_kludge(0,0); + state->spritegen2->skns_sprite_kludge(0,0); VIDEO_START_CALL( kaneko16_1xVIEW2_tilemaps ); } @@ -387,8 +386,8 @@ static SCREEN_UPDATE(jchan) bitmap_fill(state->sprite_bitmap_1, cliprect, 0x0000); bitmap_fill(state->sprite_bitmap_2, cliprect, 0x0000); - skns_draw_sprites(screen->machine, state->sprite_bitmap_1, cliprect, state->sprite_ram32_1, 0x4000, screen->machine->region("gfx1")->base(), screen->machine->region ("gfx1")->bytes(), state->sprite_regs32_1 ); - skns_draw_sprites(screen->machine, state->sprite_bitmap_2, cliprect, state->sprite_ram32_2, 0x4000, screen->machine->region("gfx2")->base(), screen->machine->region ("gfx2")->bytes(), state->sprite_regs32_2 ); + state->spritegen1->skns_draw_sprites(screen->machine, state->sprite_bitmap_1, cliprect, state->sprite_ram32_1, 0x4000, screen->machine->region("gfx1")->base(), screen->machine->region ("gfx1")->bytes(), state->sprite_regs32_1 ); + state->spritegen2->skns_draw_sprites(screen->machine, state->sprite_bitmap_2, cliprect, state->sprite_ram32_2, 0x4000, screen->machine->region("gfx2")->base(), screen->machine->region ("gfx2")->bytes(), state->sprite_regs32_2 ); // ignoring priority bits for now - might use alpha too, check 0x8000 of palette writes for (y=0;y<240;y++) @@ -690,6 +689,9 @@ static MACHINE_CONFIG_START( jchan, jchan_state ) MCFG_VIDEO_START(jchan) + MCFG_DEVICE_ADD("spritegen1", sknsspr_, 0) + MCFG_DEVICE_ADD("spritegen2", sknsspr_, 0) + MCFG_NVRAM_ADD_0FILL("nvram") /* sound hardware */ diff --git a/src/mame/drivers/suprnova.c b/src/mame/drivers/suprnova.c index 27f0a966592..7f1427c89bd 100644 --- a/src/mame/drivers/suprnova.c +++ b/src/mame/drivers/suprnova.c @@ -150,8 +150,10 @@ NEP-16 #include "deprecat.h" #include "sound/ymz280b.h" #include "cpu/sh2/sh2.h" -#include "includes/suprnova.h" #include "machine/nvram.h" +#include "video/sknsspr.h" +#include "includes/suprnova.h" + #define BIOS_SKIP 1 // Skip Bios as it takes too long and doesn't complete atm. @@ -791,7 +793,10 @@ static const ymz280b_interface ymz280b_intf = 0 // irq ? }; -static MACHINE_CONFIG_START( skns, driver_device ) + + + +static MACHINE_CONFIG_START( skns, skns_state ) MCFG_CPU_ADD("maincpu", SH2,28638000) MCFG_CPU_PROGRAM_MAP(skns_map) MCFG_CPU_VBLANK_INT_HACK(skns_interrupt,2) @@ -820,6 +825,8 @@ static MACHINE_CONFIG_START( skns, driver_device ) MCFG_PALETTE_LENGTH(32768) MCFG_GFXDECODE(skns_bg) + MCFG_DEVICE_ADD("spritegen", sknsspr_, 0) + MCFG_VIDEO_START(skns) MCFG_VIDEO_RESET(skns) @@ -967,25 +974,25 @@ static void set_drc_pcflush(running_machine *machine, UINT32 addr) sh2drc_add_pcflush(machine->device("maincpu"), addr); } -static DRIVER_INIT( galpani4 ) { skns_sprite_kludge(-5,-1); init_skns(machine); } -static DRIVER_INIT( galpanis ) { skns_sprite_kludge(-5,-1); init_skns(machine); } -static DRIVER_INIT( cyvern ) { skns_sprite_kludge(+0,+2); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x604d3c8, 0x604d3cb, 0, 0, cyvern_speedup_r ); set_drc_pcflush(machine, 0x402ebd2); } -static DRIVER_INIT( galpans2 ) { skns_sprite_kludge(-1,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60fb6bc, 0x60fb6bf, 0, 0, galpans2_speedup_r ); set_drc_pcflush(machine, 0x4049ae2); } -static DRIVER_INIT( gutsn ) { skns_sprite_kludge(+0,+0); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x600c780, 0x600c783, 0, 0, gutsn_speedup_r ); set_drc_pcflush(machine, 0x402206e); } -static DRIVER_INIT( panicstr ) { skns_sprite_kludge(-1,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60f19e4, 0x60f19e7, 0, 0, panicstr_speedup_r ); set_drc_pcflush(machine, 0x404e68a); } -static DRIVER_INIT( senknow ) { skns_sprite_kludge(+1,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60000dc, 0x60000df, 0, 0, senknow_speedup_r ); set_drc_pcflush(machine, 0x4017dce); } -static DRIVER_INIT( puzzloop ) { skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6081d38, 0x6081d3b, 0, 0, puzzloop_speedup_r ); set_drc_pcflush(machine, 0x401da14); } -static DRIVER_INIT( puzzloopj ) { skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6086714, 0x6086717, 0, 0, puzzloopj_speedup_r ); set_drc_pcflush(machine, 0x401dca0); } -static DRIVER_INIT( puzzloopa ) { skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6085bcc, 0x6085bcf, 0, 0, puzzloopa_speedup_r ); set_drc_pcflush(machine, 0x401d9d4); } -static DRIVER_INIT( puzzloopu ) { skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6085cec, 0x6085cef, 0, 0, puzzloopu_speedup_r ); set_drc_pcflush(machine, 0x401dab0); } -static DRIVER_INIT( jjparads ) { skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6000994, 0x6000997, 0, 0, jjparads_speedup_r ); set_drc_pcflush(machine, 0x4015e84); } -static DRIVER_INIT( jjparad2 ) { skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6000984, 0x6000987, 0, 0, jjparad2_speedup_r ); set_drc_pcflush(machine, 0x401620a); } -static DRIVER_INIT( ryouran ) { skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6000a14, 0x6000a17, 0, 0, ryouran_speedup_r ); set_drc_pcflush(machine, 0x40182ce); } -static DRIVER_INIT( teljan ) { skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6002fb4, 0x6002fb7, 0, 0, teljan_speedup_r ); set_drc_pcflush(machine, 0x401ba32); } -static DRIVER_INIT( sengekis ) { skns_sprite_kludge(-192,-272); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60b74bc, 0x60b74bf, 0, 0, sengekis_speedup_r ); set_drc_pcflush(machine, 0x60006ec); } -static DRIVER_INIT( sengekij ) { skns_sprite_kludge(-192,-272); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60b7380, 0x60b7383, 0, 0, sengekij_speedup_r ); set_drc_pcflush(machine, 0x60006ec); } -static DRIVER_INIT( sarukani ) { skns_sprite_kludge(-1,-1); init_skns(machine); set_drc_pcflush(machine, 0x4013b42); } // Speedup is in skns_io_w() -static DRIVER_INIT( galpans3 ) { skns_sprite_kludge(-1,-1); init_skns(machine); } +static DRIVER_INIT( galpani4 ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-5,-1); init_skns(machine); } +static DRIVER_INIT( galpanis ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-5,-1); init_skns(machine); } +static DRIVER_INIT( cyvern ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(+0,+2); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x604d3c8, 0x604d3cb, 0, 0, cyvern_speedup_r ); set_drc_pcflush(machine, 0x402ebd2); } +static DRIVER_INIT( galpans2 ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-1,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60fb6bc, 0x60fb6bf, 0, 0, galpans2_speedup_r ); set_drc_pcflush(machine, 0x4049ae2); } +static DRIVER_INIT( gutsn ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(+0,+0); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x600c780, 0x600c783, 0, 0, gutsn_speedup_r ); set_drc_pcflush(machine, 0x402206e); } +static DRIVER_INIT( panicstr ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-1,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60f19e4, 0x60f19e7, 0, 0, panicstr_speedup_r ); set_drc_pcflush(machine, 0x404e68a); } +static DRIVER_INIT( senknow ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(+1,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60000dc, 0x60000df, 0, 0, senknow_speedup_r ); set_drc_pcflush(machine, 0x4017dce); } +static DRIVER_INIT( puzzloop ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6081d38, 0x6081d3b, 0, 0, puzzloop_speedup_r ); set_drc_pcflush(machine, 0x401da14); } +static DRIVER_INIT( puzzloopj ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6086714, 0x6086717, 0, 0, puzzloopj_speedup_r ); set_drc_pcflush(machine, 0x401dca0); } +static DRIVER_INIT( puzzloopa ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6085bcc, 0x6085bcf, 0, 0, puzzloopa_speedup_r ); set_drc_pcflush(machine, 0x401d9d4); } +static DRIVER_INIT( puzzloopu ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-9,-1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6085cec, 0x6085cef, 0, 0, puzzloopu_speedup_r ); set_drc_pcflush(machine, 0x401dab0); } +static DRIVER_INIT( jjparads ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6000994, 0x6000997, 0, 0, jjparads_speedup_r ); set_drc_pcflush(machine, 0x4015e84); } +static DRIVER_INIT( jjparad2 ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6000984, 0x6000987, 0, 0, jjparad2_speedup_r ); set_drc_pcflush(machine, 0x401620a); } +static DRIVER_INIT( ryouran ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6000a14, 0x6000a17, 0, 0, ryouran_speedup_r ); set_drc_pcflush(machine, 0x40182ce); } +static DRIVER_INIT( teljan ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(+5,+1); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x6002fb4, 0x6002fb7, 0, 0, teljan_speedup_r ); set_drc_pcflush(machine, 0x401ba32); } +static DRIVER_INIT( sengekis ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-192,-272); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60b74bc, 0x60b74bf, 0, 0, sengekis_speedup_r ); set_drc_pcflush(machine, 0x60006ec); } +static DRIVER_INIT( sengekij ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-192,-272); init_skns(machine); memory_install_read32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x60b7380, 0x60b7383, 0, 0, sengekij_speedup_r ); set_drc_pcflush(machine, 0x60006ec); } +static DRIVER_INIT( sarukani ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-1,-1); init_skns(machine); set_drc_pcflush(machine, 0x4013b42); } // Speedup is in skns_io_w() +static DRIVER_INIT( galpans3 ) { machine->device<sknsspr_device>("spritegen")->skns_sprite_kludge(-1,-1); init_skns(machine); } diff --git a/src/mame/includes/suprnova.h b/src/mame/includes/suprnova.h index 7ee10bcf43f..7af45dacbfa 100644 --- a/src/mame/includes/suprnova.h +++ b/src/mame/includes/suprnova.h @@ -1,13 +1,20 @@ /*----------- defined in drivers/suprnova.c -----------*/ +class skns_state : public driver_device +{ +public: + skns_state(running_machine &machine, const driver_device_config_base &config) + : driver_device(machine, config) { } + + sknsspr_device* spritegen; +}; + extern UINT32 *skns_tilemapA_ram, *skns_tilemapB_ram, *skns_v3slc_ram; extern UINT32 *skns_palette_ram; extern UINT32 *skns_pal_regs, *skns_v3_regs, *skns_spc_regs; /*----------- defined in video/suprnova.c -----------*/ -extern int suprnova_alt_enable_sprites; - void skns_sprite_kludge(int x, int y); void skns_draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 1a930f7b8da..4c253d27827 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -776,6 +776,7 @@ $(MAMEOBJ)/kaneko.a: \ $(DRIVERS)/kaneko16.o $(MACHINE)/kaneko16.o $(VIDEO)/kaneko16.o \ $(DRIVERS)/sandscrp.o \ $(DRIVERS)/suprnova.o $(VIDEO)/suprnova.o \ + $(VIDEO)/sknsspr.o \ $(MAMEOBJ)/konami.a: \ $(DRIVERS)/88games.o $(VIDEO)/88games.o \ diff --git a/src/mame/video/sknsspr.c b/src/mame/video/sknsspr.c new file mode 100644 index 00000000000..1828a923d25 --- /dev/null +++ b/src/mame/video/sknsspr.c @@ -0,0 +1,575 @@ +/* Super Kaneko Nova System Sprites + + "CG24173 6186" & "CG24143 4181" (always used as a pair?) + + - used by suprnova.c + galpani3.c + jchan.c + + - ToDo: + Get rid of sprite position kludges + Fix zooming precision/rounding (most noticable on jchan backgrounds) + +*/ + +#include "emu.h" +#include "sknsspr.h" + + +sknsspr_device_config::sknsspr_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) + : device_config(mconfig, static_alloc_device_config, "sknsspr_device", tag, owner, clock) +{ +} + +device_config *sknsspr_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) +{ + return global_alloc(sknsspr_device_config(mconfig, tag, owner, clock)); +} + +device_t *sknsspr_device_config::alloc_device(running_machine &machine) const +{ + return auto_alloc(&machine, sknsspr_device(machine, *this)); +} + +sknsspr_device::sknsspr_device(running_machine &_machine, const sknsspr_device_config &config) + : device_t(_machine, config), + m_config(config) +{ +} + +void sknsspr_device::device_start() +{ + //printf("sknsspr_device::device_start()\n"); +} + +void sknsspr_device::device_reset() +{ + //printf("sknsspr_device::device_reset()\n"); +} + +int sknsspr_device::skns_rle_decode ( running_machine *machine, int romoffset, int size, UINT8*gfx_source, size_t gfx_length ) +{ + UINT8 *src = gfx_source; + size_t srcsize = gfx_length; + UINT8 *dst = decodebuffer; + int decodeoffset = 0; + + while(size>0) { + UINT8 code = src[(romoffset++)%srcsize]; + size -= (code & 0x7f) + 1; + if(code & 0x80) { /* (code & 0x7f) normal values will follow */ + code &= 0x7f; + do { + dst[(decodeoffset++)%SUPRNOVA_DECODE_BUFFER_SIZE] = src[(romoffset++)%srcsize]; + code--; + } while(code != 0xff); + } else { /* repeat next value (code & 0x7f) times */ + UINT8 val = src[(romoffset++)%srcsize]; + do { + dst[(decodeoffset++)%SUPRNOVA_DECODE_BUFFER_SIZE] = val; + code--; + } while(code != 0xff); + } + } + return &src[romoffset%srcsize]-gfx_source; +} + +void sknsspr_device::skns_sprite_kludge(int x, int y) +{ + sprite_kludge_x = x; + sprite_kludge_y = y; +} + +/* Zooming blitter, zoom is by way of both source and destination offsets */ +/* We are working in .6 fixed point if you hadn't guessed */ + +#define z_decls(step) \ + UINT16 zxs = 0x40-(zx_m>>2); \ + UINT16 zxd = 0x40-(zx_s>>2); \ + UINT16 zys = 0x40-(zy_m>>2); \ + UINT16 zyd = 0x40-(zy_s>>2); \ + int xs, ys, xd, yd, old, old2; \ + int step_spr = step; \ + int bxs = 0, bys = 0; \ + rectangle clip; \ + clip.min_x = cliprect->min_x<<6; \ + clip.max_x = (cliprect->max_x+1)<<6; \ + clip.min_y = cliprect->min_y<<6; \ + clip.max_y = (cliprect->max_y+1)<<6; \ + sx <<= 6; \ + sy <<= 6; \ + x <<= 6; \ + y <<= 6; + +#define z_clamp_x_min() \ + if(x < clip.min_x) { \ + do { \ + bxs += zxs; \ + x += zxd; \ + } while(x < clip.min_x); \ + } + +#define z_clamp_x_max() \ + if(x > clip.max_x) { \ + do { \ + bxs += zxs; \ + x -= zxd; \ + } while(x > clip.max_x); \ + } + +#define z_clamp_y_min() \ + if(y < clip.min_y) { \ + do { \ + bys += zys; \ + y += zyd; \ + } while(y < clip.min_y); \ + src += (bys>>6)*step_spr; \ + } + +#define z_clamp_y_max() \ + if(y > clip.max_y) { \ + do { \ + bys += zys; \ + y -= zyd; \ + } while(y > clip.max_y); \ + src += (bys>>6)*step_spr; \ + } + +#define z_loop_x() \ + xs = bxs; \ + xd = x; \ + while(xs < sx && xd <= clip.max_x) + +#define z_loop_x_flip() \ + xs = bxs; \ + xd = x; \ + while(xs < sx && xd >= clip.min_x) + +#define z_loop_y() \ + ys = bys; \ + yd = y; \ + while(ys < sy && yd <= clip.max_y) + +#define z_loop_y_flip() \ + ys = bys; \ + yd = y; \ + while(ys < sy && yd >= clip.min_y) + +#define z_draw_pixel() \ + UINT8 val = src[xs >> 6]; \ + if(val) \ + *BITMAP_ADDR16(bitmap, yd>>6, xd>>6) = val + colour; + +#define z_x_dst(op) \ + old = xd; \ + do { \ + xs += zxs; \ + xd op zxd; \ + } while(!((xd^old) & ~0x3f)); + +#define z_y_dst(op) \ + old = yd; \ + old2 = ys; \ + do { \ + ys += zys; \ + yd op zyd; \ + } while(!((yd^old) & ~0x3f)); \ + while((ys^old2) & ~0x3f) { \ + src += step_spr; \ + old2 += 0x40; \ + } + +static void blit_nf_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) +{ + z_decls(sx); + z_clamp_x_min(); + z_clamp_y_min(); + z_loop_y() { + z_loop_x() { + z_draw_pixel(); + z_x_dst(+=); + } + z_y_dst(+=); + } +} + +static void blit_fy_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) +{ + z_decls(sx); + z_clamp_x_min(); + z_clamp_y_max(); + z_loop_y_flip() { + z_loop_x() { + z_draw_pixel(); + z_x_dst(+=); + } + z_y_dst(-=); + } +} + +static void blit_fx_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) +{ + z_decls(sx); + z_clamp_x_max(); + z_clamp_y_min(); + z_loop_y() { + z_loop_x_flip() { + z_draw_pixel(); + z_x_dst(-=); + } + z_y_dst(+=); + } +} + +static void blit_fxy_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) +{ + z_decls(sx); + z_clamp_x_max(); + z_clamp_y_max(); + z_loop_y_flip() { + z_loop_x_flip() { + z_draw_pixel(); + z_x_dst(-=); + } + z_y_dst(-=); + } +} + +static void (*const blit_z[4])(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) = { + blit_nf_z, + blit_fy_z, + blit_fx_z, + blit_fxy_z, +}; + +void sknsspr_device::skns_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT32* spriteram_source, size_t spriteram_size, UINT8* gfx_source, size_t gfx_length, UINT32* sprite_regs) +{ + /*- SPR RAM Format -** + + 16 bytes per sprite + +0x00 --ss --SS z--- ---- jjjg g-ff ppcc cccc + + s = y size + S = x size + j = joint + g = group sprite is part of (if groups are enabled) + f = flip + p = priority + c = palette + +0x04 ---- -aaa aaaa aaaa aaaa aaaa aaaa aaaa + + a = ROM address of sprite data + +0x08 ZZZZ ZZ-- zzzz zz-- xxxx xxxx xx-- ---- + + Z = horizontal zoom table + z = horizontal zoom subtable + x = x position + +0x0C ZZZZ ZZ-- zzzz zz-- yyyy yyyy yy-- ---- + + Z = vertical zoom table + z = vertical zoom subtable + x = y position + + **- End of Comments -*/ + + /* sprite ram start / end is not really fixed registers change it */ + + //printf ("addr %08x\n", (sprite_regs[0x14/4])); + + + UINT32 *source = spriteram_source; + UINT32 *finish = source + spriteram_size/4; + + int group_x_offset[4]; + int group_y_offset[4]; + int group_enable; + int group_number; + int sprite_flip; + int sprite_x_scroll; + int sprite_y_scroll; + int disabled = sprite_regs[0x04/4] & 0x08; // RWR1 + int xsize,ysize, size, xpos=0,ypos=0, pri=0, romoffset, colour=0, xflip,yflip, joint; + int sx,sy; + int endromoffs=0, gfxlen; + int grow; + UINT16 zoomx_m, zoomx_s, zoomy_m, zoomy_s; + + + if ((!disabled)){ + + group_enable = (sprite_regs[0x00/4] & 0x0040) >> 6; // RWR0 + + /* Sengekis uses global flip */ + sprite_flip = (sprite_regs[0x04/4] & 0x03); // RWR1 + + sprite_y_scroll = ((sprite_regs[0x08/4] & 0x7fc0) >> 6); // RWR2 + sprite_x_scroll = ((sprite_regs[0x10/4] & 0x7fc0) >> 6); // RWR4 + if (sprite_y_scroll&0x100) sprite_y_scroll -= 0x200; // Signed + if (sprite_x_scroll&0x100) sprite_x_scroll -= 0x200; // Signed + + group_x_offset[0] = (sprite_regs[0x18/4] & 0xffc0) >> 6; // RWR6 + group_y_offset[0] = (sprite_regs[0x1c/4] & 0xffc0) >> 6; // RWR7 + if (group_x_offset[0]&0x200) group_x_offset[0] -= 0x400; // Signed + if (group_y_offset[0]&0x200) group_y_offset[0] -= 0x400; // Signed + + group_x_offset[1] = (sprite_regs[0x20/4] & 0xffc0) >> 6; // RWR8 + group_y_offset[1] = (sprite_regs[0x24/4] & 0xffc0) >> 6; // RWR9 + if (group_x_offset[1]&0x200) group_x_offset[1] -= 0x400; // Signed + if (group_y_offset[1]&0x200) group_y_offset[1] -= 0x400; // Signed + + group_x_offset[2] = (sprite_regs[0x28/4] & 0xffc0) >> 6; // RWR10 + group_y_offset[2] = (sprite_regs[0x2c/4] & 0xffc0) >> 6; // RWR11 + if (group_x_offset[2]&0x200) group_x_offset[2] -= 0x400; // Signed + if (group_y_offset[2]&0x200) group_y_offset[2] -= 0x400; // Signed + + group_x_offset[3] = (sprite_regs[0x30/4] & 0xffc0) >> 6; // RWR12 + group_y_offset[3] = (sprite_regs[0x34/4] & 0xffc0) >> 6; // RWR13 + if (group_x_offset[3]&0x200) group_x_offset[3] -= 0x400; // Signed + if (group_y_offset[3]&0x200) group_y_offset[3] -= 0x400; // Signed + + // popmessage ("x %08x y %08x x2 %08x y2 %08x",sprite_x_scroll, sprite_y_scroll,group_x_offset[1], group_y_offset[1]); + // popmessage("%d %d %d %d A:%d B:%d", sprite_kludge_x, sprite_kludge_y, sprite_x_scroll, sprite_y_scroll, (skns_pal_regs[0x00/4] & 0x7000) >> 12, (skns_pal_regs[0x10/4] & 0x7000) >> 12); + // if (keyboard_pressed(KEYCODE_Q)) sprite_kludge_x++; + // if (keyboard_pressed(KEYCODE_W)) sprite_kludge_x--; + // if (keyboard_pressed(KEYCODE_E)) sprite_kludge_y++; + // if (keyboard_pressed(KEYCODE_D)) sprite_kludge_y--; + + // Tilemap Pri/enables + // popmessage("A: %x %x B: %x %x", skns_v3_regs[0x10/4]>>3, skns_v3_regs[0x10/4]&7, skns_v3_regs[0x34/4]>>3, skns_v3_regs[0x34/4]&7); + + /* Seems that sprites are consistently off by a fixed no. of pixels in different games + (Patterns emerge through Manufacturer/Date/Orientation) */ + sprite_x_scroll += sprite_kludge_x; + sprite_y_scroll += sprite_kludge_y; + + + gfxlen = gfx_length; + while( source<finish ) + { + xflip = (source[0] & 0x00000200) >> 9; + yflip = (source[0] & 0x00000100) >> 8; + + ysize = (source[0] & 0x30000000) >> 28; + xsize = (source[0] & 0x03000000) >> 24; + xsize ++; + ysize ++; + + xsize *= 16; + ysize *= 16; + + size = xsize * ysize; + + joint = (source[0] & 0x0000e000) >> 13; + + if (!(joint & 1)) + { + xpos = (source[2] & 0x0000ffc0) >> 6; + ypos = (source[3] & 0x0000ffc0) >> 6; + + xpos += sprite_x_scroll; // Global offset + ypos += sprite_y_scroll; + + if (group_enable) + { + group_number = (source[0] & 0x00001800) >> 11; + + /* the group positioning doesn't seem to be working as i'd expect, + if I apply the x position the cursor on galpani4 ends up moving + from the correct position to too far right, also the y offset + seems to cause the position to be off by one in galpans2 even if + it fixes the position in galpani4? + + even if I take into account the global sprite scroll registers + it isn't right + + global offset kludged using game specific offset -pjp */ + + xpos += group_x_offset[group_number]; + ypos += group_y_offset[group_number]; + } + } + else + { + xpos += (source[2] & 0x0000ffc0) >> 6; + ypos += (source[3] & 0x0000ffc0) >> 6; + } + + if (xpos > 0x1ff) xpos -= 0x400; + if (ypos > 0x1ff) ypos -= 0x400; + + /* Local sprite offset (for taking flip into account and drawing offset) */ + sx = xpos; + sy = ypos; + + /* Global Sprite Flip (sengekis) */ + if (sprite_flip&2) + { + xflip ^= 1; + sx = machine->primary_screen->visible_area().max_x+1 - sx; + } + if (sprite_flip&1) + { + yflip ^= 1; + sy = machine->primary_screen->visible_area().max_y+1 - sy; + } + + /* Palette linking */ + if (!(joint & 2)) + { + colour = (source[0] & 0x0000003f) >> 0; + } + + /* Priority and Tile linking */ + if (!(joint & 4)) + { + romoffset = (source[1] & 0x07ffffff) >> 0; + pri = (source[0] & 0x000000c0) >> 6; + } else { + romoffset = endromoffs; + } + + grow = (source[0]>>23) & 1; + + if (!grow) + { + zoomx_m = (source[2] >> 24)&0x00fc; + zoomx_s = (source[2] >> 16)&0x00fc; + zoomy_m = (source[3] >> 24)&0x00fc; + zoomy_s = (source[3] >> 16)&0x00fc; + } + else + { + // sengekis uses this on sprites which are shrinking as they head towards the ground + // it's also used on the input test of Gals Panic S2 + // + // it appears to offer a higher precision 'shrink' mode (although I'm not entirely + // convinced this implementation is correct because we simply end up ignoring + // part of the data) + zoomx_m = 0; + zoomx_s = (source[2] >> 24)&0x00fc; + zoomy_m = 0; + zoomy_s = (source[3] >> 24)&0x00fc; + + + } + + + romoffset &= gfxlen-1; + + endromoffs = skns_rle_decode ( machine, romoffset, size, gfx_source, gfx_length ); + + // in Cyvern + + // train in tunnel pri = 0x00 + // nothing? = 0x01 + // players etc. pri = 0x02 + // pickups etc. pri = 0x03 + + // PriTest +// if(!( (keyboard_pressed(KEYCODE_Q)&&(pri==0)) || (keyboard_pressed(KEYCODE_W)&&(pri==1)) || (keyboard_pressed(KEYCODE_E)&&(pri==2)) || (keyboard_pressed(KEYCODE_D)&&(pri==3)) )) +// if( !(keyboard_pressed(KEYCODE_Q) && ((source[0] & 0x00800000)>>24)) ) + + + + { + int NewColour = (colour<<8) | (pri << 14); + + if(zoomx_m || zoomx_s || zoomy_m || zoomy_s) + { + blit_z[ (xflip<<1) | yflip ](bitmap, cliprect, decodebuffer, sx, sy, xsize, ysize, zoomx_m, zoomx_s, zoomy_m, zoomy_s, NewColour); + } + else + { + if (!xflip && !yflip) { + int xx,yy; + + for (xx = 0; xx<xsize; xx++) + { + if ((sx+xx < (cliprect->max_x+1)) && (sx+xx >= cliprect->min_x)) + { + for (yy = 0; yy<ysize; yy++) + { + if ((sy+yy < (cliprect->max_y+1)) && (sy+yy >= cliprect->min_y)) + { + int pix; + pix = decodebuffer[xsize*yy+xx]; + if (pix) + *BITMAP_ADDR16(bitmap, sy+yy, sx+xx) = pix+ NewColour; // change later + } + } + } + } + } else if (!xflip && yflip) { + int xx,yy; + sy -= ysize; + + for (xx = 0; xx<xsize; xx++) + { + if ((sx+xx < (cliprect->max_x+1)) && (sx+xx >= cliprect->min_x)) + { + for (yy = 0; yy<ysize; yy++) + { + if ((sy+(ysize-1-yy) < (cliprect->max_y+1)) && (sy+(ysize-1-yy) >= cliprect->min_y)) + { + int pix; + pix = decodebuffer[xsize*yy+xx]; + if (pix) + *BITMAP_ADDR16(bitmap, sy+(ysize-1-yy), sx+xx) = pix+ NewColour; // change later + } + } + } + } + } else if (xflip && !yflip) { + int xx,yy; + sx -= xsize; + + for (xx = 0; xx<xsize; xx++) + { + if ( (sx+(xsize-1-xx) < (cliprect->max_x+1)) && (sx+(xsize-1-xx) >= cliprect->min_x)) + { + for (yy = 0; yy<ysize; yy++) + { + if ((sy+yy < (cliprect->max_y+1)) && (sy+yy >= cliprect->min_y)) + { + int pix; + pix = decodebuffer[xsize*yy+xx]; + if (pix) + *BITMAP_ADDR16(bitmap, sy+yy, sx+(xsize-1-xx)) = pix+ NewColour; // change later + } + } + } + } + } else if (xflip && yflip) { + int xx,yy; + sx -= xsize; + sy -= ysize; + + for (xx = 0; xx<xsize; xx++) + { + if ((sx+(xsize-1-xx) < (cliprect->max_x+1)) && (sx+(xsize-1-xx) >= cliprect->min_x)) + { + for (yy = 0; yy<ysize; yy++) + { + if ((sy+(ysize-1-yy) < (cliprect->max_y+1)) && (sy+(ysize-1-yy) >= cliprect->min_y)) + { + int pix; + pix = decodebuffer[xsize*yy+xx]; + if (pix) + *BITMAP_ADDR16(bitmap, sy+(ysize-1-yy), sx+(xsize-1-xx)) = pix+ NewColour; // change later + } + } + } + } + } + } + }//End PriTest + + source+=4; + } + } +} + diff --git a/src/mame/video/sknsspr.h b/src/mame/video/sknsspr.h new file mode 100644 index 00000000000..966805ad81e --- /dev/null +++ b/src/mame/video/sknsspr.h @@ -0,0 +1,36 @@ + +class sknsspr_device_config : public device_config +{ + friend class sknsspr_device; + sknsspr_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); +public: + static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + virtual device_t *alloc_device(running_machine &machine) const; +protected: +}; + +class sknsspr_device : public device_t +{ + friend class sknsspr_device_config; + sknsspr_device(running_machine &_machine, const sknsspr_device_config &config); +public: + void skns_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT32* spriteram_source, size_t spriteram_size, UINT8* gfx_source, size_t gfx_length, UINT32* sprite_regs); + void skns_sprite_kludge(int x, int y); + +protected: + virtual void device_start(); + virtual void device_reset(); + const sknsspr_device_config &m_config; +private: + int sprite_kludge_x, sprite_kludge_y; + #define SUPRNOVA_DECODE_BUFFER_SIZE 0x2000 + UINT8 decodebuffer[SUPRNOVA_DECODE_BUFFER_SIZE]; + int skns_rle_decode ( running_machine *machine, int romoffset, int size, UINT8*gfx_source, size_t gfx_length ); +}; + +const device_type sknsspr_ = sknsspr_device_config::static_alloc_device_config; + + + + + diff --git a/src/mame/video/suprnova.c b/src/mame/video/suprnova.c index e5315f7aab6..55dc61a34fa 100644 --- a/src/mame/video/suprnova.c +++ b/src/mame/video/suprnova.c @@ -1,20 +1,7 @@ /* Super Kaneko Nova System video */ -/* -TODO: -Implement double buffering for sprites? -We have to tell games which buffer to draw to? irrelevant to emulation - -Remove all debug keys -*/ - -/* -Done: -Add global sprite flip -Tilemap flip flags were reversed -*/ - #include "emu.h" +#include "video/sknsspr.h" #include "includes/suprnova.h" static bitmap_t *sprite_bitmap; @@ -109,13 +96,10 @@ static void suprnova_draw_roz(bitmap_t* bitmap, bitmap_t* bitmapflags, const rec } -#define SUPRNOVA_DECODE_BUFFER_SIZE 0x2000 - -static UINT8 decodebuffer[SUPRNOVA_DECODE_BUFFER_SIZE]; static int depthA=0; static int depthB=0; -static int sprite_kludge_x=0, sprite_kludge_y=0; + static int use_spc_bright, use_v3_bright; // makes sarukani rather dark, but should be default.. static UINT8 bright_spc_b=0x00, bright_spc_g=0x00, bright_spc_r=0x00; @@ -311,532 +295,6 @@ static void palette_update(running_machine *machine) } -static int skns_rle_decode ( running_machine *machine, int romoffset, int size, UINT8*gfx_source, size_t gfx_length ) -{ - UINT8 *src = gfx_source; - size_t srcsize = gfx_length; - UINT8 *dst = decodebuffer; - int decodeoffset = 0; - - while(size>0) { - UINT8 code = src[(romoffset++)%srcsize]; - size -= (code & 0x7f) + 1; - if(code & 0x80) { /* (code & 0x7f) normal values will follow */ - code &= 0x7f; - do { - dst[(decodeoffset++)%SUPRNOVA_DECODE_BUFFER_SIZE] = src[(romoffset++)%srcsize]; - code--; - } while(code != 0xff); - } else { /* repeat next value (code & 0x7f) times */ - UINT8 val = src[(romoffset++)%srcsize]; - do { - dst[(decodeoffset++)%SUPRNOVA_DECODE_BUFFER_SIZE] = val; - code--; - } while(code != 0xff); - } - } - return &src[romoffset%srcsize]-gfx_source; -} - -void skns_sprite_kludge(int x, int y) -{ - sprite_kludge_x = x; - sprite_kludge_y = y; -} - -/* Zooming blitter, zoom is by way of both source and destination offsets */ -/* We are working in .6 fixed point if you hadn't guessed */ - -#define z_decls(step) \ - UINT16 zxs = 0x40-(zx_m>>2); \ - UINT16 zxd = 0x40-(zx_s>>2); \ - UINT16 zys = 0x40-(zy_m>>2); \ - UINT16 zyd = 0x40-(zy_s>>2); \ - int xs, ys, xd, yd, old, old2; \ - int step_spr = step; \ - int bxs = 0, bys = 0; \ - rectangle clip; \ - clip.min_x = cliprect->min_x<<6; \ - clip.max_x = (cliprect->max_x+1)<<6; \ - clip.min_y = cliprect->min_y<<6; \ - clip.max_y = (cliprect->max_y+1)<<6; \ - sx <<= 6; \ - sy <<= 6; \ - x <<= 6; \ - y <<= 6; - -#define z_clamp_x_min() \ - if(x < clip.min_x) { \ - do { \ - bxs += zxs; \ - x += zxd; \ - } while(x < clip.min_x); \ - } - -#define z_clamp_x_max() \ - if(x > clip.max_x) { \ - do { \ - bxs += zxs; \ - x -= zxd; \ - } while(x > clip.max_x); \ - } - -#define z_clamp_y_min() \ - if(y < clip.min_y) { \ - do { \ - bys += zys; \ - y += zyd; \ - } while(y < clip.min_y); \ - src += (bys>>6)*step_spr; \ - } - -#define z_clamp_y_max() \ - if(y > clip.max_y) { \ - do { \ - bys += zys; \ - y -= zyd; \ - } while(y > clip.max_y); \ - src += (bys>>6)*step_spr; \ - } - -#define z_loop_x() \ - xs = bxs; \ - xd = x; \ - while(xs < sx && xd <= clip.max_x) - -#define z_loop_x_flip() \ - xs = bxs; \ - xd = x; \ - while(xs < sx && xd >= clip.min_x) - -#define z_loop_y() \ - ys = bys; \ - yd = y; \ - while(ys < sy && yd <= clip.max_y) - -#define z_loop_y_flip() \ - ys = bys; \ - yd = y; \ - while(ys < sy && yd >= clip.min_y) - -#define z_draw_pixel() \ - UINT8 val = src[xs >> 6]; \ - if(val) \ - *BITMAP_ADDR16(bitmap, yd>>6, xd>>6) = val + colour; - -#define z_x_dst(op) \ - old = xd; \ - do { \ - xs += zxs; \ - xd op zxd; \ - } while(!((xd^old) & ~0x3f)); - -#define z_y_dst(op) \ - old = yd; \ - old2 = ys; \ - do { \ - ys += zys; \ - yd op zyd; \ - } while(!((yd^old) & ~0x3f)); \ - while((ys^old2) & ~0x3f) { \ - src += step_spr; \ - old2 += 0x40; \ - } - -static void blit_nf_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) -{ - z_decls(sx); - z_clamp_x_min(); - z_clamp_y_min(); - z_loop_y() { - z_loop_x() { - z_draw_pixel(); - z_x_dst(+=); - } - z_y_dst(+=); - } -} - -static void blit_fy_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) -{ - z_decls(sx); - z_clamp_x_min(); - z_clamp_y_max(); - z_loop_y_flip() { - z_loop_x() { - z_draw_pixel(); - z_x_dst(+=); - } - z_y_dst(-=); - } -} - -static void blit_fx_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) -{ - z_decls(sx); - z_clamp_x_max(); - z_clamp_y_min(); - z_loop_y() { - z_loop_x_flip() { - z_draw_pixel(); - z_x_dst(-=); - } - z_y_dst(+=); - } -} - -static void blit_fxy_z(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) -{ - z_decls(sx); - z_clamp_x_max(); - z_clamp_y_max(); - z_loop_y_flip() { - z_loop_x_flip() { - z_draw_pixel(); - z_x_dst(-=); - } - z_y_dst(-=); - } -} - -static void (*const blit_z[4])(bitmap_t *bitmap, const rectangle *cliprect, const UINT8 *src, int x, int y, int sx, int sy, UINT16 zx_m, UINT16 zx_s, UINT16 zy_m, UINT16 zy_s, int colour) = { - blit_nf_z, - blit_fy_z, - blit_fx_z, - blit_fxy_z, -}; - -void skns_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT32* spriteram_source, size_t spriteram_size, UINT8* gfx_source, size_t gfx_length, UINT32* sprite_regs) -{ - /*- SPR RAM Format -** - - 16 bytes per sprite - -0x00 --ss --SS z--- ---- jjjg g-ff ppcc cccc - - s = y size - S = x size - j = joint - g = group sprite is part of (if groups are enabled) - f = flip - p = priority - c = palette - -0x04 ---- -aaa aaaa aaaa aaaa aaaa aaaa aaaa - - a = ROM address of sprite data - -0x08 ZZZZ ZZ-- zzzz zz-- xxxx xxxx xx-- ---- - - Z = horizontal zoom table - z = horizontal zoom subtable - x = x position - -0x0C ZZZZ ZZ-- zzzz zz-- yyyy yyyy yy-- ---- - - Z = vertical zoom table - z = vertical zoom subtable - x = y position - - **- End of Comments -*/ - - /* sprite ram start / end is not really fixed registers change it */ - - //printf ("addr %08x\n", (sprite_regs[0x14/4])); - - - UINT32 *source = spriteram_source; - UINT32 *finish = source + spriteram_size/4; - - int group_x_offset[4]; - int group_y_offset[4]; - int group_enable; - int group_number; - int sprite_flip; - int sprite_x_scroll; - int sprite_y_scroll; - int disabled = sprite_regs[0x04/4] & 0x08; // RWR1 - int xsize,ysize, size, xpos=0,ypos=0, pri=0, romoffset, colour=0, xflip,yflip, joint; - int sx,sy; - int endromoffs=0, gfxlen; - int grow; - UINT16 zoomx_m, zoomx_s, zoomy_m, zoomy_s; - - - if ((!disabled) && suprnova_alt_enable_sprites){ - - group_enable = (sprite_regs[0x00/4] & 0x0040) >> 6; // RWR0 - - /* Sengekis uses global flip */ - sprite_flip = (sprite_regs[0x04/4] & 0x03); // RWR1 - - sprite_y_scroll = ((sprite_regs[0x08/4] & 0x7fc0) >> 6); // RWR2 - sprite_x_scroll = ((sprite_regs[0x10/4] & 0x7fc0) >> 6); // RWR4 - if (sprite_y_scroll&0x100) sprite_y_scroll -= 0x200; // Signed - if (sprite_x_scroll&0x100) sprite_x_scroll -= 0x200; // Signed - - group_x_offset[0] = (sprite_regs[0x18/4] & 0xffc0) >> 6; // RWR6 - group_y_offset[0] = (sprite_regs[0x1c/4] & 0xffc0) >> 6; // RWR7 - if (group_x_offset[0]&0x200) group_x_offset[0] -= 0x400; // Signed - if (group_y_offset[0]&0x200) group_y_offset[0] -= 0x400; // Signed - - group_x_offset[1] = (sprite_regs[0x20/4] & 0xffc0) >> 6; // RWR8 - group_y_offset[1] = (sprite_regs[0x24/4] & 0xffc0) >> 6; // RWR9 - if (group_x_offset[1]&0x200) group_x_offset[1] -= 0x400; // Signed - if (group_y_offset[1]&0x200) group_y_offset[1] -= 0x400; // Signed - - group_x_offset[2] = (sprite_regs[0x28/4] & 0xffc0) >> 6; // RWR10 - group_y_offset[2] = (sprite_regs[0x2c/4] & 0xffc0) >> 6; // RWR11 - if (group_x_offset[2]&0x200) group_x_offset[2] -= 0x400; // Signed - if (group_y_offset[2]&0x200) group_y_offset[2] -= 0x400; // Signed - - group_x_offset[3] = (sprite_regs[0x30/4] & 0xffc0) >> 6; // RWR12 - group_y_offset[3] = (sprite_regs[0x34/4] & 0xffc0) >> 6; // RWR13 - if (group_x_offset[3]&0x200) group_x_offset[3] -= 0x400; // Signed - if (group_y_offset[3]&0x200) group_y_offset[3] -= 0x400; // Signed - - // popmessage ("x %08x y %08x x2 %08x y2 %08x",sprite_x_scroll, sprite_y_scroll,group_x_offset[1], group_y_offset[1]); - // popmessage("%d %d %d %d A:%d B:%d", sprite_kludge_x, sprite_kludge_y, sprite_x_scroll, sprite_y_scroll, (skns_pal_regs[0x00/4] & 0x7000) >> 12, (skns_pal_regs[0x10/4] & 0x7000) >> 12); - // if (keyboard_pressed(KEYCODE_Q)) sprite_kludge_x++; - // if (keyboard_pressed(KEYCODE_W)) sprite_kludge_x--; - // if (keyboard_pressed(KEYCODE_E)) sprite_kludge_y++; - // if (keyboard_pressed(KEYCODE_D)) sprite_kludge_y--; - - // Tilemap Pri/enables - // popmessage("A: %x %x B: %x %x", skns_v3_regs[0x10/4]>>3, skns_v3_regs[0x10/4]&7, skns_v3_regs[0x34/4]>>3, skns_v3_regs[0x34/4]&7); - - /* Seems that sprites are consistently off by a fixed no. of pixels in different games - (Patterns emerge through Manufacturer/Date/Orientation) */ - sprite_x_scroll += sprite_kludge_x; - sprite_y_scroll += sprite_kludge_y; - - - gfxlen = gfx_length; - while( source<finish ) - { - xflip = (source[0] & 0x00000200) >> 9; - yflip = (source[0] & 0x00000100) >> 8; - - ysize = (source[0] & 0x30000000) >> 28; - xsize = (source[0] & 0x03000000) >> 24; - xsize ++; - ysize ++; - - xsize *= 16; - ysize *= 16; - - size = xsize * ysize; - - joint = (source[0] & 0x0000e000) >> 13; - - if (!(joint & 1)) - { - xpos = (source[2] & 0x0000ffc0) >> 6; - ypos = (source[3] & 0x0000ffc0) >> 6; - - xpos += sprite_x_scroll; // Global offset - ypos += sprite_y_scroll; - - if (group_enable) - { - group_number = (source[0] & 0x00001800) >> 11; - - /* the group positioning doesn't seem to be working as i'd expect, - if I apply the x position the cursor on galpani4 ends up moving - from the correct position to too far right, also the y offset - seems to cause the position to be off by one in galpans2 even if - it fixes the position in galpani4? - - even if I take into account the global sprite scroll registers - it isn't right - - global offset kludged using game specific offset -pjp */ - - xpos += group_x_offset[group_number]; - ypos += group_y_offset[group_number]; - } - } - else - { - xpos += (source[2] & 0x0000ffc0) >> 6; - ypos += (source[3] & 0x0000ffc0) >> 6; - } - - if (xpos > 0x1ff) xpos -= 0x400; - if (ypos > 0x1ff) ypos -= 0x400; - - /* Local sprite offset (for taking flip into account and drawing offset) */ - sx = xpos; - sy = ypos; - - /* Global Sprite Flip (sengekis) */ - if (sprite_flip&2) - { - xflip ^= 1; - sx = machine->primary_screen->visible_area().max_x+1 - sx; - } - if (sprite_flip&1) - { - yflip ^= 1; - sy = machine->primary_screen->visible_area().max_y+1 - sy; - } - - /* Palette linking */ - if (!(joint & 2)) - { - colour = (source[0] & 0x0000003f) >> 0; - } - - /* Priority and Tile linking */ - if (!(joint & 4)) - { - romoffset = (source[1] & 0x07ffffff) >> 0; - pri = (source[0] & 0x000000c0) >> 6; - } else { - romoffset = endromoffs; - } - - grow = (source[0]>>23) & 1; - - if (!grow) - { - zoomx_m = (source[2] >> 24)&0x00fc; - zoomx_s = (source[2] >> 16)&0x00fc; - zoomy_m = (source[3] >> 24)&0x00fc; - zoomy_s = (source[3] >> 16)&0x00fc; - } - else - { - // sengekis uses this on sprites which are shrinking as they head towards the ground - // it's also used on the input test of Gals Panic S2 - // - // it appears to offer a higher precision 'shrink' mode (although I'm not entirely - // convinced this implementation is correct because we simply end up ignoring - // part of the data) - zoomx_m = 0; - zoomx_s = (source[2] >> 24)&0x00fc; - zoomy_m = 0; - zoomy_s = (source[3] >> 24)&0x00fc; - - - } - - - romoffset &= gfxlen-1; - - endromoffs = skns_rle_decode ( machine, romoffset, size, gfx_source, gfx_length ); - - // in Cyvern - - // train in tunnel pri = 0x00 - // nothing? = 0x01 - // players etc. pri = 0x02 - // pickups etc. pri = 0x03 - - // PriTest -// if(!( (keyboard_pressed(KEYCODE_Q)&&(pri==0)) || (keyboard_pressed(KEYCODE_W)&&(pri==1)) || (keyboard_pressed(KEYCODE_E)&&(pri==2)) || (keyboard_pressed(KEYCODE_D)&&(pri==3)) )) -// if( !(keyboard_pressed(KEYCODE_Q) && ((source[0] & 0x00800000)>>24)) ) - - - - { - int NewColour = (colour<<8) | (pri << 14); - - if(zoomx_m || zoomx_s || zoomy_m || zoomy_s) - { - blit_z[ (xflip<<1) | yflip ](bitmap, cliprect, decodebuffer, sx, sy, xsize, ysize, zoomx_m, zoomx_s, zoomy_m, zoomy_s, NewColour); - } - else - { - if (!xflip && !yflip) { - int xx,yy; - - for (xx = 0; xx<xsize; xx++) - { - if ((sx+xx < (cliprect->max_x+1)) && (sx+xx >= cliprect->min_x)) - { - for (yy = 0; yy<ysize; yy++) - { - if ((sy+yy < (cliprect->max_y+1)) && (sy+yy >= cliprect->min_y)) - { - int pix; - pix = decodebuffer[xsize*yy+xx]; - if (pix) - *BITMAP_ADDR16(bitmap, sy+yy, sx+xx) = pix+ NewColour; // change later - } - } - } - } - } else if (!xflip && yflip) { - int xx,yy; - sy -= ysize; - - for (xx = 0; xx<xsize; xx++) - { - if ((sx+xx < (cliprect->max_x+1)) && (sx+xx >= cliprect->min_x)) - { - for (yy = 0; yy<ysize; yy++) - { - if ((sy+(ysize-1-yy) < (cliprect->max_y+1)) && (sy+(ysize-1-yy) >= cliprect->min_y)) - { - int pix; - pix = decodebuffer[xsize*yy+xx]; - if (pix) - *BITMAP_ADDR16(bitmap, sy+(ysize-1-yy), sx+xx) = pix+ NewColour; // change later - } - } - } - } - } else if (xflip && !yflip) { - int xx,yy; - sx -= xsize; - - for (xx = 0; xx<xsize; xx++) - { - if ( (sx+(xsize-1-xx) < (cliprect->max_x+1)) && (sx+(xsize-1-xx) >= cliprect->min_x)) - { - for (yy = 0; yy<ysize; yy++) - { - if ((sy+yy < (cliprect->max_y+1)) && (sy+yy >= cliprect->min_y)) - { - int pix; - pix = decodebuffer[xsize*yy+xx]; - if (pix) - *BITMAP_ADDR16(bitmap, sy+yy, sx+(xsize-1-xx)) = pix+ NewColour; // change later - } - } - } - } - } else if (xflip && yflip) { - int xx,yy; - sx -= xsize; - sy -= ysize; - - for (xx = 0; xx<xsize; xx++) - { - if ((sx+(xsize-1-xx) < (cliprect->max_x+1)) && (sx+(xsize-1-xx) >= cliprect->min_x)) - { - for (yy = 0; yy<ysize; yy++) - { - if ((sy+(ysize-1-yy) < (cliprect->max_y+1)) && (sy+(ysize-1-yy) >= cliprect->min_y)) - { - int pix; - pix = decodebuffer[xsize*yy+xx]; - if (pix) - *BITMAP_ADDR16(bitmap, sy+(ysize-1-yy), sx+(xsize-1-xx)) = pix+ NewColour; // change later - } - } - } - } - } - } - }//End PriTest - - source+=4; - } - } -} - static tilemap_t *skns_tilemap_A; static tilemap_t *skns_tilemap_B; @@ -916,6 +374,10 @@ WRITE32_HANDLER ( skns_v3_regs_w ) VIDEO_START(skns) { + skns_state *state = machine->driver_data<skns_state>(); + + state->spritegen = machine->device<sknsspr_device>("spritegen"); + skns_tilemap_A = tilemap_create(machine, get_tilemap_A_tile_info,tilemap_scan_rows,16,16,64, 64); tilemap_set_transparent_pen(skns_tilemap_A,0); @@ -1009,6 +471,8 @@ static void supernova_draw_b( bitmap_t *bitmap, bitmap_t* bitmap_flags, const re SCREEN_UPDATE(skns) { + skns_state *state = screen->machine->driver_data<skns_state>(); + palette_update(screen->machine); bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine)); @@ -1181,7 +645,9 @@ SCREEN_UPDATE(skns) } bitmap_fill(sprite_bitmap, cliprect, 0x0000); - skns_draw_sprites(screen->machine, sprite_bitmap, cliprect, screen->machine->generic.spriteram.u32, screen->machine->generic.spriteram_size, screen->machine->region("gfx1")->base(), screen->machine->region ("gfx1")->bytes(), skns_spc_regs ); + + if (suprnova_alt_enable_sprites) + state->spritegen->skns_draw_sprites(screen->machine, sprite_bitmap, cliprect, screen->machine->generic.spriteram.u32, screen->machine->generic.spriteram_size, screen->machine->region("gfx1")->base(), screen->machine->region ("gfx1")->bytes(), skns_spc_regs ); return 0; |