summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit235b0d2e01aec1e6aa71aeb66ac6d026c169e6ac (patch)
tree60bc1cd4c4db9ba73470687125424e0c3753932a
parent4a8673b63966d80b5a60f4f1e0a04872e7ec4bea (diff)
Moved Kaneko Super Nova sprite chip emulation inside its own file [David Haywood]
-rw-r--r--.gitattributes2
-rw-r--r--src/mame/drivers/galpani3.c13
-rw-r--r--src/mame/drivers/jchan.c28
-rw-r--r--src/mame/drivers/suprnova.c49
-rw-r--r--src/mame/includes/suprnova.h11
-rw-r--r--src/mame/mame.mak1
-rw-r--r--src/mame/video/sknsspr.c575
-rw-r--r--src/mame/video/sknsspr.h36
-rw-r--r--src/mame/video/suprnova.c556
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;