From dc5af38f5bf7d2c5f4076862ea010b77d4f462c9 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Wed, 2 Apr 2008 08:40:34 +0000 Subject: [PATCH] From: roberto zandona [mailto:robiza71@tin.it] Subject: patch for mermaid proper implentation of hardware collision (first implentation was incomplete) this fix mermaid (when the player is in the water with the sharks) and rougien (Mantis 01652) --- src/mame/drivers/mermaid.c | 1 - src/mame/video/mermaid.c | 183 +++++++++++++++++++++++++++++-------- 2 files changed, 144 insertions(+), 40 deletions(-) diff --git a/src/mame/drivers/mermaid.c b/src/mame/drivers/mermaid.c index 726d1a51f8c..2dbf33e544f 100644 --- a/src/mame/drivers/mermaid.c +++ b/src/mame/drivers/mermaid.c @@ -10,7 +10,6 @@ * Rougien Known issues: - * Hardware collision detection is not implemented. * Are the stars really supposed to go up in Rougien? diff --git a/src/mame/video/mermaid.c b/src/mame/video/mermaid.c index 8eeecf4414f..fcf546d7293 100644 --- a/src/mame/video/mermaid.c +++ b/src/mame/video/mermaid.c @@ -8,7 +8,7 @@ UINT8* mermaid_fg_scrollram; static bitmap_t* helper; static bitmap_t* helper2; -static int collision_sprite_background,collision_sprite_foreground,collision_sprite_sprite_boat,collision_sprite_sprite_wind; +static int coll_bit0,coll_bit1,coll_bit2,coll_bit3,coll_bit6; static int rougien_gfxbank1, rougien_gfxbank2; @@ -107,24 +107,27 @@ WRITE8_HANDLER( rougien_gfxbankswitch2_w ) READ8_HANDLER( mermaid_collision_r ) { /* - collision register active LO - Bit 0 - Bit 1 - Sprite - Foreground - Bit 2 - Sprite - Stream - Bit 3 - Sprite (Wind) - Sprite + collision register active LOW: + + with coll = spriteram[offs + 2] & 0xc0 + + Bit 0 - Sprite (coll = 0x40) - Sprite (coll = 0x00) + Bit 1 - Sprite (coll = 0x40) - Foreground + Bit 2 - Sprite (coll = 0x40) - Background + Bit 3 - Sprite (coll = 0x80) - Sprite (coll = 0x00) Bit 4 Bit 5 - Bit 6 - Sprite (Boat) - Sprite + Bit 6 - Sprite (coll = 0x40) - Sprite (coll = 0x80) Bit 7 - */ + */ int collision = 0xff; - if(collision_sprite_foreground) collision &= 0xfd; - if(collision_sprite_background) collision &= 0xfb; - - if(collision_sprite_sprite_wind) collision &= 0xf7; - if(collision_sprite_sprite_boat) collision &= 0xbf; + if(coll_bit0) collision &= 0xfe; + if(coll_bit1) collision &= 0xfd; + if(coll_bit2) collision &= 0xfb; + if(coll_bit3) collision &= 0xf7; + if(coll_bit6) collision &= 0xbf; return collision; } @@ -220,8 +223,9 @@ static UINT8 collision_check(colortable_t *colortable, rectangle* rect) { UINT16 a = colortable_entry_get_value(colortable, *BITMAP_ADDR16(helper, y, x)); UINT16 b = colortable_entry_get_value(colortable, *BITMAP_ADDR16(helper2, y, x)); + if (b != 0) - if (a != 0) + if ((a != 0) & (a != 0x40)) data |= 0x01; } @@ -234,18 +238,20 @@ VIDEO_EOF( mermaid ) int offs,offs2; - collision_sprite_foreground = 0; - collision_sprite_sprite_boat = 0; - collision_sprite_sprite_wind = 0; + coll_bit1 = 0; + coll_bit2 = 0; + coll_bit3 = 0; + coll_bit6 = 0; + coll_bit0 = 0; - // check for "boat" sprite + // check for bit 0 (sprite-sprite), 1 (sprite-foreground), 2 (sprite-background) - for (offs = spriteram_size - 4; offs >= spriteram_size - (4*2); offs -= 4) + for (offs = spriteram_size - 4; offs >= 0; offs -= 4) { int attr = spriteram[offs + 2]; int bank = (attr & 0x30) >> 4; + int coll = (attr & 0xc0) >> 6; int code = (spriteram[offs] & 0x3f) | (bank << 6); -// int color = attr & 0x0f; int flipx = spriteram[offs] & 0x40; int flipy = spriteram[offs] & 0x80; int sx = spriteram[offs + 3] + 1; @@ -253,6 +259,8 @@ VIDEO_EOF( mermaid ) rectangle rect; + if (coll != 1) continue; + code |= rougien_gfxbank1 * 0x2800; code |= rougien_gfxbank2 * 0x2400; @@ -282,7 +290,7 @@ VIDEO_EOF( mermaid ) if (rect.max_y > visarea->max_y) rect.max_y = visarea->max_y; - // check collision sprite-background (stream) + // check collision sprite - background fillbitmap(helper,0,&rect); fillbitmap(helper2,0,&rect); @@ -292,9 +300,9 @@ VIDEO_EOF( mermaid ) drawgfx(helper2, machine->gfx[1], code, 0, flipx, flipy, sx, sy, &rect,TRANSPARENCY_PEN, 0); - collision_sprite_background |= collision_check(machine->colortable, &rect); + coll_bit2 |= collision_check(machine->colortable, &rect); - // check collision sprite-foreground + // check collision sprite - foreground fillbitmap(helper,0,&rect); fillbitmap(helper2,0,&rect); @@ -304,25 +312,27 @@ VIDEO_EOF( mermaid ) drawgfx(helper2, machine->gfx[1], code, 0, flipx, flipy, sx, sy, &rect,TRANSPARENCY_PEN, 0); - collision_sprite_foreground |= collision_check(machine->colortable, &rect); + coll_bit1 |= collision_check(machine->colortable, &rect); - // check collision sprite "boat" - sprite + // check collision sprite - sprite fillbitmap(helper,0,&rect); fillbitmap(helper2,0,&rect); - for (offs2 = spriteram_size - (4*6) - 4; offs2 >= 0; offs2 -= 4) + for (offs2 = spriteram_size - 4; offs2 >= 0; offs2 -= 4) if (offs != offs2) { int attr2 = spriteram[offs2 + 2]; int bank2 = (attr2 & 0x30) >> 4; + int coll2 = (attr2 & 0xc0) >> 6; int code2 = (spriteram[offs2] & 0x3f) | (bank2 << 6); -// int color2 = attr2 & 0x0f; int flipx2 = spriteram[offs2] & 0x40; int flipy2 = spriteram[offs2] & 0x80; int sx2 = spriteram[offs2 + 3] + 1; int sy2 = 240 - spriteram[offs2 + 1]; + if (coll2 != 0) continue; + code2 |= rougien_gfxbank1 * 0x2800; code2 |= rougien_gfxbank2 * 0x2400; @@ -342,20 +352,20 @@ VIDEO_EOF( mermaid ) &rect,TRANSPARENCY_PEN, 0); } - drawgfx(helper2, machine->gfx[1], code, 0, flipx, flipy, sx, sy, + drawgfx(helper2, machine->gfx[1], code, 0, flipx, flipy, sx, sy, &rect,TRANSPARENCY_PEN, 0); - collision_sprite_sprite_boat |= collision_check(machine->colortable, &rect); - } + coll_bit0 |= collision_check(machine->colortable, &rect); + } - // check for "sail" sprite + // check for bit 3 (sprite-sprite) - for (offs = spriteram_size - 4*3; offs >= spriteram_size - (4*4); offs -= 4) + for (offs = spriteram_size - 4; offs >= 0; offs -= 4) { int attr = spriteram[offs + 2]; int bank = (attr & 0x30) >> 4; + int coll = (attr & 0xc0) >> 6; int code = (spriteram[offs] & 0x3f) | (bank << 6); -// int color = attr & 0x0f; int flipx = spriteram[offs] & 0x40; int flipy = spriteram[offs] & 0x80; int sx = spriteram[offs + 3] + 1; @@ -363,6 +373,8 @@ VIDEO_EOF( mermaid ) rectangle rect; + if (coll != 2) continue; + code |= rougien_gfxbank1 * 0x2800; code |= rougien_gfxbank2 * 0x2400; @@ -392,23 +404,25 @@ VIDEO_EOF( mermaid ) if (rect.max_y > visarea->max_y) rect.max_y = visarea->max_y; - // check collision sprite "sail" - sprite + // check collision sprite - sprite fillbitmap(helper,0,&rect); fillbitmap(helper2,0,&rect); - for (offs2 = spriteram_size - (4*6) - 4; offs2 >= 0; offs2 -= 4) + for (offs2 = spriteram_size - 4; offs2 >= 0; offs2 -= 4) if (offs != offs2) { int attr2 = spriteram[offs2 + 2]; int bank2 = (attr2 & 0x30) >> 4; + int coll2 = (attr2 & 0xc0) >> 6; int code2 = (spriteram[offs2] & 0x3f) | (bank2 << 6); -// int color2 = attr2 & 0x0f; int flipx2 = spriteram[offs2] & 0x40; int flipy2 = spriteram[offs2] & 0x80; int sx2 = spriteram[offs2 + 3] + 1; int sy2 = 240 - spriteram[offs2 + 1]; + if (coll2 != 0) continue; + code2 |= rougien_gfxbank1 * 0x2800; code2 |= rougien_gfxbank2 * 0x2400; @@ -424,13 +438,104 @@ VIDEO_EOF( mermaid ) sy2 = 240 - sy2; } - drawgfx(helper, machine->gfx[1], code2, 1, flipx2, flipy2, sx2, sy2, + drawgfx(helper, machine->gfx[1], code2, 0, flipx2, flipy2, sx2, sy2, &rect,TRANSPARENCY_PEN, 0); } - drawgfx(helper2, machine->gfx[1], code, 0, flipx, flipy, sx, sy, + drawgfx(helper2, machine->gfx[1], code, 0, flipx, flipy, sx, sy, &rect,TRANSPARENCY_PEN, 0); - collision_sprite_sprite_wind |= collision_check(machine->colortable, &rect); + coll_bit3 |= collision_check(machine->colortable, &rect); + } + + // check for bit 6 + + for (offs = spriteram_size - 4; offs >= 0; offs -= 4) + { + int attr = spriteram[offs + 2]; + int bank = (attr & 0x30) >> 4; + int coll = (attr & 0xc0) >> 6; + int code = (spriteram[offs] & 0x3f) | (bank << 6); + int flipx = spriteram[offs] & 0x40; + int flipy = spriteram[offs] & 0x80; + int sx = spriteram[offs + 3] + 1; + int sy = 240 - spriteram[offs + 1]; + + rectangle rect; + + if (coll != 1) continue; + + code |= rougien_gfxbank1 * 0x2800; + code |= rougien_gfxbank2 * 0x2400; + + if (flip_screen_x_get()) + { + flipx = !flipx; + sx = 240 - sx; } + + if (flip_screen_y_get()) + { + flipy = !flipy; + sy = 240 - sy; + } + + rect.min_x = sx; + rect.min_y = sy; + rect.max_x = sx + machine->gfx[1]->width - 1; + rect.max_y = sy + machine->gfx[1]->height - 1; + + if (rect.min_x < visarea->min_x) + rect.min_x = visarea->min_x; + if (rect.min_y < visarea->min_y) + rect.min_y = visarea->min_y; + if (rect.max_x > visarea->max_x) + rect.max_x = visarea->max_x; + if (rect.max_y > visarea->max_y) + rect.max_y = visarea->max_y; + + // check collision sprite - sprite + + fillbitmap(helper,0,&rect); + fillbitmap(helper2,0,&rect); + + for (offs2 = spriteram_size - 4; offs2 >= 0; offs2 -= 4) + if (offs != offs2) + { + int attr2 = spriteram[offs2 + 2]; + int bank2 = (attr2 & 0x30) >> 4; + int coll2 = (attr2 & 0xc0) >> 6; + int code2 = (spriteram[offs2] & 0x3f) | (bank2 << 6); + int flipx2 = spriteram[offs2] & 0x40; + int flipy2 = spriteram[offs2] & 0x80; + int sx2 = spriteram[offs2 + 3] + 1; + int sy2 = 240 - spriteram[offs2 + 1]; + + if (coll2 != 2) continue; + + code2 |= rougien_gfxbank1 * 0x2800; + code2 |= rougien_gfxbank2 * 0x2400; + + if (flip_screen_x_get()) + { + flipx2 = !flipx2; + sx2 = 240 - sx2; + } + + if (flip_screen_y_get()) + { + flipy2 = !flipy2; + sy2 = 240 - sy2; + } + + drawgfx(helper, machine->gfx[1], code2, 0, flipx2, flipy2, sx2, sy2, + &rect,TRANSPARENCY_PEN, 0); + } + + drawgfx(helper2, machine->gfx[1], code, 0, flipx, flipy, sx, sy, + &rect,TRANSPARENCY_PEN, 0); + + coll_bit6 |= collision_check(machine->colortable, &rect); + } + }