Bones-69 Posted January 11, 2019 Share Posted January 11, 2019 From the XB Handbook in regards to the CALL COINC command; Format CALL COINC( #sprite-number, #sprite-number, tolerance, numeric-variable ) CALL COINC( #sprite-number, dot-row, dot-column, tolerance, numeric-variable ) CALL COINC( ALL, numeric-variable ) If the keyword ALL is given, sprites are coincident only if one or more of the dots which make them up occupy the same position on the screen. If two sprites or a sprite and a location are given, then tolerance must be specified, and two sprites are coincident if their upper left hand corners are within the value specified by tolerance. A sprite and a location are coincident if the upper left hand corner of the sprite and the position specified by dot-row and dot-column are within the value specified by tolerance. These coincidents are reported even if there is no apparent overlap of the sprites or the sprite and the position. I created the following little program to get a better visual. Use the arrow keys to move the blue sprite onto/around the red sprite. Note when the two sprites are properly aligned that there is no coincidence under the ALL keyword (due to there being no actual dot overlap). BTW- The white background is not a sprite - only two sprites are used. 100 CALL CLEAR :: CALL SCREEN(2)::FOR I=1 TO 12::CALL COLOR(I,15,2)::NEXT I::CALL MAGNIFY(3)::CALL HCHAR(18,15,125,2)::CALL HCHAR(19,15,125,2) 110 CALL CHAR(124,"E0E0E0E0FFFFFFFFFFFFFFFFFFFFFFFF07070707878787878787CFCFCFFFFFFF",128,"1F1F1F1F000000000000000000000000F8F8F8F8787878787878303030000000") 120 Y=118 :: X=113 :: CALL SPRITE(#2,124,7,137,113,#1,128,5,Y,X)::A$="CALL COINC(#1,#2,"::B$(0)="YES"::B$(1)="NO" 130 CALL KEY(0,A,B)::IF A<8 OR A>11 THEN 130 140 ON A-7 GOTO 150,160,170,180 150 X=X-1::GOTO 190 160 X=X+1::GOTO 190 170 Y=Y+1::GOTO 190 180 Y=Y-1 190 CALL LOCATE(#1,Y,X) 200 FOR I=0 TO 12::CALL COINC(#1,#2,I,A)::DISPLAY AT(I+1,1):A$&STR$(I)&","&B$(A+1)&")"::NEXT I 210 CALL COINC(ALL,A)::DISPLAY AT(I+1,1):A$&"ALL,"&B$(A+1)&")" 220 GOTO 130 It would be a wonderful thing to be able to specify particular sprites (say #1 & #5) and have the function behave as it currently does when the keyword ALL is specified. ie- Be able to check a true coincidence between sprites *only* when two dots occupy the same screen position, rather than the scatter-gun approach of using the upper left hand corner plus a specified tolerance. Does anyone have any ideas on how this might be achieved in XB? I imagine the processing might be too much for a regular XB program, but I doubt it would overwhelm an XB compiled program. I am basically trying to work out a method to detect a dot-to-dot coincidence without being forced to use the ALL Keyword (the use of multicoloured sprites make the ALL command mostly impractical). Any ideas? Full XB Reference; COINC subprogram Format CALL COINC( #sprite-number, #sprite-number, tolerance, numeric-variable ) CALL COINC( #sprite-number, dot-row, dot-column, tolerance, numeric-variable ) CALL COINC( ALL, numeric-variable ) Description The COINC subprogram detects a coincidence between a sprite and another sprite or a position on the screen. The value returned in numeric-variable is -1 if there is a coincidence and 0 if there is no coincidence. If the keyword ALL is given, the coincidence of any two sprites is reported. If two sprites are identified by #sprite-number, their coincidence is reported. If #sprite-number and a location are identified, their coincidence is reported. If the keyword ALL is given, sprites are coincident only if one or more of the dots which make them up occupy the same position on the screen. If two sprites or a sprite and a location are given, then tolerance must be specified, and two sprites are coincident if their upper left hand corners are within the value specified by tolerance. A sprite and a location are coincident if the upper left hand corner of the sprite and the position specified by dot-row and dot-column are within the value specified by tolerance. These coincidents are reported even if there is no apparent overlap of the sprites or the sprite and the position. Dot-row and dot-column are numbered consecutively starting with 1 in the upper left hand corner of the screen. Thus the dot-row can be from 1 to 192 and the dot-column can be from 1 to 256, (Actually the dot-row can go up to 256, but the positions from 193 through 256 are off the bottom of the screen.) If any part of the sprite occupies the position given, then there is a coincidence. Whether or not a coincidence is detected depends on several variables. If the sprites are moving very quickly, COINC may not be able to detect their coincidence. Also, COINC checks for a coincidence only when it is called, so a program may miss a coincidence that occurs when the program is executing some other statement. Quote Link to comment Share on other sites More sharing options...
RXB Posted January 11, 2019 Share Posted January 11, 2019 (edited) Honestly this is a more of a hardware problem of design of Sprite location detection using top left number 1 pixel of the 8x8 grid of a character. Now is RXB I have new routines for dealing with joystick and sprite collisions that does help with joystick with sprite control. What I have done is combined the commands CALL JOYSTICK :: CALL MOTION or CALL LOCATE and IF KEY=FIRE THEN line-number into a single GPL XB command and the speed increase is very noticable. Working on release of this new version of RXB 2019 Edited January 11, 2019 by RXB 1 Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted January 11, 2019 Share Posted January 11, 2019 It would be a wonderful thing to be able to specify particular sprites (say #1 & #5) and have the function behave as it currently does when the keyword ALL is specified. ie- Be able to check a true coincidence between sprites *only* when two dots occupy the same screen position, rather than the scatter-gun approach of using the upper left hand corner plus a specified tolerance. Does anyone have any ideas on how this might be achieved in XB? I imagine the processing might be too much for a regular XB program, but I doubt it would overwhelm an XB compiled program. I am basically trying to work out a method to detect a dot-to-dot coincidence without being forced to use the ALL Keyword (the use of multicoloured sprites make the ALL command mostly impractical). Any ideas? The ALL command must rely on a hardware register in the VDP (Video Display Processor). Technically I suppose XB reads and clears this bit of information from the VDP once every frame-update (on the ISR). So, as you've mentioned, any sprite overlaying any other sprite with one or more pixels will set this bit. And maybe a collision is held by XB (for more than one frame) until it is read using the COINC. On the other hand, when you use "tolerance", I think the value returned is calculated on the spot / fly. With Assembly you can try and detect on which raster-lines pixel collisions occur. I don't think this will be implemented in XB256. If you want to go with ALL, then you can cleverly arrange your sprites and paths so that only one collision can occur. Otherwise, if you can limit the number and types of collisions possible, then some pixel-points can be tested using ordinary calculations, but that takes processing power and won't be bulletproof. Let's take Space Invaders as an example, and let's assume it's all sprites. ALL will work perfectly, but we're soon having a hard time finding which hit what. Let's forget about shields. And then let's change the invader droppings to background graphics. And let's ensure that the invaders never overlap. And let's assume that you only got one missile going up at a time (it could be guided), well, any collision using ALL must be at the missile's position. More than one missile at a time is probably not impossible - as long as they don't overlap (with a reasonable gap). Other games may be simplified like this one way or another. 3 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 11, 2019 Share Posted January 11, 2019 (edited) Using software to test if two pixels overlap is really too time consuming even in assembly. I think the best approach is to use ALL first to test if any pixels overlap, and if so use tolerance to detect the involved sprites. If more than two sprites are close together you might end up detecting the wrong sprite, but that is usually acceptable. As Sometimes wrote it depends on how the sprites are organized. If two sprites always overlap, for instance, the ALL check is useless. Edit: If a F18A library for XB is ever developed the GPU could be used to provide a pixel accurate COINC function between one or more sprites. Edited January 11, 2019 by Asmusr 3 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted January 11, 2019 Share Posted January 11, 2019 Thinking about doing sprite bits COINC in assembly. This is a good fit for the CZC, COC, or SOCB instructions. It might be too cycle intensive to test all sprites, so pick the ones to test. It can also be effective at testing sprites against background chars. Bitwise Sprite COINC This code demonstrates testing for overlap between two 8x8 sprite patterns in CPU RAM. Assume you did coord testing and their 8x8 boundaries overlap. Sprite #2 is asssumed to be down and to the right of sprite #1. Other situations are left for later. 16x16 sprites are left for later. If you have multicolor (2 sprites together) it is probably best to create 1 combined dummy char pattern to test against. It will be an advantage to operate on everything in CPU RAM (keep SATB in CPU RAM, write the whole SATB to VDP on each "tick".) Here is a picture of an 8x8 ball hitting an 8x8 ship: R1-> 1111 R0 ^ 111111 <--> | 11111111 | R3 11111111 v R2->1111111*2 * = collision 1111111*2 11111122 1111 22 22 222222 22222222 22222222 PAT DATA >3C7E,>FFFF,>FFFF,>7E3C DATA >1818,>1818,>187E,>FFFF ... LI R0,4 x separation. needed in R0 for SLA LI R1,PAT sprite#1 pattern address LI R2,PAT+8 sprite#2 pattern address LI R3,4 y separation BL @HT JNE GOTHIT ... ... HT A R3,R1 LI R4,8 #rows to test S R3,R4 CLR R5 test/shift register CLR R6 test register HL MOVB *R1+,R5 SLA R5,0 shift #1 pat left by R0 places MOVB *R2+,R6 CZC R6,R5 if the 1s in #2 are all 0s in #1 JNE HX DEC R4 JNE HL HX RT return status: EQ if no hit, NE if hit. 2 Quote Link to comment Share on other sites More sharing options...
Willsy Posted January 11, 2019 Share Posted January 11, 2019 This might provide some inspiration. The Forth syntax probably won't mean very much, but overall i'm sure it'll make sense. Cheers Mark 2 Quote Link to comment Share on other sites More sharing options...
RXB Posted January 12, 2019 Share Posted January 12, 2019 (edited) Thinking about doing sprite bits COINC in assembly. This is a good fit for the CZC, COC, or SOCB instructions. It might be too cycle intensive to test all sprites, so pick the ones to test. It can also be effective at testing sprites against background chars. Bitwise Sprite COINC This code demonstrates testing for overlap between two 8x8 sprite patterns in CPU RAM. Assume you did coord testing and their 8x8 boundaries overlap. Sprite #2 is asssumed to be down and to the right of sprite #1. Other situations are left for later. 16x16 sprites are left for later. If you have multicolor (2 sprites together) it is probably best to create 1 combined dummy char pattern to test against. It will be an advantage to operate on everything in CPU RAM (keep SATB in CPU RAM, write the whole SATB to VDP on each "tick".) Here is a picture of an 8x8 ball hitting an 8x8 ship: R1-> 1111 R0 ^ 111111 <--> | 11111111 | R3 11111111 v R2->1111111*2 * = collision 1111111*2 11111122 1111 22 22 222222 22222222 22222222 PAT DATA >3C7E,>FFFF,>FFFF,>7E3C DATA >1818,>1818,>187E,>FFFF ... LI R0,4 x separation. needed in R0 for SLA LI R1,PAT sprite#1 pattern address LI R2,PAT+8 sprite#2 pattern address LI R3,4 y separation BL @HT JNE GOTHIT ... ... HT A R3,R1 LI R4,8 #rows to test S R3,R4 CLR R5 test/shift register CLR R6 test register HL MOVB *R1+,R5 SLA R5,0 shift #1 pat left by R0 places MOVB *R2+,R6 CZC R6,R5 if the 1s in #2 are all 0s in #1 JNE HX DEC R4 JNE HL HX RT return status: EQ if no hit, NE if hit. This is why I wanted help on XB ROMs and adding routines to RXB ROMs like moving CALL COINC from GPL to Assembly. Same for some other routines while remaining backwards compatible mostly. Some may be way faster like my new CALL JOYMOTION or JOYLOCATE then XB but easy to adjust in XB programs. When I combine CALL JOYST & CALL KEY & CALL MOTION & IF KEY=Fire button THEN line-number CALL JOYMOTION(keyunit,X,Y,#sprite,Rindex,Cindex,KEY) GOTO line-number That is a hell of a faster routine all in GPL then XB normal: CALL JOYST(1,X,Y) :: CALL KEY(1,S,S) :: CALL MOTION(#1,X*-4,Y*-4) :: IF S THEN line-number As you can see everytime you come back to XB has to look up the name of the routine and start processing it in the line vs RXB all done from a single GPL command. Now if I can use assembly this would really fly. Edited January 12, 2019 by RXB 1 Quote Link to comment Share on other sites More sharing options...
Bones-69 Posted January 15, 2019 Author Share Posted January 15, 2019 Thanks for the feedback and links guys - all very helpful stuff. I hadn't anticipated it would be this hard. For XB to not support dot-coincing between specified sprites I probably should have realised there was more to it.... I tried a few ideas on paper most of which were complicated, impractical, and took an absurd amount of steps and processing - but one idea seemed to have some potential, especially if it was XB compiled; It would be effortless using CALL POSITION to determine if the 64 dots of any MAGNIFY 3 sprite were in a situation where they might overlap with a second sprite. This could be determined from the the Upper Left Hand Corner position of each sprite. A minim overlap of one dot creates a potential 46 x 46 grid with the reference sprite being centered at position 16,16 (46 is determined by 16+15+15). If the two sprites fall within the 46 x 46 grid, the relative position of one sprite to the other sprite could be stored as a string. If the known positions for a coincidence were determined in advance, a "master string" could then act as a reference point for all such Y/X coordinates. Determining a dot-to-dot coincidence would then just be a case of searching one string within the other. So I think the steps would be; -Initial check to see if a coincidence is possible (if two sprites fall within the 46 x 46 grid), and if so; -Store relative coordinates of second sprite as a string -Search "master" string for the second sprite coordinate string using the POS command -If the returned variable in the POS statement is not equal to zero, a coincidence between two sprites has taken place. This idea seems like it might work although some effort in advance would be required to create the character "Coincidence Strings". Not sure if the concept is clear so I have Illustrated the idea in my attachment. *For the illustrated example I have not "stringified" the center of the cross, this would probably be necessary - especially to dot-check sprites that were in motion. 2 Quote Link to comment Share on other sites More sharing options...
Bones-69 Posted January 15, 2019 Author Share Posted January 15, 2019 Quick little test & seems to work OK! Is detecting a dot/dot coincidence between two specific sprites, without using CALL COINC. Use arrow keys; 100 CALL CLEAR :: CALL SCREEN(2):: FOR I=1 TO 12 :: CALL COLOR(I,15,2):: NEXT I :: CALL MAGNIFY(3):: DISPLAY AT(24,1):"COINC:" 110 S$="!-30!-31!-21!-12!-13!03!13!12!21!31!30!3-1!2-1!1-2!1-3!0-3!-1-3!-1-2!-2-1!-3-1!20!02!0-2!-20!10!00!-10!01!0-1"::Y=100 :: X=100 120 CALL CHAR(124,"0000000000010107070101000000000000000000008080E0E0808",128,"0000000000000001010000000000000000000000000000808") 130 CALL SPRITE(#2,124,7,80,X,#1,128,5,Y,X,#3,124,14,50,50,0,10,#4,124,14,50,50,0,-5,#5,124,14,50,50,0,5) 140 CALL KEY(0,A,B):: IF A<8 OR A>11 THEN 140 150 ON A-7 GOTO 160,170,180,190 160 X=X-1 :: GOTO 200 170 X=X+1 :: GOTO 200 180 Y=Y+1 :: GOTO 200 190 Y=Y-1 200 CALL LOCATE(#1,Y,X):: CALL POSITION(#2,A,B):: A=A-Y :: B=B-X :: A$="!"&STR$(A)&STR$(B):: C=POS(S$,A$,1):: IF C=0 THEN A$="NO" ELSE A$="YES" 210 DISPLAY AT(24,7):A$ :: GOTO 140 3 Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted January 15, 2019 Share Posted January 15, 2019 Interesting. Looking good. Unfortunately it will miss more than what's mentioned. And I'm thinking these are then rather simple sprites.FarmerPotato might have something that can be used in XB256. Like when ALL has detected a collision (could be many sprites overlapping), now then take a look at only sprite #3 and #10 and see if they are really overlapping.With some games there may even be the case where sprites seems to pass through each other, but are not overlapping in any individual frames. This can happen even with sprites only moving at 1 pixel per frame. Well, that's another story. 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted January 15, 2019 Share Posted January 15, 2019 (edited) This is a HARDWARE PROBLEM not a software problem. Sprites use upper left pixel 1 and then add a tolerance that SUCKS it goes in full circle around that 1st pixel the width of the tolerance. So you get hits from pixel 1 of a sprite that looks like it missed as they are not touching, but the Tolerance says they are? If you go to this video at minute 8:00 you will see RXB CALL COINC in RXB vs normal XB CALL COINC comparison. I improved it in RXB. Also keep going and I show the imporvement on RXB CALL DISTANCE in RXB vs normals XB CALL DISTANCE. Again I improved it in RXB. This was in RXB 2001 since then I have added more commands. Edited January 15, 2019 by RXB Quote Link to comment Share on other sites More sharing options...
Bones-69 Posted January 16, 2019 Author Share Posted January 16, 2019 Interesting. Looking good. Unfortunately it will miss more than what's mentioned. And I'm thinking these are then rather simple sprites. FarmerPotato might have something that can be used in XB256. Like when ALL has detected a collision (could be many sprites overlapping), now then take a look at only sprite #3 and #10 and see if they are really overlapping. With some games there may even be the case where sprites seems to pass through each other, but are not overlapping in any individual frames. This can happen even with sprites only moving at 1 pixel per frame. Well, that's another story. I had overlooked the diagonal possibility during my original thought process but ended up correcting it in the code (post #9). So in that example a coinc is detected in all positions that it should I have the situation of not being able to use ALL to drill down at almost any point., I have a design where sprites hide behind other sprites to give the effect of "popping up". I guess there is always a workaround, but I am trying very much to avoid it.... Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted January 16, 2019 Share Posted January 16, 2019 Quick little test & seems to work OK! Is detecting a dot/dot coincidence between two specific sprites, without using CALL COINC. Use arrow keys; 100 CALL CLEAR :: CALL SCREEN(2):: FOR I=1 TO 12 :: CALL COLOR(I,15,2):: NEXT I :: CALL MAGNIFY(3):: DISPLAY AT(24,1):"COINC:" 110 S$="!-30!-31!-21!-12!-13!03!13!12!21!31!30!3-1!2-1!1-2!1-3!0-3!-1-3!-1-2!-2-1!-3-1!20!02!0-2!-20!10!00!-10!01!0-1"::Y=100 :: X=100 120 CALL CHAR(124,"0000000000010107070101000000000000000000008080E0E0808",128,"0000000000000001010000000000000000000000000000808") 130 CALL SPRITE(#2,124,7,80,X,#1,128,5,Y,X,#3,124,14,50,50,0,10,#4,124,14,50,50,0,-5,#5,124,14,50,50,0,5) 140 CALL KEY(0,A,B):: IF A<8 OR A>11 THEN 140 150 ON A-7 GOTO 160,170,180,190 160 X=X-1 :: GOTO 200 170 X=X+1 :: GOTO 200 180 Y=Y+1 :: GOTO 200 190 Y=Y-1 200 CALL LOCATE(#1,Y,X):: CALL POSITION(#2,A,B):: A=A-Y :: B=B-X :: A$="!"&STR$(A)&STR$(B):: C=POS(S$,A$,1):: IF C=0 THEN A$="NO" ELSE A$="YES" 210 DISPLAY AT(24,7):A$ :: GOTO 140 I had overlooked the diagonal possibility during my original thought process but ended up correcting it in the code (post #9). So in that example a coinc is detected in all positions that it should It still says no. I have the situation of not being able to use ALL to drill down at almost any point., I have a design where sprites hide behind other sprites to give the effect of "popping up". I guess there is always a workaround, but I am trying very much to avoid it.... There's probably more to it, but here goes. Make the sprites you hide behind part of the background characters, and have the sprites that "pop up", have different patterns, so they appear to "pop up" from behind something. Quote Link to comment Share on other sites More sharing options...
Bones-69 Posted January 16, 2019 Author Share Posted January 16, 2019 You are absolutely right. In fixing the inside of the cross I forgot about the 4 "quadrants". It's an easy fix, just need to add 4 more coordinates to the string. I will get around to clarifying the challenge with an image in the next day or two. Thanks Sometimes. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.