mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
SSV - emulate rowscroll effect (#4337)
* start ssv refactoring (nw) * step1, make it horribly inefficient (nw) * bleah, variable reuse within functions for entirely different purposes is annoying * some refactor (nw) * refactor (nw) * (nw) * (nw) * (nw) * refactoring (nw) * refactor (nw0 * refactor (nw) * Revert "refactor (nw)" This reverts commit 21d7fefe1d844be44e20a044b9cd0d75b2bc9695. * refactor (nw) * name tweaks (nw) * refactor (nw) * refactor (nw) * refactor (nw) * refactor (nw) * doesn't need to be a macro (nw) * refactor (nw) * less pointer math (nw) * less variable shadowing (nw) * refactor (nw) * simpler (nw) * moving towards line renderer (nw) * moving closer to a line renderer (nw) * closer (nw) * refactor (nw) * (nw) * (nw) * terminology changes (nw) * maybe (nw) * emulate rowscroll effect
This commit is contained in:
parent
45143caaaf
commit
ff0150a9e8
@ -169,9 +169,15 @@ private:
|
||||
void update_irq_state();
|
||||
IRQ_CALLBACK_MEMBER(irq_callback);
|
||||
|
||||
void drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,uint32_t code,uint32_t color,int flipx,int flipy,int x0,int y0,int shadow);
|
||||
void draw_row(bitmap_ind16 &bitmap, const rectangle &cliprect, int sx, int sy, int scroll);
|
||||
void drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow, int realline, int line);
|
||||
void drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy,int shadow);
|
||||
|
||||
void draw_16x16_tile_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int flipx, int flipy, int mode, int code, int color, int sx, int sy, int realline, int line);
|
||||
void get_tile(int x, int y, int size, int page, int& code, int& attr, int& flipx, int& flipy);
|
||||
void draw_row_64pixhigh(bitmap_ind16 &bitmap, const rectangle &cliprect, int in_sy, int scroll);
|
||||
void draw_layer(bitmap_ind16 &bitmap, const rectangle &cliprect, int nr);
|
||||
|
||||
void draw_sprites_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect, int code, int flipx, int flipy, int gfx, int shadow, int color, int sx, int sy, int xnum, int ynum);
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void enable_video(int enable);
|
||||
void init(int interrupt_ultrax);
|
||||
|
@ -93,15 +93,13 @@
|
||||
|
||||
2.h Scroll Y
|
||||
|
||||
4.h Priority ? (0000, 0401, 0440, 057f, 05ff)
|
||||
4.h Priority ? (0000, 0401, 0440, 057f, 05ff) (seems to control offsets too)
|
||||
|
||||
6.h fed- ---- ---- ---- Tilemap width (games only use 1 -> $200, 2 -> $400)
|
||||
---c ---- ---- ---- ?
|
||||
---- b--- ---- ---- Shadow
|
||||
---c ---- ---- ---- Rowscroll enable
|
||||
---- b--- ---- ---- Shadow mode
|
||||
---- -a98 ---- ---- Each bit enables 2 bitplanes*
|
||||
---- ---- 7654 3210 ? some games leave it to 0, others
|
||||
use e.g 28 for scroll 0, 29 for
|
||||
scroll 1, 2a etc.
|
||||
---- ---- 7654 3210 Rowscroll base (multiply by 0x400)
|
||||
|
||||
Where scroll x&y refer to a virtual $8000 x $200 tilemap (filling the
|
||||
whole spriteram) made of 16x16 tiles. A tile uses 4 bytes:
|
||||
@ -132,8 +130,6 @@
|
||||
The number of low bits from the "shadowing tile" is 4 or 2, depending on
|
||||
bit 7 of 1c0076.
|
||||
|
||||
Note: press Z to show some info on each sprite (debug builds only)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
@ -141,52 +137,43 @@ Note: press Z to show some info on each sprite (debug builds only)
|
||||
#include "render.h"
|
||||
|
||||
|
||||
void ssv_state::drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,
|
||||
uint32_t code,uint32_t color,int flipx,int flipy,int x0,int y0,
|
||||
int shadow )
|
||||
void ssv_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow, int realline, int line)
|
||||
{
|
||||
const uint8_t *addr, *source;
|
||||
uint8_t pen;
|
||||
uint16_t *dest;
|
||||
int sx, x1, dx;
|
||||
int sy, y1, dy;
|
||||
const uint8_t *const addr = gfx->get_data(code % gfx->elements());
|
||||
const uint32_t realcolor = gfx->granularity() * (color % gfx->colors());
|
||||
|
||||
addr = gfx->get_data(code % gfx->elements());
|
||||
color = gfx->granularity() * (color % gfx->colors());
|
||||
const uint8_t* const source = flipy ? addr + (7 - line) * gfx->rowbytes() : addr + line * gfx->rowbytes();
|
||||
|
||||
if ( flipx ) { x1 = x0-1; x0 += gfx->width()-1; dx = -1; }
|
||||
else { x1 = x0 + gfx->width(); dx = 1; }
|
||||
|
||||
if ( flipy ) { y1 = y0-1; y0 += gfx->height()-1; dy = -1; }
|
||||
else { y1 = y0 + gfx->height(); dy = 1; }
|
||||
|
||||
#define SSV_DRAWGFX(SETPIXELCOLOR) \
|
||||
for ( sy = y0; sy != y1; sy += dy ) \
|
||||
{ \
|
||||
if ( sy >= cliprect.min_y && sy <= cliprect.max_y ) \
|
||||
{ \
|
||||
source = addr; \
|
||||
dest = &bitmap.pix16(sy); \
|
||||
\
|
||||
for ( sx = x0; sx != x1; sx += dx ) \
|
||||
{ \
|
||||
pen = *source++; \
|
||||
\
|
||||
if ( pen && sx >= cliprect.min_x && sx <= cliprect.max_x ) \
|
||||
SETPIXELCOLOR \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
addr += gfx->rowbytes(); \
|
||||
}
|
||||
|
||||
if (shadow)
|
||||
if (realline >= cliprect.min_y && realline <= cliprect.max_y)
|
||||
{
|
||||
SSV_DRAWGFX( { dest[sx] = ((dest[sx] & m_shadow_pen_mask) | (pen << m_shadow_pen_shift)) & 0x7fff; } )
|
||||
uint16_t* dest = &bitmap.pix16(realline);
|
||||
|
||||
const int x0 = flipx ? (base_sx + gfx->width() - 1) : (base_sx);
|
||||
const int x1 = flipx ? (base_sx - 1) : (x0 + gfx->width());
|
||||
const int dx = flipx ? (-1) : (1);
|
||||
|
||||
int column = 0;
|
||||
for (int sx = x0; sx != x1; sx += dx)
|
||||
{
|
||||
uint8_t pen = source[column];
|
||||
|
||||
if (pen && sx >= cliprect.min_x && sx <= cliprect.max_x)
|
||||
{
|
||||
if (shadow)
|
||||
dest[sx] = ((dest[sx] & m_shadow_pen_mask) | (pen << m_shadow_pen_shift)) & 0x7fff; \
|
||||
else
|
||||
dest[sx] = (realcolor + pen) & 0x7fff;
|
||||
}
|
||||
column++;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
void ssv_state::drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow)
|
||||
{
|
||||
for (int line = 0; line < 8; line++)
|
||||
{
|
||||
SSV_DRAWGFX( { dest[sx] = (color + pen) & 0x7fff; } )
|
||||
drawgfx_line(bitmap, cliprect, gfx, code, color, flipx, flipy, base_sx, base_sy, shadow, base_sy+line, line);
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,362 +566,326 @@ From the above some noteworthy cases are:
|
||||
|
||||
/* Draw a tilemap sprite */
|
||||
|
||||
void ssv_state::draw_row(bitmap_ind16 &bitmap, const rectangle &cliprect, int sx, int sy, int scroll)
|
||||
|
||||
void ssv_state::draw_16x16_tile_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int flipx, int flipy, int mode, int code, int color, int sx, int sy, int realline, int line)
|
||||
{
|
||||
uint16_t *spriteram16 = m_spriteram;
|
||||
uint16_t *ssv_scroll = m_scroll;
|
||||
rectangle clip;
|
||||
int attr, code, color, mode, size, page, shadow;
|
||||
int x, x1, sx1, flipx, xnum, xstart, xend, xinc;
|
||||
int y, y1, sy1, flipy, ynum, ystart, yend, yinc;
|
||||
uint16_t *s3;
|
||||
/* Force 16x16 tiles ? */
|
||||
int realcode;
|
||||
if (flipy)
|
||||
{
|
||||
if (line & 8)
|
||||
realcode = code ;
|
||||
else
|
||||
realcode = code + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line & 8)
|
||||
realcode = code + 1;
|
||||
else
|
||||
realcode = code;
|
||||
}
|
||||
int tileline = line & 7;
|
||||
|
||||
xnum = 0x20; // width in tiles (screen-wide)
|
||||
ynum = 0x8; // height in tiles (always 64 pixels?)
|
||||
int shadow = (mode & 0x0800);
|
||||
/* Select 256 or 64 color tiles */
|
||||
int gfx = ((mode & 0x0100) ? 0 : 1);
|
||||
|
||||
scroll &= 0x7; // scroll register index
|
||||
drawgfx_line(bitmap, cliprect, m_gfxdecode->gfx(gfx), realcode, color, flipx, flipy, sx, sy, shadow, realline, tileline);
|
||||
|
||||
/* Sign extend the position */
|
||||
sx = 0;
|
||||
sy = (sy & 0x1ff) - (sy & 0x200);
|
||||
}
|
||||
|
||||
inline void ssv_state::get_tile(int x, int y, int size, int page, int& code, int& attr, int& flipx, int& flipy)
|
||||
{
|
||||
uint16_t* s3 = &m_spriteram[page * (size * ((0x1000 / 0x200) / 2)) +
|
||||
((x & ((size - 1) & ~0xf)) << 2) +
|
||||
((y & ((0x200 - 1) & ~0xf)) >> 3)];
|
||||
|
||||
code = s3[0]; // code high bits
|
||||
attr = s3[1]; // code low bits + color
|
||||
|
||||
/* Code's high bits are scrambled */
|
||||
code += m_tile_code[(attr & 0x3c00) >> 10];
|
||||
flipy = (attr & 0x4000);
|
||||
flipx = (attr & 0x8000);
|
||||
|
||||
if ((m_scroll[0x74 / 2] & 0x1000) && ((m_scroll[0x74 / 2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipx == 0) flipx = 1; else flipx = 0;
|
||||
}
|
||||
if ((m_scroll[0x74 / 2] & 0x4000) && ((m_scroll[0x74 / 2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipy == 0) flipy = 1; else flipy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ssv_state::draw_row_64pixhigh(bitmap_ind16 &bitmap, const rectangle &cliprect, int in_sy, int scrollreg)
|
||||
{
|
||||
scrollreg &= 0x7; // scroll register index
|
||||
|
||||
/* in_sy will always be 0x00, 0x40, 0x80, 0xc0 in 'draw layer' */
|
||||
in_sy = (in_sy & 0x1ff) - (in_sy & 0x200);
|
||||
|
||||
/* Set up a clipping region for the tilemap slice .. */
|
||||
|
||||
clip.set(sx, sx + xnum * 0x10 - 1, sy, sy + ynum * 0x8 - 1);
|
||||
rectangle outclip;
|
||||
outclip.set(0, 0x20/*width in tiles*/ * 0x10, in_sy, in_sy + 0x8/*height in tiles, always 64 pixels*/ * 0x8);
|
||||
|
||||
/* .. and clip it against the visible screen */
|
||||
|
||||
if (clip.min_x > cliprect.max_x) return;
|
||||
if (clip.min_y > cliprect.max_y) return;
|
||||
if (outclip.min_x > cliprect.max_x) return;
|
||||
if (outclip.min_y > cliprect.max_y) return;
|
||||
|
||||
if (clip.max_x < cliprect.min_x) return;
|
||||
if (clip.max_y < cliprect.min_y) return;
|
||||
if (outclip.max_x < cliprect.min_x) return;
|
||||
if (outclip.max_y < cliprect.min_y) return;
|
||||
|
||||
if (clip.min_x < cliprect.min_x) clip.min_x = cliprect.min_x;
|
||||
if (clip.max_x > cliprect.max_x) clip.max_x = cliprect.max_x;
|
||||
outclip &= cliprect;
|
||||
|
||||
if (clip.min_y < cliprect.min_y) clip.min_y = cliprect.min_y;
|
||||
if (clip.max_y > cliprect.max_y) clip.max_y = cliprect.max_y;
|
||||
|
||||
/* Get the scroll data */
|
||||
x = ssv_scroll[ scroll * 4 + 0 ]; // x scroll
|
||||
y = ssv_scroll[ scroll * 4 + 1 ]; // y scroll
|
||||
// ssv_scroll[ scroll * 4 + 2 ]; // ???
|
||||
mode = ssv_scroll[ scroll * 4 + 3 ]; // layer disabled, shadow, depth etc.
|
||||
|
||||
/* Background layer disabled */
|
||||
if ((mode & 0xe000) == 0)
|
||||
return;
|
||||
|
||||
shadow = (mode & 0x0800);
|
||||
|
||||
/* Decide the actual size of the tilemap */
|
||||
size = 1 << (8 + ((mode & 0xe000) >> 13));
|
||||
page = (x & 0x7fff) / size;
|
||||
|
||||
/* Given a fixed scroll value, the portion of tilemap displayed changes with the sprite position */
|
||||
x += sx;
|
||||
y += sy;
|
||||
|
||||
/* Tweak the scroll values */
|
||||
// x += 0;
|
||||
y += ((ssv_scroll[0x70/2] & 0x1ff) - (ssv_scroll[0x70/2] & 0x200) + ssv_scroll[0x6a/2] + 2);
|
||||
|
||||
// Kludge for eaglshot
|
||||
if ((ssv_scroll[ scroll * 4 + 2 ] & 0x05ff) == 0x0440) x += -0x10;
|
||||
if ((ssv_scroll[ scroll * 4 + 2 ] & 0x05ff) == 0x0401) x += -0x20;
|
||||
|
||||
/* Draw the rows */
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
sx1 = sx - (x & 0xf);
|
||||
sy1 = sy - (y & 0xf);
|
||||
|
||||
for (sx=sx1,x=x1; sx <= clip.max_x; sx+=0x10,x+=0x10)
|
||||
for (int line = outclip.min_y; line <= outclip.max_y; line++)
|
||||
{
|
||||
for (sy=sy1,y=y1; sy <= clip.max_y; sy+=0x10,y+=0x10)
|
||||
rectangle clip;
|
||||
clip.set(outclip.min_x, outclip.max_x, line, line);
|
||||
|
||||
/* Get the scroll data */
|
||||
int tilemap_scrollx = m_scroll[scrollreg * 4 + 0]; // x scroll
|
||||
int tilemap_scrolly = m_scroll[scrollreg * 4 + 1]; // y scroll
|
||||
int unknown = m_scroll[scrollreg * 4 + 2]; // ???
|
||||
int mode = m_scroll[scrollreg * 4 + 3]; // layer disabled, shadow, depth etc.
|
||||
|
||||
/* Background layer disabled */
|
||||
if ((mode & 0xe000) == 0)
|
||||
return;
|
||||
|
||||
/* Decide the actual size of the tilemap */
|
||||
int size = 1 << (8 + ((mode & 0xe000) >> 13));
|
||||
int page = (tilemap_scrollx & 0x7fff) / size;
|
||||
|
||||
/* Given a fixed scroll value, the portion of tilemap displayed changes with the sprite position */
|
||||
tilemap_scrolly += in_sy;
|
||||
|
||||
/* Tweak the scroll values */
|
||||
tilemap_scrolly += ((m_scroll[0x70 / 2] & 0x1ff) - (m_scroll[0x70 / 2] & 0x200) + m_scroll[0x6a / 2] + 2);
|
||||
|
||||
// Kludge for eaglshot
|
||||
if ((unknown & 0x05ff) == 0x0440) tilemap_scrollx += -0x10;
|
||||
if ((unknown & 0x05ff) == 0x0401) tilemap_scrollx += -0x20;
|
||||
|
||||
int realy = tilemap_scrolly + (line - in_sy);
|
||||
|
||||
if ((mode & 0x1000))
|
||||
{
|
||||
int tx, ty, gfx;
|
||||
|
||||
s3 = &spriteram16[ page * (size * ((0x1000/0x200)/2)) +
|
||||
((x & ((size -1) & ~0xf)) << 2) +
|
||||
((y & ((0x200-1) & ~0xf)) >> 3) ];
|
||||
|
||||
code = s3[0]; // code high bits
|
||||
attr = s3[1]; // code low bits + color
|
||||
|
||||
/* Code's high bits are scrambled */
|
||||
code += m_tile_code[(attr & 0x3c00)>>10];
|
||||
flipy = (attr & 0x4000);
|
||||
flipx = (attr & 0x8000);
|
||||
|
||||
if ((ssv_scroll[0x74/2] & 0x1000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipx == 0) flipx = 1; else flipx = 0;
|
||||
}
|
||||
if ((ssv_scroll[0x74/2] & 0x4000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipy == 0) flipy = 1; else flipy = 0;
|
||||
}
|
||||
|
||||
color = attr;
|
||||
|
||||
/* Select 256 or 64 color tiles */
|
||||
gfx = ((mode & 0x0100) ? 0 : 1);
|
||||
|
||||
/* Force 16x16 tiles ? */
|
||||
if (flipx) { xstart = 1-1; xend = -1; xinc = -1; }
|
||||
else { xstart = 0; xend = 1; xinc = +1; }
|
||||
|
||||
if (flipy) { ystart = 2-1; yend = -1; yinc = -1; }
|
||||
else { ystart = 0; yend = 2; yinc = +1; }
|
||||
|
||||
/* Draw a tile (16x16) */
|
||||
for (tx = xstart; tx != xend; tx += xinc)
|
||||
{
|
||||
for (ty = ystart; ty != yend; ty += yinc)
|
||||
{
|
||||
drawgfx( bitmap, clip, m_gfxdecode->gfx(gfx),
|
||||
code++,
|
||||
color,
|
||||
flipx, flipy,
|
||||
sx + tx * 16, sy + ty * 8,
|
||||
shadow );
|
||||
} /* ty */
|
||||
} /* tx */
|
||||
|
||||
} /* sy */
|
||||
} /* sx */
|
||||
uint32_t scrolltable_base = ((mode & 0x00ff) * 0x400 ) /2;
|
||||
//logerror("line %d realy %04x: scrolltable base is %08x\n", line,realy&0x1ff, scrolltable_base*2);
|
||||
tilemap_scrollx += m_spriteram[(scrolltable_base+(realy&0x1ff)) & 0x1ffff];
|
||||
}
|
||||
|
||||
/* Draw the rows */
|
||||
int sx1 = 0 - (tilemap_scrollx & 0xf);
|
||||
int x = tilemap_scrollx;
|
||||
for (int sx = sx1; sx <= clip.max_x; sx += 0x10)
|
||||
{
|
||||
int code, attr, flipx, flipy;
|
||||
get_tile(x, realy, size, page, code, attr, flipx, flipy);
|
||||
draw_16x16_tile_line(bitmap, clip, flipx, flipy, mode, code, attr, sx, realy, line,realy & 0xf);
|
||||
x += 0x10;
|
||||
} /* sx */
|
||||
} /* line */
|
||||
}
|
||||
|
||||
/* Draw the "background layer" using multiple tilemap sprites */
|
||||
|
||||
void ssv_state::draw_layer(bitmap_ind16 &bitmap, const rectangle &cliprect, int nr)
|
||||
{
|
||||
int sy;
|
||||
for ( sy = 0; sy <= m_screen->visible_area().max_y; sy += 0x40 )
|
||||
draw_row(bitmap, cliprect, 0, sy, nr);
|
||||
for ( int sy = 0; sy <= m_screen->visible_area().max_y; sy += 0x40 )
|
||||
draw_row_64pixhigh(bitmap, cliprect, sy, nr);
|
||||
}
|
||||
|
||||
void ssv_state::draw_sprites_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect, int code, int flipx, int flipy, int gfx, int shadow, int color, int sx, int sy, int xnum, int ynum)
|
||||
{
|
||||
int xstart, xend, xinc;
|
||||
int ystart, yend, yinc;
|
||||
|
||||
/* Draw the tiles */
|
||||
if (flipx) { xstart = xnum - 1; xend = -1; xinc = -1; }
|
||||
else { xstart = 0; xend = xnum; xinc = +1; }
|
||||
|
||||
if (flipy) { ystart = ynum - 1; yend = -1; yinc = -1; }
|
||||
else { ystart = 0; yend = ynum; yinc = +1; }
|
||||
|
||||
for (int x = xstart; x != xend; x += xinc)
|
||||
{
|
||||
for (int y = ystart; y != yend; y += yinc)
|
||||
{
|
||||
drawgfx(bitmap, cliprect, m_gfxdecode->gfx(gfx),
|
||||
code++,
|
||||
color,
|
||||
flipx, flipy,
|
||||
sx + x * 16, sy + y * 8,
|
||||
shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Draw sprites in the sprites list */
|
||||
|
||||
void ssv_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* Sprites list */
|
||||
uint16_t *ssv_scroll = m_scroll;
|
||||
uint16_t *spriteram16 = m_spriteram;
|
||||
uint16_t *spritelist_global = m_spriteram;
|
||||
uint16_t *spritelist_global_end = m_spriteram + 0x02000 / 2;
|
||||
|
||||
uint16_t *s1 = spriteram16;
|
||||
uint16_t *end1 = spriteram16 + 0x02000/2;
|
||||
uint16_t *end2 = spriteram16 + 0x40000/2;
|
||||
uint16_t *s2;
|
||||
|
||||
for ( ; s1 < end1; s1+=4 )
|
||||
for (; spritelist_global < spritelist_global_end; spritelist_global += 4)
|
||||
{
|
||||
int attr, code, color, num, sprite;
|
||||
int sx, x, xoffs, flipx, xnum, xstart, xend, xinc, sprites_offsx;
|
||||
int sy, y, yoffs, flipy, ynum, ystart, yend, yinc, sprites_offsy, tilemaps_offsy;
|
||||
int mode,global_depth,global_xnum,global_ynum;
|
||||
|
||||
mode = s1[ 0 ];
|
||||
sprite = s1[ 1 ];
|
||||
xoffs = s1[ 2 ];
|
||||
yoffs = s1[ 3 ];
|
||||
int sprite = spritelist_global[1];
|
||||
|
||||
/* Last sprite */
|
||||
if (sprite & 0x8000) break;
|
||||
|
||||
/* Single-sprite address */
|
||||
s2 = &spriteram16[ (sprite & 0x7fff) * 4 ];
|
||||
tilemaps_offsy = ((s2[3] & 0x1ff) - (s2[3] & 0x200));
|
||||
uint16_t* spritelist_local = &m_spriteram[(sprite & 0x7fff) * 4];
|
||||
int tilemaps_offsy = ((spritelist_local[3] & 0x1ff) - (spritelist_local[3] & 0x200));
|
||||
|
||||
/* Every single sprite is offset by x & yoffs, and additionally
|
||||
by one of the 8 x & y offsets in the 1c0040-1c005f area */
|
||||
int mode = spritelist_global[0];
|
||||
|
||||
xoffs += ssv_scroll[((mode & 0x00e0) >> 4) + 0x40/2];
|
||||
yoffs += ssv_scroll[((mode & 0x00e0) >> 4) + 0x42/2];
|
||||
/* Number of single-sprites int local list (1-32) */
|
||||
int local_num = (mode & 0x001f);
|
||||
|
||||
/* Number of single-sprites (1-32) */
|
||||
num = (mode & 0x001f) + 1;
|
||||
global_ynum = (mode & 0x0300) << 2;
|
||||
global_xnum = (mode & 0x0c00);
|
||||
global_depth = (mode & 0xf000);
|
||||
|
||||
for( ; num > 0; num--,s2+=4 )
|
||||
for (int count = 0; count <= local_num; count++, spritelist_local += 4)
|
||||
{
|
||||
int depth, local_depth, local_xnum, local_ynum;
|
||||
uint16_t *spritelist_local_end = m_spriteram + 0x40000 / 2;
|
||||
|
||||
if (s2 >= end2) break;
|
||||
if (spritelist_local >= spritelist_local_end) break;
|
||||
|
||||
sx = s2[ 2 ];
|
||||
sy = s2[ 3 ];
|
||||
int sx = spritelist_local[2];
|
||||
int sy = spritelist_local[3];
|
||||
|
||||
local_depth = sx & 0xf000;
|
||||
local_xnum = sx & 0x0c00;
|
||||
local_ynum = sy & 0x0c00;
|
||||
/* do we use local sizes (set here) or global ones (set in previous list) */
|
||||
int use_local = m_scroll[0x76 / 2] & 0x4000;
|
||||
|
||||
if (ssv_scroll[0x76/2] & 0x4000)
|
||||
{
|
||||
xnum = local_xnum;
|
||||
ynum = local_ynum;
|
||||
depth = local_depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
xnum = global_xnum;
|
||||
ynum = global_ynum;
|
||||
depth = global_depth;
|
||||
}
|
||||
int xnum = use_local ? (sx & 0x0c00) : (mode & 0x0c00);
|
||||
int ynum = use_local ? (sy & 0x0c00) : (mode & 0x0300) << 2;
|
||||
int depth = use_local ? (sx & 0xf000) : (mode & 0xf000);
|
||||
|
||||
if ( s2[0] <= 7 && s2[1] == 0 && xnum == 0 && ynum == 0x0c00)
|
||||
if (spritelist_local[0] <= 7 && spritelist_local[1] == 0 && xnum == 0 && ynum == 0x0c00)
|
||||
{
|
||||
// Tilemap Sprite
|
||||
int scroll;
|
||||
|
||||
scroll = s2[ 0 ]; // scroll index
|
||||
scroll = spritelist_local[0]; // scroll index
|
||||
|
||||
if (ssv_scroll[0x76/2] & 0x1000)
|
||||
if (m_scroll[0x76 / 2] & 0x1000)
|
||||
sy -= 0x20; // eaglshot
|
||||
else
|
||||
{
|
||||
if (ssv_scroll[0x7a/2] & 0x0800)
|
||||
if (m_scroll[0x7a / 2] & 0x0800)
|
||||
{
|
||||
if (ssv_scroll[0x7a/2] & 0x1000) // drifto94, dynagear, keithlcy, mslider, stmblade, gdfs, ultrax, twineag2
|
||||
if (m_scroll[0x7a / 2] & 0x1000) // drifto94, dynagear, keithlcy, mslider, stmblade, gdfs, ultrax, twineag2
|
||||
sy -= tilemaps_offsy;
|
||||
else // srmp4
|
||||
sy += tilemaps_offsy;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mode & 0x001f) != 0)
|
||||
draw_row(bitmap, cliprect, sx, sy, scroll);
|
||||
if (local_num != 0)
|
||||
draw_row_64pixhigh(bitmap, cliprect, sy, scroll);
|
||||
}
|
||||
else
|
||||
{
|
||||
// "Normal" Sprite
|
||||
/*
|
||||
hot spots:
|
||||
"warning" in hypreac2 has mode & 0x0100 and is not 16x16
|
||||
keithlcy high scores has mode & 0x0100 and y & 0x0c00 can be 0x0c00
|
||||
drifto94 "you have proved yOur".. has mode & 0x0100 and x & 0x0c00 can be 0x0c00
|
||||
ultrax (begin of lev1): 100010: 6b60 4280 0016 00a0
|
||||
121400: 51a0 0042 6800 0c00 needs to be a normal sprite
|
||||
*/
|
||||
/*
|
||||
hot spots:
|
||||
"warning" in hypreac2 has mode & 0x0100 and is not 16x16
|
||||
keithlcy high scores has mode & 0x0100 and y & 0x0c00 can be 0x0c00
|
||||
drifto94 "you have proved yOur".. has mode & 0x0100 and x & 0x0c00 can be 0x0c00
|
||||
ultrax (begin of lev1): 100010: 6b60 4280 0016 00a0
|
||||
121400: 51a0 0042 6800 0c00 needs to be a normal sprite
|
||||
*/
|
||||
|
||||
int shadow, gfx;
|
||||
if (s2 >= end2) break;
|
||||
|
||||
code = s2[0]; // code high bits
|
||||
attr = s2[1]; // code low bits + color
|
||||
int code = spritelist_local[0]; // code high bits
|
||||
int attr = spritelist_local[1]; // code low bits + color
|
||||
|
||||
/* Code's high bits are scrambled */
|
||||
code += m_tile_code[(attr & 0x3c00)>>10];
|
||||
flipy = (attr & 0x4000);
|
||||
flipx = (attr & 0x8000);
|
||||
code += m_tile_code[(attr & 0x3c00) >> 10];
|
||||
int flipy = (attr & 0x4000);
|
||||
int flipx = (attr & 0x8000);
|
||||
|
||||
if ((ssv_scroll[0x74/2] & 0x1000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
if ((m_scroll[0x74 / 2] & 0x1000) && ((m_scroll[0x74 / 2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipx == 0) flipx = 1; else flipx = 0;
|
||||
}
|
||||
if ((ssv_scroll[0x74/2] & 0x4000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
if ((m_scroll[0x74 / 2] & 0x4000) && ((m_scroll[0x74 / 2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipy == 0) flipy = 1; else flipy = 0;
|
||||
}
|
||||
|
||||
color = attr;
|
||||
|
||||
/* Select 256 or 64 color tiles */
|
||||
gfx = (depth & 0x1000) ? 0 : 1;
|
||||
shadow = (depth & 0x8000);
|
||||
int gfx = (depth & 0x1000) ? 0 : 1;
|
||||
int shadow = (depth & 0x8000);
|
||||
|
||||
/* Single-sprite tile size */
|
||||
xnum = 1 << (xnum >> 10); // 1, 2, 4 or 8 tiles
|
||||
ynum = 1 << (ynum >> 10); // 1, 2, 4 tiles (8 means tilemap sprite?)
|
||||
|
||||
if (flipx) { xstart = xnum-1; xend = -1; xinc = -1; }
|
||||
else { xstart = 0; xend = xnum; xinc = +1; }
|
||||
|
||||
if (flipy) { ystart = ynum-1; yend = -1; yinc = -1; }
|
||||
else { ystart = 0; yend = ynum; yinc = +1; }
|
||||
/* Every single sprite is offset by x & yoffs, and additionally
|
||||
by one of the 8 x & y offsets in the 1c0040-1c005f area */
|
||||
|
||||
/* Apply global offsets */
|
||||
sx += xoffs;
|
||||
sy += yoffs;
|
||||
int scrollreg = ((mode & 0x00e0) >> 4);
|
||||
|
||||
sx += spritelist_global[2] + m_scroll[scrollreg + (0x40 / 2)];
|
||||
sy += spritelist_global[3] + m_scroll[scrollreg + (0x42 / 2)];
|
||||
|
||||
/* Sign extend the position */
|
||||
sx = (sx & 0x1ff) - (sx & 0x200);
|
||||
sy = (sy & 0x1ff) - (sy & 0x200);
|
||||
sx = (sx & 0x1ff) - (sx & 0x200);
|
||||
sy = (sy & 0x1ff) - (sy & 0x200);
|
||||
|
||||
sprites_offsx = ((ssv_scroll[0x74/2] & 0x7f) - (ssv_scroll[0x74/2] & 0x80));
|
||||
int sprites_offsx = ((m_scroll[0x74 / 2] & 0x7f) - (m_scroll[0x74 / 2] & 0x80));
|
||||
|
||||
sprites_offsy = -((ssv_scroll[0x70/2] & 0x1ff) - (ssv_scroll[0x70/2] & 0x200) + ssv_scroll[0x6a/2] + 1);
|
||||
int sprites_offsy = -((m_scroll[0x70 / 2] & 0x1ff) - (m_scroll[0x70 / 2] & 0x200) + m_scroll[0x6a / 2] + 1);
|
||||
|
||||
if (ssv_scroll[0x74/2] & 0x4000) // flipscreen y
|
||||
if (m_scroll[0x74 / 2] & 0x4000) // flipscreen y
|
||||
{
|
||||
sy = -sy;
|
||||
if (ssv_scroll[0x74/2] & 0x8000)
|
||||
if (m_scroll[0x74 / 2] & 0x8000)
|
||||
sy += 0x00; //
|
||||
else
|
||||
sy -= 0x10; // vasara (hack)
|
||||
}
|
||||
|
||||
if (ssv_scroll[0x74/2] & 0x1000) // flipscreen x
|
||||
if (m_scroll[0x74 / 2] & 0x1000) // flipscreen x
|
||||
{
|
||||
sx = -sx + 0x100;
|
||||
}
|
||||
|
||||
/* Single-sprite tile size */
|
||||
xnum = 1 << (xnum >> 10); // 1, 2, 4 or 8 tiles
|
||||
ynum = 1 << (ynum >> 10); // 1, 2, 4 tiles (8 means tilemap sprite?)
|
||||
|
||||
// sprites can be relative to a side, the other side or the center
|
||||
|
||||
if (ssv_scroll[0x7a/2] == 0x7140)
|
||||
if (m_scroll[0x7a / 2] == 0x7140)
|
||||
{
|
||||
// srmp7
|
||||
sx = sprites_offsx + sx;
|
||||
sy = sprites_offsy - sy;
|
||||
sx = sprites_offsx + sx;
|
||||
sy = sprites_offsy - sy;
|
||||
}
|
||||
else if (ssv_scroll[0x7a/2] & 0x0800)
|
||||
else if (m_scroll[0x7a / 2] & 0x0800)
|
||||
{
|
||||
// dynagear, drifto94, eaglshot, keithlcy, mslider, srmp4, stmblade, twineag2, ultrax
|
||||
sx = sprites_offsx + sx - (xnum * 8) ;
|
||||
sy = sprites_offsy - sy - (ynum * 8) / 2;
|
||||
sx = sprites_offsx + sx - (xnum * 8);
|
||||
sy = sprites_offsy - sy - (ynum * 8) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hypreact, hypreac2, janjans1, meosism, ryorioh, survarts, sxyreact, sxyreac2, vasara, vasara2
|
||||
sx = sprites_offsx + sx;
|
||||
sy = sprites_offsy - sy - (ynum * 8);
|
||||
// hypreact, hypreac2, janjanspritelist_global, meosism, ryorioh, survarts, sxyreact, sxyreac2, vasara, vasara2
|
||||
sx = sprites_offsx + sx;
|
||||
sy = sprites_offsy - sy - (ynum * 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Sprite code masking */
|
||||
if (xnum == 2 && ynum == 4) // needed by hypreact
|
||||
{
|
||||
code &= ~7;
|
||||
}
|
||||
|
||||
/* Draw the tiles */
|
||||
|
||||
for (x = xstart; x != xend; x += xinc)
|
||||
{
|
||||
for (y = ystart; y != yend; y += yinc)
|
||||
{
|
||||
drawgfx( bitmap, cliprect, m_gfxdecode->gfx(gfx),
|
||||
code++,
|
||||
color,
|
||||
flipx, flipy,
|
||||
sx + x * 16, sy + y * 8,
|
||||
shadow );
|
||||
}
|
||||
}
|
||||
|
||||
// #ifdef MAME_DEBUG
|
||||
// if (machine().input().code_pressed(KEYCODE_Z)) /* Display some info on each sprite */
|
||||
// { char buf[30];
|
||||
// sprintf(buf, "%02X",/*(s2[2] & ~0x3ff)>>8*/mode>>8);
|
||||
// machine().ui().draw_text(&machine().render().ui_container(), buf, sx, sy);
|
||||
// }
|
||||
// #endif
|
||||
draw_sprites_tiles(bitmap, cliprect, code, flipx, flipy, gfx, shadow, attr, sx, sy, xnum, ynum);
|
||||
|
||||
} /* sprite type */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user