diff options
-rw-r--r-- | src/mame/drivers/sigmab98.c | 242 |
1 files changed, 176 insertions, 66 deletions
diff --git a/src/mame/drivers/sigmab98.c b/src/mame/drivers/sigmab98.c index c3f55b869b8..1b581b6ce10 100644 --- a/src/mame/drivers/sigmab98.c +++ b/src/mame/drivers/sigmab98.c @@ -87,13 +87,13 @@ http://www.tsc-acnet.com/index.php?sort=8&action=cataloglist&s=1&mode=3&genre_id To Do: - KL5C80 emulation is needed to consolidate the sammymdl games in one memory map and to run the BIOS -- Sprites rotation, e.g. logo in dashhero, pepsiman https://youtu.be/p3cbZ67m4lo?t=1m24s, tdoboon https://youtu.be/loPP3jt0Ob0 - Remove ROM patches: gegege checks the EEPROM output after reset, and wants a timed 0->1 transition or locks up while saving setting in service mode. Using a reset_delay of 7 works, unless when "play style" is set to "coin" (it probably changes the number of reads from port $C0). I guess the reset_delay mechanism should be implemented with a timer in eeprom.c. - pyenaget intro: when the theater scrolls out to the left, the train should scroll in from the right, with no visible gaps. It currently leaves the screen empty instead, for several seconds. +- tdoboon: no smoke from hit planes as shown in the video? Tiles are present (f60-125f) and used in demo mode. - dashhero does not acknowledge the button bashing correctly, it's very hard to win (a slower pace works better!) Notes: @@ -140,6 +140,8 @@ public: required_device<screen_device> m_screen; required_device<palette_device> m_palette; + bitmap_ind16 *m_sprite_bitmap; + UINT8 m_reg; UINT8 m_rombank; UINT8 m_reg2; @@ -237,6 +239,7 @@ public: DECLARE_MACHINE_RESET(sigmab98); DECLARE_MACHINE_RESET(sammymdl); + virtual void video_start(); UINT32 screen_update_sigmab98(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void screen_eof_sammymdl(screen_device &screen, bool state); INTERRUPT_GEN_MEMBER(sigmab98_vblank_interrupt); @@ -251,6 +254,11 @@ public: ***************************************************************************/ +void sigmab98_state::video_start() +{ + m_sprite_bitmap = auto_bitmap_ind16_alloc(machine(), 512, 512); +} + /*************************************************************************** Sprites @@ -274,19 +282,28 @@ public: 6 7654 3--- Number of Y Tiles - 1 ---- -210 Y (High) 7 Y (Low) - 8 Shrink Factor (<< 8, High) - 9 Shrink Factor (<< 8, Low) - a ? rotation, see dashhero (Sigma logo) - b ? and pepsiman (when falling) + 8 Destination Delta X, Scaled by Shrink Factor << 8 (High) + 9 Destination Delta X, Scaled by Shrink Factor << 8 (Low) + a Destination Delta Y, Scaled by Shrink Factor << 8 (High) + b Destination Delta Y, Scaled by Shrink Factor << 8 (Low) c 7654 3--- - ---- -210 Delta X (High) - d Delta X (Low) + ---- -210 Source X (High) + d Source X (Low) e 7654 3--- - ---- -210 Delta Y (High) - f Delta Y (Low) + ---- -210 Source Y (High) + f Source Y (Low) + + Sprites rotation examples: + logo in dashhero, pepsiman https://youtu.be/p3cbZ67m4lo?t=1m24s, tdoboon https://youtu.be/loPP3jt0Ob0 ***************************************************************************/ +inline int integer_part(int x) +{ +// return x >> 16; + return (x + 0x8000) >> 16; +} + void sigmab98_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int pri_mask) { UINT8 *end = (m_buffered_spriteram ? m_buffered_spriteram->buffer() : m_spriteram) - 0x10; @@ -294,77 +311,170 @@ void sigmab98_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprec for ( ; s != end; s -= 0x10 ) { - int gfx, code, color, zoom, /*rot,*/ dim, scale; - int sx, nx, x, x0, x1, dx, flipx; - int sy, ny, y, y0, y1, dy, flipy; - if ( (s[ 0x01 ] & 0x04) == 0) continue; if ( ((1 << (s[ 0x01 ] & 0x03)) & pri_mask) == 0 ) continue; - color = s[ 0x00 ] & 0xf; + int color = s[ 0x00 ] & 0xf; - gfx = (s[ 0x01 ] & 0x40 ) ? 1 : 0; + int gfx = (s[ 0x01 ] & 0x40 ) ? 1 : 0; + int code = s[ 0x02 ] * 256 + s[ 0x03 ]; - code = s[ 0x02 ] * 256 + s[ 0x03 ]; + int nx = ((s[ 0x04 ] & 0xf8) >> 3) + 1; + int dstx = (s[ 0x04 ] & 0x03) * 256 + s[ 0x05 ]; - nx = ((s[ 0x04 ] & 0xf8) >> 3) + 1; + int ny = ((s[ 0x06 ] & 0xf8) >> 3) + 1; + int dsty = (s[ 0x06 ] & 0x03) * 256 + s[ 0x07 ]; - sx = (s[ 0x04 ] & 0x03) * 256 + s[ 0x05 ]; + int dstdx = (s[ 0x08 ] & 0xff) * 256 + s[ 0x09 ]; // 0x100 = no zoom, 0x200 = 50% zoom + int dstdy = (s[ 0x0a ] & 0xff) * 256 + s[ 0x0b ]; // "" - ny = ((s[ 0x06 ] & 0xf8) >> 3) + 1; + int srcx = (s[ 0x0c ] & 0xff) * 256 + s[ 0x0d ]; + int srcy = (s[ 0x0e ] & 0xff) * 256 + s[ 0x0f ]; + + // Sign extend the position + dstx = (dstx & 0x01ff) - (dstx & 0x0200); // or 0x3ff/0x400? + dsty = (dsty & 0x01ff) - (dsty & 0x0200); - sy = (s[ 0x06 ] & 0x03) * 256 + s[ 0x07 ]; + // Flipping + int x0, x1, dx, flipx = s[ 0x01 ] & 0x10; + int y0, y1, dy, flipy = s[ 0x01 ] & 0x08; - zoom = (s[ 0x08 ] & 0xff) * 256 + s[ 0x09 ]; // 0x100 means no zoom + if ( flipx ) { x0 = nx - 1; x1 = -1; dx = -1; } + else { x0 = 0; x1 = nx; dx = +1; } -// rot = (s[ 0x0a ] & 0xff) * 256 + s[ 0x0b ]; // unimplemented! + if ( flipy ) { y0 = ny - 1; y1 = -1; dy = -1; } + else { y0 = 0; y1 = ny; dy = +1; } - dx = (s[ 0x0c ] & 0xff) * 256 + s[ 0x0d ]; - dy = (s[ 0x0e ] & 0xff) * 256 + s[ 0x0f ]; + // Draw the sprite directly to screen if no zoom/rotation/offset is required + if (dstdx == 0x100 && !dstdy && !srcx && !srcy) + { + for (int y = y0; y != y1; y += dy) + { + for (int x = x0; x != x1; x += dx) + { + m_gfxdecode->gfx(gfx)->transpen(bitmap, cliprect, + code++, color, + flipx, flipy, + dstx + x * 16, dsty + y * 16, 0); + } + } - // Sign extend the position - sx = (sx & 0x1ff) - (sx & 0x200); - sy = (sy & 0x1ff) - (sy & 0x200); - dx = (dx & 0x7fff) - (dx & 0x8000); - dy = (dy & 0x7fff) - (dy & 0x8000); + continue; + } + + // First draw the sprite in a buffer without zoom/rotation/offset, nor transparency + rectangle sprite_cliprect(0, nx * 16 - 1, 0, ny * 16 - 1); + for (int y = y0; y != y1; y += dy) + { + for (int x = x0; x != x1; x += dx) + { + m_gfxdecode->gfx(gfx)->opaque(*m_sprite_bitmap, sprite_cliprect, + code++, color, + flipx, flipy, + x * 16, y * 16); + } + } + + // Sign extend the transformation values + dstdx = (dstdx & 0x7fff) - (dstdx & 0x8000); + dstdy = (dstdy & 0x7fff) - (dstdy & 0x8000); + srcx = (srcx & 0x7fff) - (srcx & 0x8000); + srcy = (srcy & 0x7fff) - (srcy & 0x8000); + dstdy = -dstdy; // Use fixed point values (16.16), for accuracy - sx <<= 16; - sy <<= 16; + dstx <<= 16; + dsty <<= 16; - zoom = (1 << 16) / (zoom ? zoom : 1); - dim = (0x10 << 8) * zoom; - // Add shift (negated) - sx -= (dx << 8) * zoom; - sy -= (dy << 8) * zoom; - scale = dim / 0x10; + // Source delta (equal for x and y) + int z = int( sqrt(dstdx * dstdx + dstdy * dstdy) + 0.5 ); // dest delta vector is scaled by the source delta!? + if (!z) + z = 0x100; + int srcdzz = z << 8; - // Let's approximate to the nearest greater integer value - // to avoid holes in between tiles - if (scale & 0xffff) scale += (1<<16) / 0x10; + // Destination x and y deltas + int dstdxx = (dstdx << 16) / z; // dest x delta for source x increments + int dstdyx = (dstdy << 16) / z; // dest y delta for source x increments - flipx = s[ 0x01 ] & 0x10; - flipy = s[ 0x01 ] & 0x08; + int dstdxy = -dstdyx; // dest x delta for source y increments (orthogonal to the above vector) + int dstdyy = dstdxx; // dest y delta for source y increments - if ( flipx ) { x0 = nx - 1; x1 = -1; dx = -1; } - else { x0 = 0; x1 = nx; dx = +1; } + // Transform the source offset in a destination offset (negate, scale and rotate it) + srcx = (-srcx << 8) / z; + srcy = (-srcy << 8) / z; - if ( flipy ) { y0 = ny - 1; y1 = -1; dy = -1; } - else { y0 = 0; y1 = ny; dy = +1; } + dstx += srcx * dstdxx; + dsty += srcx * dstdyx; - for (y = y0; y != y1; y += dy) + dstx += srcy * dstdxy; + dsty += srcy * dstdyy; + + // Supersampling (2x2) to avoid gaps in the destination + srcdzz /= 2; + dstdxx /= 2; + dstdyx /= 2; + dstdxy /= 2; + dstdyy /= 2; + + // Transform the source image while drawing to the screen + UINT16 *src = &m_sprite_bitmap->pix16(0); + UINT16 *dst = &bitmap.pix16(0); + + int src_rowpixels = m_sprite_bitmap->rowpixels(); + int dst_rowpixels = bitmap.rowpixels(); + + UINT16 penmask = gfx ? 0xff : 0x0f; + + // Scan source image top to bottom + srcy = 0; + for (;;) { - for (x = x0; x != x1; x += dx) + int dstx_prev = dstx; + int dsty_prev = dsty; + + int fy = integer_part(srcy); + if (fy > sprite_cliprect.max_y) + break; + if (fy >= sprite_cliprect.min_y) { - m_gfxdecode->gfx(gfx)->zoom_transpen(bitmap,cliprect, - code++, color, - flipx, flipy, - (sx + x * dim) / 0x10000, (sy + y * dim) / 0x10000, - scale, scale, 0 ); + // left to right + srcx = 0; + for (;;) + { + int fx = integer_part(srcx); + if (fx > sprite_cliprect.max_x) + break; + if (fx >= sprite_cliprect.min_x) + { + int px = integer_part(dstx); + int py = integer_part(dsty); + + if (px >= cliprect.min_x && px <= cliprect.max_x && py >= cliprect.min_y && py <= cliprect.max_y) + { + UINT16 pen = src[fy * src_rowpixels + fx]; + if (pen & penmask) + dst[py * dst_rowpixels + px] = pen; + } + } + + // increment source x and dest x,y + srcx += srcdzz; + + dstx += dstdxx; + dsty += dstdyx; + } } + + // increment source y and dest x,y + srcy += srcdzz; + + dstx = dstx_prev; + dsty = dsty_prev; + dstx += dstdxy; + dsty += dstdyy; } } } @@ -2807,18 +2917,18 @@ DRIVER_INIT_MEMBER(sigmab98_state,haekaka) ***************************************************************************/ -GAME( 1997, dodghero, 0, dodghero, sigma_1b, sigmab98_state, dodghero, ROT0, "Sigma", "Minna Atsumare! Dodge Hero", GAME_IMPERFECT_GRAPHICS ) -GAME( 1997, sushimar, 0, dodghero, sigma_3b, sigmab98_state, dodghero, ROT0, "Sigma", "Itazura Daisuki! Sushimaru Kun", GAME_IMPERFECT_GRAPHICS ) -GAME( 1997, gegege, 0, gegege, sigma_1b, sigmab98_state, gegege, ROT0, "Sigma / Banpresto", "GeGeGe no Kitarou Youkai Slot", GAME_IMPERFECT_GRAPHICS ) -GAME( 1997, b3rinsya, 0, gegege, sigma_5b, sigmab98_state, b3rinsya, ROT0, "Sigma", "Burning Sanrinsya - Burning Tricycle", GAME_IMPERFECT_GRAPHICS ) // 1997 in the rom -GAME( 1997, pepsiman, 0, gegege, sigma_3b, sigmab98_state, pepsiman, ROT0, "Sigma", "PEPSI Man", GAME_IMPERFECT_GRAPHICS ) -GAME( 1998, tbeastw2, 0, gegege, sigma_3b, sigmab98_state, tbeastw2, ROT0, "Sigma / Transformer Production Company / Takara", "Transformers Beast Wars II", GAME_IMPERFECT_GRAPHICS ) // 1997 in the rom -GAME( 1997, ucytokyu, 0, gegege, sigma_js, sigmab98_state, ucytokyu, ROT0, "Sigma", "Uchuu Tokkyuu Medalian", GAME_IMPERFECT_GRAPHICS ) // Banpresto + others in the ROM -GAME( 2000, dashhero, 0, dashhero, sigma_1b, sigmab98_state, dashhero, ROT0, "Sigma", "Minna Ganbare! Dash Hero", GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) // 1999 in the rom +GAME( 1997, dodghero, 0, dodghero, sigma_1b, sigmab98_state, dodghero, ROT0, "Sigma", "Minna Atsumare! Dodge Hero", 0 ) +GAME( 1997, sushimar, 0, dodghero, sigma_3b, sigmab98_state, dodghero, ROT0, "Sigma", "Itazura Daisuki! Sushimaru Kun", 0 ) +GAME( 1997, gegege, 0, gegege, sigma_1b, sigmab98_state, gegege, ROT0, "Sigma / Banpresto", "GeGeGe no Kitarou Youkai Slot", 0 ) +GAME( 1997, b3rinsya, 0, gegege, sigma_5b, sigmab98_state, b3rinsya, ROT0, "Sigma", "Burning Sanrinsya - Burning Tricycle", 0 ) // 1997 in the rom +GAME( 1997, pepsiman, 0, gegege, sigma_3b, sigmab98_state, pepsiman, ROT0, "Sigma", "PEPSI Man", 0 ) +GAME( 1998, tbeastw2, 0, gegege, sigma_3b, sigmab98_state, tbeastw2, ROT0, "Sigma / Transformer Production Company / Takara", "Transformers Beast Wars II", 0 ) // 1997 in the rom +GAME( 1997, ucytokyu, 0, gegege, sigma_js, sigmab98_state, ucytokyu, ROT0, "Sigma", "Uchuu Tokkyuu Medalian", 0 ) // Banpresto + others in the ROM +GAME( 2000, dashhero, 0, dashhero, sigma_1b, sigmab98_state, dashhero, ROT0, "Sigma", "Minna Ganbare! Dash Hero", GAME_NOT_WORKING ) // 1999 in the rom // Sammy Medal Games: GAME( 2000, sammymdl, 0, sammymdl, sammymdl, sigmab98_state, animalc, ROT0, "Sammy", "Sammy Medal Game System Bios", GAME_IS_BIOS_ROOT ) -GAME( 2000, animalc, sammymdl, animalc, sammymdl, sigmab98_state, animalc, ROT0, "Sammy", "Animal Catch", GAME_IMPERFECT_GRAPHICS ) -GAME( 2000, itazuram, sammymdl, itazuram, sammymdl, sigmab98_state, itazuram, ROT0, "Sammy", "Itazura Monkey", GAME_IMPERFECT_GRAPHICS ) -GAME( 2000, pyenaget, sammymdl, pyenaget, sammymdl, sigmab98_state, haekaka, ROT0, "Sammy", "Pye-nage Taikai", GAME_IMPERFECT_GRAPHICS ) -GAME( 2000, tdoboon, sammymdl, tdoboon, haekaka, sigmab98_state, haekaka, ROT0, "Sammy", "Taihou de Doboon", GAME_IMPERFECT_GRAPHICS ) -GAME( 2001, haekaka, sammymdl, haekaka, haekaka, sigmab98_state, haekaka, ROT0, "Sammy", "Hae Hae Ka Ka Ka", GAME_IMPERFECT_GRAPHICS ) +GAME( 2000, animalc, sammymdl, animalc, sammymdl, sigmab98_state, animalc, ROT0, "Sammy", "Animal Catch", 0 ) +GAME( 2000, itazuram, sammymdl, itazuram, sammymdl, sigmab98_state, itazuram, ROT0, "Sammy", "Itazura Monkey", 0 ) +GAME( 2000, pyenaget, sammymdl, pyenaget, sammymdl, sigmab98_state, haekaka, ROT0, "Sammy", "Pye-nage Taikai", 0 ) +GAME( 2000, tdoboon, sammymdl, tdoboon, haekaka, sigmab98_state, haekaka, ROT0, "Sammy", "Taihou de Doboon", 0 ) +GAME( 2001, haekaka, sammymdl, haekaka, haekaka, sigmab98_state, haekaka, ROT0, "Sammy", "Hae Hae Ka Ka Ka", 0 ) |