summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/hng64_sprite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/hng64_sprite.c')
-rw-r--r--src/mame/video/hng64_sprite.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/src/mame/video/hng64_sprite.c b/src/mame/video/hng64_sprite.c
new file mode 100644
index 00000000000..0c6f6e37fc3
--- /dev/null
+++ b/src/mame/video/hng64_sprite.c
@@ -0,0 +1,225 @@
+
+/* Hyper NeoGeo 64 Sprite bits */
+
+#include "includes/hng64.h"
+
+/*
+ * Sprite Format
+ * ------------------
+ *
+ * UINT32 | Bits | Use
+ * | 3322 2222 2222 1111 1111 11 |
+ * -------+-1098-7654-3210-9876-5432-1098-7654-3210-+----------------
+ * 0 | yyyy yyyy yyyy yyyy xxxx xxxx xxxx xxxx | x/y position
+ * 1 | YYYY YYYY YYYY YYYY XXXX XXXX XXXX XXXX | x/y zoom (*)
+ * 2 | ---- -zzz zzzz zzzz ---- ---I cccc CCCC | Z-buffer value, 'Inline' chain flag, x/y chain
+ * 3 | ---- ---- pppp pppp ---- ---- ---- ---- | palette entry
+ * 4 | mmmm -?fF a??? tttt tttt tttt tttt tttt | mosaic factor, unknown (**) , flip bits, additive blending, unknown (***), tile number
+ * 5 | ---- ---- ---- ---- ---- ---- ---- ---- | not used ??
+ * 6 | ---- ---- ---- ---- ---- ---- ---- ---- | not used ??
+ * 7 | ---- ---- ---- ---- ---- ---- ---- ---- | not used ??
+ *
+ * (*) Fatal Fury WA standard elements are 0x1000-0x1000, all the other games sets 0x100-0x100, related to the bit 27 of sprite regs 0?
+ * (**) setted by black squares in ranking screen in Samurai Shodown 64 1, sprite disable?
+ * (***) bit 22 is setted on some Fatal Fury WA snow (not all of them), bit 21 is setted on Xrally how to play elements in attract mode
+ *
+ * Sprite Global Registers
+ * -----------------------
+ *
+ * UINT32 | Bits | Use
+ * | 3322 2222 2222 1111 1111 11 |
+ * -------+-1098-7654-3210-9876-5432-1098-7654-3210-+----------------
+ * 0 | ---- z--- b--- ---- ---- ---- ---- ---- | zooming mode, bpp select
+ * 1 | yyyy yyyy yyyy yyyy xxxx xxxx xxxx xxxx | global sprite offset (ss64 rankings in attract)
+ * 2 | ---- ---- ---- ---- ---- ---- ---- ---- |
+ * 3 | ---- ---- ---- ---- ---- ---- ---- ---- |
+ * 4 | ---- ---- ---- ---- ---- ---- ---- ---- |
+ * (anything else is unknown at the current time)
+ * Notes:
+ * [0]
+ * 0xf0000000 setted in both Samurai Shodown
+ * 0x00060000 always setted in all the games
+ * 0x00010000 setted in POST, sprite disable?
+ * [4]
+ * 0x0e0 in Samurai Shodown/Xrally games, 0x1c0 in all the others, zooming factor?
+ */
+
+void hng64_state::draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ gfx_element *gfx;
+ UINT32 *source = m_spriteram;
+ UINT32 *finish = m_spriteram + 0xc000/4;
+
+ // global offsets in sprite regs
+ int spriteoffsx = (m_spriteregs[1]>>0)&0xffff;
+ int spriteoffsy = (m_spriteregs[1]>>16)&0xffff;
+
+#if 0
+ for (int iii = 0; iii < 0x0f; iii++)
+ osd_printf_debug("%.8x ", m_videoregs[iii]);
+ osd_printf_debug("\n");
+#endif
+
+ while( source<finish )
+ {
+ int tileno,chainx,chainy,xflip;
+ int pal,xinc,yinc,yflip;
+ UINT16 xpos, ypos;
+ int xdrw,ydrw;
+ int chaini;
+ int zbuf;
+ UINT32 zoomx,zoomy;
+ float foomX, foomY;
+ int blend;
+ int disable;
+
+
+
+ ypos = (source[0]&0xffff0000)>>16;
+ xpos = (source[0]&0x0000ffff)>>0;
+ xpos += (spriteoffsx);
+ ypos += (spriteoffsy);
+
+ tileno= (source[4]&0x0007ffff);
+ blend= (source[4]&0x00800000);
+ yflip= (source[4]&0x01000000)>>24;
+ xflip= (source[4]&0x02000000)>>25;
+ disable=(source[4]&0x04000000)>>26; // ss64 rankings?
+
+ pal =(source[3]&0x00ff0000)>>16;
+
+ chainy=(source[2]&0x0000000f);
+ chainx=(source[2]&0x000000f0)>>4;
+ chaini=(source[2]&0x00000100);
+ zbuf = (source[2]&0x07ff0000)>>16; //?
+
+ zoomy = (source[1]&0xffff0000)>>16;
+ zoomx = (source[1]&0x0000ffff)>>0;
+
+ #if 1
+ if(zbuf == 0x7ff) //temp kludge to avoid garbage on screen
+ {
+ source+=8;
+ continue;
+ }
+ #endif
+ if(disable)
+ {
+ source+=8;
+ continue;
+ }
+
+#if 0
+ if (!(source[4] == 0x00000000 || source[4] == 0x000000aa))
+ osd_printf_debug("unknown : %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x \n", source[0], source[1], source[2], source[3],
+ source[4], source[5], source[6], source[7]);
+#endif
+
+ /* Calculate the zoom */
+ {
+ int zoom_factor;
+
+ /* FIXME: regular zoom mode has precision bugs, can be easily seen in Samurai Shodown 64 intro */
+ zoom_factor = (m_spriteregs[0] & 0x08000000) ? 0x1000 : 0x100;
+ if(!zoomx) zoomx=zoom_factor;
+ if(!zoomy) zoomy=zoom_factor;
+
+ /* First, prevent any possible divide by zero errors */
+ foomX = (float)(zoom_factor) / (float)zoomx;
+ foomY = (float)(zoom_factor) / (float)zoomy;
+
+ zoomx = ((int)foomX) << 16;
+ zoomy = ((int)foomY) << 16;
+
+ zoomx += (int)((foomX - floor(foomX)) * (float)0x10000);
+ zoomy += (int)((foomY - floor(foomY)) * (float)0x10000);
+ }
+
+ if (m_spriteregs[0] & 0x00800000) //bpp switch
+ {
+ gfx= m_gfxdecode->gfx(4);
+ }
+ else
+ {
+ gfx= m_gfxdecode->gfx(5);
+ tileno>>=1;
+ pal&=0xf;
+ }
+
+ // Accommodate for chaining and flipping
+ if(xflip)
+ {
+ xinc=-(int)(16.0f*foomX);
+ xpos-=xinc*chainx;
+ }
+ else
+ {
+ xinc=(int)(16.0f*foomX);
+ }
+
+ if(yflip)
+ {
+ yinc=-(int)(16.0f*foomY);
+ ypos-=yinc*chainy;
+ }
+ else
+ {
+ yinc=(int)(16.0f*foomY);
+ }
+
+#if 0
+ if (((source[2) & 0xffff0000) >> 16) == 0x0001)
+ {
+ popmessage("T %.8x %.8x %.8x %.8x %.8x", source[0], source[1], source[2], source[3], source[4]);
+ //popmessage("T %.8x %.8x %.8x %.8x %.8x", source[0], source[1], source[2], source[3], source[4]);
+ }
+#endif
+
+ for(ydrw=0;ydrw<=chainy;ydrw++)
+ {
+ for(xdrw=0;xdrw<=chainx;xdrw++)
+ {
+ INT16 drawx = xpos+(xinc*xdrw);
+ INT16 drawy = ypos+(yinc*ydrw);
+
+ // 0x3ff (0x200 sign bit) based on sams64_2 char select
+ drawx &= 0x3ff;
+ drawy &= 0x3ff;
+
+ if (drawx&0x0200)drawx-=0x400;
+ if (drawy&0x0200)drawy-=0x400;
+
+ if (!chaini)
+ {
+ if (!blend) gfx->prio_zoom_transpen(bitmap,cliprect,tileno,pal,xflip,yflip,drawx,drawy,zoomx,zoomy/*0x10000*/,screen.priority(), 0,0);
+ else gfx->prio_zoom_transpen_additive(bitmap,cliprect,tileno,pal,xflip,yflip,drawx,drawy,zoomx,zoomy/*0x10000*/,screen.priority(), 0,0);
+ tileno++;
+ }
+ else // inline chain mode, used by ss64
+ {
+ tileno=(source[4]&0x0007ffff);
+ pal =(source[3]&0x00ff0000)>>16;
+
+ if (m_spriteregs[0] & 0x00800000) //bpp switch
+ {
+ gfx= m_gfxdecode->gfx(4);
+ }
+ else
+ {
+ gfx= m_gfxdecode->gfx(5);
+ tileno>>=1;
+ pal&=0xf;
+ }
+
+ if (!blend) gfx->prio_zoom_transpen(bitmap,cliprect,tileno,pal,xflip,yflip,drawx,drawy,zoomx,zoomy/*0x10000*/,screen.priority(), 0,0);
+ else gfx->prio_zoom_transpen_additive(bitmap,cliprect,tileno,pal,xflip,yflip,drawx,drawy,zoomx,zoomy/*0x10000*/,screen.priority(), 0,0);
+ source +=8;
+ }
+
+ }
+ }
+
+ if (!chaini) source +=8;
+ }
+}
+