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)
This commit is contained in:
Aaron Giles 2008-04-02 08:40:34 +00:00
parent cce0f9f8e7
commit dc5af38f5b
2 changed files with 144 additions and 40 deletions

View File

@ -10,7 +10,6 @@
* Rougien
Known issues:
* Hardware collision detection is not implemented.
* Are the stars really supposed to go up in Rougien?

View File

@ -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);
}
}