Jump to content
IGNORED

Combining Collision Statements


KevKelley

Recommended Posts

I was curious if there is a way to do some sort of mass collision statement in the DPC+ kernel like:

 

If collision (player0,player1-9) then...

 

Or if there is an easy way to kind of combine many of the collision statements for the objects with one target. While I am sure if the answer, I was curious if anyone either knew something or had a method of their own that they use to consolidate collision statements. 

Link to comment
Share on other sites

I think in the multi sprite kernel you can do a collision(player0, player1) to see if any virtual sprite has collided with player0.  This works (maybe?) because the 5 time-shared sprites are actually player1.  Maybe you can do this in the DPC+ world to check for any collision at all then drill down (with further soft collision checking) to which virtual sprite hit.

 

I may be tired and delusional though.  So, this experiment might not turn out how I think :)

 

 

 

 

Link to comment
Share on other sites

3 hours ago, Random Terrain said:

I think "if collision(player0,player1)" can still work for all the virtual players. Seems to work here:

 

https://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#ex_dpc_collision

I thought in DPC+ each virtual sprite could now be used with its own collision statement so the multisprite kernel thing wouldn't work...

 

But if that's the case I would probably have to rework my code because I have players as the player. I am just trying to avoid checking a bunch of collision statements as in one of my programs I noticed I would get a scanline issue but it stopped if I made a boundary box instead. Or checking certain frames

 

It's not a big deal but was trying to make some small, concise code to avoid any issues. 

Link to comment
Share on other sites

4 hours ago, KevKelley said:

I thought in DPC+ each virtual sprite could now be used with its own collision statement so the multisprite kernel thing wouldn't work...

 

Try the example program to make sure. Seems that individual virtual sprite collisions and player1 for all virtual sprite collisions both work.

Link to comment
Share on other sites

1 hour ago, Random Terrain said:

 

Try the example program to make sure. Seems that individual virtual sprite collisions and player1 for all virtual sprite collisions both work.

Individual works. I was just curious if there is a way to combine them, kind of like doing sprite color and pixel data in DPC+ and saying player1-5: ...

Link to comment
Share on other sites

The hardware collision will be toggled when the player0 and player1 sprites overlap. So, when you check that, you're checking to see if player0 and player1 overlap. Sounds obvious, but it's important to make that clear.

 

We know that player1 is being repositioned during the kernel, but it is also "flickering" sprites that share a scanline. Sometimes, some virtual sprites are "off".

 

There will be frames that the Atari hardware collision detection can't "see" some virtual sprites (because some virtual sprites are "off"). So, mind the fact that checking "player0 and player1" collision won't always be a complete collision check for all virtual sprites in a given individual frame.

 

The virtual sprite ("vsprite") collision detection into bB DPC+ is pixel perfect collision that works every frame in software. The raw sprite data for shared (vertical position) scanlines are bit shifted (to adjust for their horizontal position) before a "logical AND" (to find out if two vsprites overlap). This is done with two vsprites at a time.

 

In my opinion, there's no easy or practical way for bB DPC+ on the Harmony hardware to do what you want. The entire Atari sprite "state" of each scanline isn't something bB calculates and holds in RAM. We don't have an easy way to look up multiple sprites at once, logical OR them together, and apply a logical AND. Maybe it can be done, but it would be prohibitively time consume/expensive. 

 

You need more horsepower. For instance, this kind of check would trivial using ACE C++.

 

  • Like 2
Link to comment
Share on other sites

11 hours ago, orange808 said:

The hardware collision will be toggled when the player0 and player1 sprites overlap. So, when you check that, you're checking to see if player0 and player1 overlap. Sounds obvious, but it's important to make that clear.

 

We know that player1 is being repositioned during the kernel, but it is also "flickering" sprites that share a scanline. Sometimes, some virtual sprites are "off".

 

There will be frames that the Atari hardware collision detection can't "see" some virtual sprites (because some virtual sprites are "off"). So, mind the fact that checking "player0 and player1" collision won't always be a complete collision check for all virtual sprites in a given individual frame.

 

The virtual sprite ("vsprite") collision detection into bB DPC+ is pixel perfect collision that works every frame in software. The raw sprite data for shared (vertical position) scanlines are bit shifted (to adjust for their horizontal position) before a "logical AND" (to find out if two vsprites overlap). This is done with two vsprites at a time.

 

In my opinion, there's no easy or practical way for bB DPC+ on the Harmony hardware to do what you want. The entire Atari sprite "state" of each scanline isn't something bB calculates and holds in RAM. We don't have an easy way to look up multiple sprites at once, logical OR them together, and apply a logical AND. Maybe it can be done, but it would be prohibitively time consume/expensive. 

 

You need more horsepower. For instance, this kind of check would trivial using ACE C++.

 

Thanks! Great answer. I kind of knew what to expect but was hoping for something like in the Multisprite Kernel where I could kind of do a catchall collision statement with players and players to kind of save some space. 

Link to comment
Share on other sites

I looked up the DPC+ collision detection section on R.T.s website and confirmed collision(player0, player1) can be used for a blanket collision detection between the player0 sprite and virtual sprites.  Looks like the example code uses that initial global check then drills down to which virtual sprite is on the same coordinates.

 

   ;```````````````````````````````````````````````````````````````
   ;  Checks for player0 collision with other 9 sprites.
   ; 10 is used for the y check because these sprites are 11
   ; pixels high (11 - 1 = 10). For example, if your sprite is
   ; 40 pixels tall, use 39 instead of 10.
   ;
   if !collision(player0,player1) then goto __Skip_p0_Collision
   temp5 = _Data_Sprite_Width[_Sprite_Size0]
   if (player0y + 10) >= player1y && player0y <= (player1y + 10) && (player0x + temp5) >= player1x && player0x <= (player1x + 7) then pfpixel 9 11 on
   if (player0y + 10) >= player2y && player0y <= (player2y + 10) && (player0x + temp5) >= player2x && player0x <= (player2x + 7) then pfpixel 9 20 on
   if (player0y + 10) >= player3y && player0y <= (player3y + 10) && (player0x + temp5) >= player3x && player0x <= (player3x + 7) then pfpixel 9 28 on
   if (player0y + 10) >= player4y && player0y <= (player4y + 10) && (player0x + temp5) >= player4x && player0x <= (player4x + 7) then pfpixel 9 37 on
   if (player0y + 10) >= player5y && player0y <= (player5y + 10) && (player0x + temp5) >= player5x && player0x <= (player5x + 7) then pfpixel 9 46 on
   if (player0y + 10) >= player6y && player0y <= (player6y + 10) && (player0x + temp5) >= player6x && player0x <= (player6x + 7) then pfpixel 9 55 on
   if (player0y + 10) >= player7y && player0y <= (player7y + 10) && (player0x + temp5) >= player7x && player0x <= (player7x + 7) then pfpixel 9 63 on
   if (player0y + 10) >= player8y && player0y <= (player8y + 10) && (player0x + temp5) >= player8x && player0x <= (player8x + 7) then pfpixel 9 72 on
   if (player0y + 10) >= player9y && player0y <= (player9y + 10) && (player0x + temp5) >= player9x && player0x <= (player9x + 7) then pfpixel 9 81 on

__Skip_p0_Collision

 

Link to comment
Share on other sites

Just for transparency, let's verify what we have verified.

 

else if (!strncmp(statement, "collision(player0,player1)\0", 26))
    {
	printf("	CXPPMM");
	bit = 7;
    }

 

Batari Basic will translate the collision keyword into assembler using the code I quoted. It is a call to CXPPMM.

 

Quote

CXPPMM (R) - Collision Latch P0-P1, M0-M1 (Bit 7,6) (Read only)

The TIA detects collisions between any of the 6 objects (the playfield and 5 moveable objects). There are 15 possible two-object collisions which are stored in 15 one bit latches.

Source:  

https://problemkaputt.de/2k6specs.htm  

 

So, if one of the virtual sprites is not "on" during a given frame, it will NOT detect it, because the Atari can only see a collision between P0 and P1. If you have declared a sprite and it isn't "on screen", the Atari hardware can't see a collision. The Atari only knows if it "draws" overlapping P0 and P1 sprites. As far as the Atari is concerned, if it isn't "drawn", it doesn't exist at all. So, mind that limitation.

 

The virtual sprite collision is handled on the ARM side by this code snippet:

case 20: // collision check
    {
      // takes virtual sprite, returns coll
      // syntax: sprite[1], sprite[2] (missiles, ball not yet, pf done another way)
      // draw sprites in virtual area
      C_function[3]=0;
      temp2=0;
      for (i=RIOT[player0y+C_function2];i<RIOT[player0y+C_function2]+RIOT[player0height+C_function2];++i) 
      {
        if ((i>=RIOT[player0y+C_function1]) && (i<RIOT[player0y+C_function1]+RIOT[player0height+C_function1]))
	{
          temp3=RIOT[player0x+C_function2]-RIOT[player0x+C_function1]+7; //-7 to +7 -> 0 to 14
          if (temp3<15)
	  {
            temp2=((flashdata[(RIOT[player0pointerhi+C_function2*2]<<8)+RIOT[player0pointerlo+C_function2*2]+i-RIOT[player0y+C_function2]])<<7)
                & ((flashdata[(RIOT[player0pointerhi+C_function1*2]<<8)+RIOT[player0pointerlo+C_function1*2]+i-RIOT[player0y+C_function1]])<<temp3);
	  }
	  if (temp2) 
	  {
	    C_function[3]=255;
	    return;
	  }
	}
      }
      return;
    

As you can see, the collisions are handled one at a time.

 

  • Thanks 1
Link to comment
Share on other sites

Quote

As you can see, the collisions are handled one at a time.

 

Do you think there's a good way to manage soft collisions so that every possible collision is checked and registered?

 

In the past I've checked for collisions and stored the results as boolean values.  I check each virtual sprite on its own frame.  This might lead to sloppy detection as if you have 8 virtual sprites they only get checked every 8 frames.

Link to comment
Share on other sites

16 hours ago, Gemintronic said:

 

Do you think there's a good way to manage soft collisions so that every possible collision is checked and registered?

 

In the past I've checked for collisions and stored the results as boolean values.  I check each virtual sprite on its own frame.  This might lead to sloppy detection as if you have 8 virtual sprites they only get checked every 8 frames.

I may be wrong, but iirc for regular collision checks, each time you do a drawscreen, you can do another check. If that's accurate, then if you were to do more drawscreens and collision checks between changes in position, you would miss fewer collisions.

 

If you're using boundary checks manually, then you similarly would check after each movement or set of movements. If you check after each individual sprite movement, you may catch more collisions than you would if you were to do them as a set, and you would catch still more collisions if you were to move them back and change the order of movements and checks. If you decrease the amount of movement between collision checks, you may catch even more collisions.

Edited by Fort Apocalypse
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...