diff options
author | David Haywood <mamehaze@gmail.com> | 2018-11-25 19:42:50 +0000 |
---|---|---|
committer | ajrhacker <ajrhacker@users.noreply.github.com> | 2018-11-25 14:42:50 -0500 |
commit | ff0150a9e8616c46ad13bccf3782fd7ff6ed8013 (patch) | |
tree | b5ef196f1f929fad7513e0964bb8b89c6d896f1b | |
parent | 45143caaafa8d40eba79cc2c5b4499ac2939a53d (diff) |
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
-rw-r--r-- | src/mame/includes/ssv.h | 10 | ||||
-rw-r--r-- | src/mame/video/ssv.cpp | 517 |
2 files changed, 242 insertions, 285 deletions
diff --git a/src/mame/includes/ssv.h b/src/mame/includes/ssv.h index 59f827c7a44..bce3ea60075 100644 --- a/src/mame/includes/ssv.h +++ b/src/mame/includes/ssv.h @@ -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); diff --git a/src/mame/video/ssv.cpp b/src/mame/video/ssv.cpp index 48b1bb3465b..7cfcbbf8fe2 100644 --- a/src/mame/video/ssv.cpp +++ b/src/mame/video/ssv.cpp @@ -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; - - addr = gfx->get_data(code % gfx->elements()); - color = gfx->granularity() * (color % gfx->colors()); - - 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(); \ - } + const uint8_t *const addr = gfx->get_data(code % gfx->elements()); + const uint32_t realcolor = gfx->granularity() * (color % gfx->colors()); + + const uint8_t* const source = flipy ? addr + (7 - line) * gfx->rowbytes() : addr + line * 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) -{ - 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; - - xnum = 0x20; // width in tiles (screen-wide) - ynum = 0x8; // height in tiles (always 64 pixels?) - scroll &= 0x7; // scroll register index - - /* Sign extend the position */ - sx = 0; - sy = (sy & 0x1ff) - (sy & 0x200); - - /* Set up a clipping region for the tilemap slice .. */ +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) +{ + /* 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; - clip.set(sx, sx + xnum * 0x10 - 1, sy, sy + ynum * 0x8 - 1); + int shadow = (mode & 0x0800); + /* Select 256 or 64 color tiles */ + int gfx = ((mode & 0x0100) ? 0 : 1); - /* .. and clip it against the visible screen */ + drawgfx_line(bitmap, cliprect, m_gfxdecode->gfx(gfx), realcode, color, flipx, flipy, sx, sy, shadow, realline, tileline); - if (clip.min_x > cliprect.max_x) return; - if (clip.min_y > cliprect.max_y) return; +} - if (clip.max_x < cliprect.min_x) return; - if (clip.max_y < cliprect.min_y) return; +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)]; - 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; + code = s3[0]; // code high bits + attr = s3[1]; // code low bits + color - 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; + /* Code's high bits are scrambled */ + code += m_tile_code[(attr & 0x3c00) >> 10]; + flipy = (attr & 0x4000); + flipx = (attr & 0x8000); - /* 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. + 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; + } +} - /* Background layer disabled */ - if ((mode & 0xe000) == 0) - return; +void ssv_state::draw_row_64pixhigh(bitmap_ind16 &bitmap, const rectangle &cliprect, int in_sy, int scrollreg) +{ + scrollreg &= 0x7; // scroll register index - shadow = (mode & 0x0800); + /* in_sy will always be 0x00, 0x40, 0x80, 0xc0 in 'draw layer' */ + in_sy = (in_sy & 0x1ff) - (in_sy & 0x200); - /* Decide the actual size of the tilemap */ - size = 1 << (8 + ((mode & 0xe000) >> 13)); - page = (x & 0x7fff) / size; + /* Set up a clipping region for the tilemap slice .. */ + rectangle outclip; + outclip.set(0, 0x20/*width in tiles*/ * 0x10, in_sy, in_sy + 0x8/*height in tiles, always 64 pixels*/ * 0x8); - /* Given a fixed scroll value, the portion of tilemap displayed changes with the sprite position */ - x += sx; - y += sy; + /* .. and clip it against the visible screen */ - /* Tweak the scroll values */ - // x += 0; - y += ((ssv_scroll[0x70/2] & 0x1ff) - (ssv_scroll[0x70/2] & 0x200) + ssv_scroll[0x6a/2] + 2); + if (outclip.min_x > cliprect.max_x) return; + if (outclip.min_y > cliprect.max_y) return; - // Kludge for eaglshot - if ((ssv_scroll[ scroll * 4 + 2 ] & 0x05ff) == 0x0440) x += -0x10; - if ((ssv_scroll[ scroll * 4 + 2 ] & 0x05ff) == 0x0401) x += -0x20; + if (outclip.max_x < cliprect.min_x) return; + if (outclip.max_y < cliprect.min_y) return; - /* Draw the rows */ - x1 = x; - y1 = y; - sx1 = sx - (x & 0xf); - sy1 = sy - (y & 0xf); + outclip &= cliprect; - 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) - { - int tx, ty, gfx; + rectangle clip; + clip.set(outclip.min_x, outclip.max_x, line, line); - s3 = &spriteram16[ page * (size * ((0x1000/0x200)/2)) + - ((x & ((size -1) & ~0xf)) << 2) + - ((y & ((0x200-1) & ~0xf)) >> 3) ]; + /* 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. - 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; - } + /* Background layer disabled */ + if ((mode & 0xe000) == 0) + return; - color = attr; + /* Decide the actual size of the tilemap */ + int size = 1 << (8 + ((mode & 0xe000) >> 13)); + int page = (tilemap_scrollx & 0x7fff) / size; - /* Select 256 or 64 color tiles */ - gfx = ((mode & 0x0100) ? 0 : 1); + /* Given a fixed scroll value, the portion of tilemap displayed changes with the sprite position */ + tilemap_scrolly += in_sy; - /* Force 16x16 tiles ? */ - if (flipx) { xstart = 1-1; xend = -1; xinc = -1; } - else { xstart = 0; xend = 1; xinc = +1; } + /* Tweak the scroll values */ + tilemap_scrolly += ((m_scroll[0x70 / 2] & 0x1ff) - (m_scroll[0x70 / 2] & 0x200) + m_scroll[0x6a / 2] + 2); - if (flipy) { ystart = 2-1; yend = -1; yinc = -1; } - else { ystart = 0; yend = 2; yinc = +1; } + // Kludge for eaglshot + if ((unknown & 0x05ff) == 0x0440) tilemap_scrollx += -0x10; + if ((unknown & 0x05ff) == 0x0401) tilemap_scrollx += -0x20; - /* 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 */ + int realy = tilemap_scrolly + (line - in_sy); + if ((mode & 0x1000)) + { + 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 *s1 = spriteram16; - uint16_t *end1 = spriteram16 + 0x02000/2; - uint16_t *end2 = spriteram16 + 0x40000/2; - uint16_t *s2; + uint16_t *spritelist_global = m_spriteram; + uint16_t *spritelist_global_end = m_spriteram + 0x02000 / 2; - 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 -*/ - - int shadow, gfx; - if (s2 >= end2) break; - - code = s2[0]; // code high bits - attr = s2[1]; // code low bits + color + /* + 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 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 */ |