There's probably other ways to do it using assembler and the hardcol register but I haven't explored that side of the Amiga hardware yet. So I'm probably wrong! ;D
From a quick look at the Amiga HRM (Hardware Reference Manual) I have you are correct. It is possible to detect collisions between sprites and the background.Thanks Lonewolf10. Had a quick look at my manuals (a bit out of date - A1000 - but that's a long story) and it looks very promising. Particularly like the way you can limit it to specific bitplanes. That makes it possible to have a full colour background, but collisions only detected with certain bits of the 'landscape'. 8)
I don't understand why AMOS doesn't take advantage of this feature.I suspect it was maybe considered a bit too complex to inflict on AMOS programmers at the time. I had a think about how it could be put into AMOS Basic instruction format and it's not easy to come up with something workable. BUT, it should definitely be considered for the AMOS Pro Re-development project.
Thanks Lonewolf10.
I also came across one of those docs files from way back. The ones that people typed in by hand. I've attached the archive it came from, plus the individual file to save hunting around for it.
I don't understand why AMOS doesn't take advantage of this feature.I suspect it was maybe considered a bit too complex to inflict on AMOS programmers at the time. I had a think about how it could be put into AMOS Basic instruction format and it's not easy to come up with something workable.
Just thinking out loud - maybe it could be implemented as:
- A set of instructions to set up the background detections and priorities required
- Instructions to put the settings into action (e.g. Back Col On, Back Col Off, etc.)
- Instructions to test for background collisions along the lines of the current AMOS ones for Sprites and Bobs.
- Extend AMAL to do the same (hard one that!)
Repeat
Set Hardcol 1,1
Sprite 0,X Mouse,Y Mouse,1
Text 16,16,"Hardcol(0)="+Str$(Hardcol(0))
Multi Wait
Until Mouse Click
'==================================================
' Demo of Hardware Sprite Collision with Bitplane
'
' Author : bruceuncle
' Date : 04/03/2014
'==================================================
'
' This code just positions the screen at the same
' hardware coords as your Default screen:
'
G_ADDR=Screen Base
G_XPOS=Deek(G_ADDR+82)
G_YPOS=Deek(G_ADDR+84) and $FF
For S=0 To 7
Trap Screen Close S
Next S
Screen Open 0,320,200,8,Lowres
Screen Display 0,G_XPOS,G_YPOS,320,2000
'
' The embedded sprite bank is the one in Tutorials used
' in the Collision Detection example program:
'
Get Sprite Palette : Colour 0,0 : Curs Off : Flash Off : Cls 0 : Hide On
'
' Ink 2 means we'll be drawing in bitplane 1 (cyan colour).
' This is the bitplane we want to detect collisions in.
'
Ink 2 : Box 80,80 To 239,119
'
' Ink 1 means we'll be drawing in bitplane 0 (sorta pink colour).
' This is a bitplane we're not interested in.
'
Ink 1 : Box 120,20 To 199,175
Pen 2 : Paper 0
Locate 0,23 : Centre "Press Right Mouse Key to Exit"
X=160 : Y=40 : DX=2 : DY=2
Sprite 1,X Hard(X),Y Hard(Y),2
'
' The sprite must be masked!
'
Make Mask 1
'
' Turn on hardware collision detection.
' 1st param is which bitplanes to turn on collision detection for.
' Corresponds to bits 6 to 11 in the CLXCON hardware register.
' Always set unused bitplanes to %0 in the bitmap.
' 2nd param is what value in the bitplane to check against (%0 or %1)
' Corresponds to bits 0 to 5 in the CLXCON hardware register.
' Unused bitplanes have no effect in the bitmap.
' AMOS always sets bits 12 to 15 to %1 in the CLXCON hardware register.
' That means the odd numbered sprites will also be included in the checks.
' So, effectively, all hardware sprites are always checked in AMOS.
'
' For this example we're looking for a collision with bitplane 1 so
' we will get a "hit" on the blue box but not on the pink one.
' AMOS always trims leading zeros. The value we're really loading
' is %000010, which is a bitmap of all 6 possible bitplanes. As our screen
' is only 8 colours, we're only using the first three bitplanes.
'
Set Hardcol %10,%10
'
Do
Exit If Mouse Key=2
Add X,DX : Add Y,DY
If X>294 or X<26 Then DX=-DX
If Y>174 or Y<26 Then DY=-DY
Sprite 1,X Hard(X),Y Hard(Y),2
'
' After a hit, we delay for four frames to give the sprite a chance
' to get clear:
'
If G_WAIT>0
Dec G_WAIT
Else
'
' Check sprite 1 for a hardware collision:
'
C=Hardcol(1)
'
' =Col(-1) means check for bitplane collisions (which bitplanes
' will be the ones we set up using Set Hardcol.
' 0 is returned for no collision, non-zero is a collision.
' I haven't investigated what the actual returned values mean yet!
'
If Col(-1)
'
' If we got a hit, I'm just jiggling the direction and sounding
' a ding. The G_WAIT is just to delay the next checks until
' the sprite has moved away from the box a bit. Helps prevent
' "head banging"!
'
Bell : DX=-DX : Add X,DX : G_WAIT=4
End If
End If
Wait Vbl
Loop
'
Screen Close 0
Edit
SpriteNumber | Result | |
0 thru 7 | Checks all possible hardware collisions for the specified SpriteNumber and returns -1 for a sprite-to-sprite collision. Returns 0 for a sprite to playfield collision. Saves the results (which sprite or bitplane was hit) for =Col() to use to retrieve the sprite number that was hit or whether a playfield was hit. | |
-1 | Checks only for a playfield-to-playfield collision and returns -1 for a hit and 0 for no hit. No need to use =Col() to retrieve any results. Note that this also clears AMOS's own collision table used by =Col() so there's no point in trying to use that instruction anyway! |
SpriteNumber | Result | |
0 thru 7 | Will return -1 if the specified SpriteNumber was hit and 0 for no hit. Note that the sprite numbers are paired due to Set Hardcol always enabling both odd and even sprites numbers. So if you get a hit for, say, sprite 2, you'll always also get a hit for sprite 3, and so on. There's no way to tell which one of each pair is involved. | |
8 thru 11 | Will return -1 if a bitplane hit has been detected. Values of 8 or 9 check for an odd numbered bitplane hit, values of 10 or 11 check for an even numbered bitplane hit. It doesn't matter which number you use in each pair, it's just a quirk caused by that sprite number pairing mentioned above. As the odd versus even bitplane number checking is only relevant in Dual Playfield mode, using any value from 8 thru 11 appears to work in single playfield modes. (Can any hardware expert out there verify that this is the way CLXDAT is supposed to work?) | |
-1 thru -255 | Will work through AMOS's table of collision results and return the sprite number (sic) for the first collision it finds (where a bit = %1). It will start at whatever number is specified in SpriteNumber (converting it to a positive number first). |
Hi Bruce Uncle.Oops! :-[ There should have been an updated attachment on that last post. The first version of the example worked for bitplane 1, but only by luck! (Well, I did say I hadn't worked out what all the replies were in that example post...) The culprit was my using =Col(-1).
Thanks for the documentation.
However I have a question:
In your example, if I use "Ink 4" instead of "Ink2", so I am on the 3rd bit plane, right ?
So I need to set "Set Hardcol %100,%100"
But if I do that, the ball also detect collision in bit plan 0.
I also tried "Set Hardcol %1,%1", same result.
Thanks.
'==================================================
' Demo of Hardware Sprite Collision with Bitplane
'
' Author : bruceuncle
' Date : 05/03/2014
'==================================================
'
' This code just positions the screen at the same
' hardware coords as your Default screen:
'
G_ADDR=Screen Base
G_XPOS=Deek(G_ADDR+82)
G_YPOS=Deek(G_ADDR+84) and $FF
For S=0 To 7
Trap Screen Close S
Next S
Screen Open 0,320,200,8,Lowres
Screen Display 0,G_XPOS,G_YPOS,320,2000
'
' The embedded sprite bank is the one in Tutorials used
' in the Collision Detection example program:
'
Get Sprite Palette : Colour 0,0 : Curs Off : Flash Off : Cls 0 : Hide On
'
' Ink 2 means we'll be drawing in bitplane 1 (cyan colour).
' This is the bitplane we want to detect collisions in.
'
Ink 2 : Box 80,80 To 239,119
'
' Ink 1 means we'll be drawing in bitplane 0 (sorta pink colour).
' This is a bitplane we're not interested in.
'
Ink 1 : Box 120,20 To 199,175
Pen 2 : Paper 0
Locate 0,24 : Centre "Right Mouse Button to Exit"
X=160 : Y=40 : DX=2 : DY=2
'
' Must be a hardware sprite (0 thru 7) not a computed one:
'
Sprite 1,X Hard(X),Y Hard(Y),2
'
' The sprite must be masked!
'
Make Mask 1
'
' Turn on hardware collision detection.
' 1st param is which bitplanes to turn on collision detection for.
' Corresponds to bits 6 to 11 in the CLXCON hardware register.
' Always set unused bitplanes to %0 in the bitmap.
' 2nd param is what value in the bitplane to check against (%0 or %1)
' Corresponds to bits 0 to 5 in the CLXCON hardware register.
' Unused bitplanes have no effect in the bitmap.
' AMOS always sets bits 12 to 15 to %1 in the CLXCON hardware register.
' That means the odd numbered sprites will also be included in the checks.
' So, effectively, all hardware sprites are always checked in AMOS.
'
' For this example we're looking for a collision with bitplane 1 so
' we will get a "hit" on the blue box but not on the pink one.
' AMOS always trims leading zeros. The value we're really loading
' is %000010, which is a bitmap of all 6 possible bitplanes. As our screen
' is only 8 colours, we're only using the first three bitplanes.
'
Set Hardcol %10,%10
'
Do
Exit If Mouse Key=2
Add X,DX : Add Y,DY
If X>294 or X<26 Then DX=-DX
If Y>174 or Y<26 Then DY=-DY
Sprite 1,X Hard(X),Y Hard(Y),2
If G_WAIT>0
'
' After a hit, we delay for four frames to give the sprite a chance
' to get clear:
'
Dec G_WAIT
Else
'
' Check sprite 1 for a hardware collision. The results go into AMOS's
' internal collision table.
'
C=Hardcol(1)
'
' Display positions 8 thru 15 from AMOS's collision table:
'
Locate 0,23 : For I=8 To 11 : Print Hex$(Col(I),2); : Next I
'
' =Col(8) or =Col(9) means "check for the sprite colliding with an
' even-numbered bitplane specified in
' Set Harcol"
' =Col(10) or =Col(11) means "check for the sprite colliding with an
' odd-numbered bitplane specified in
' Set Harcol"
'
' 0 is returned for no collision, -1 is a collision.
'
' The above applies to dual playfield mode.
' In single playfield mode, it doesn't matter what you use.
'
If Col(8)
'
' If we got a hit, I'm just jiggling the direction and sounding
' a ding. The G_WAIT is just to delay the next checks until
' the sprite has moved away from the box a bit. Helps prevent
' "head banging"!
'
Bell : DX=-DX : Add X,DX : G_WAIT=4
End If
End If
Wait Vbl
Loop
'
Screen Close 0
Show On
Edit
In your updated example, let's draw a (red) line in the 3rd biplane using color 7.Ah, you're confusing colour numbers with bitplanes. Colour 7 is all bitplanes (7 = %111). So if you just want a single bitplane, you'd use Colour 1 (%001 - the first bitplane), Colour 2 (%010 - the second bitplane) or Colour 4 (%100 - the third bitplane). Colour 0 (%000) is no bitplanes. Colours 3, 5, 6 & 7 (for an 8 colour screen) all set pixels bits in more than one bitplane, so you'll register 'hits' in any of those bitplanes.
Colour 7,$F00: Ink 7: Draw 80,150 to 239,150
Then the detection is also activated to this bit plane, which is weird as we set it in the 2nd bit plane only.
I am still always very hazy when it comes to bitplaces / bitmaps etc. though. I kind of get the prinicple (how the colours are made up of true/false values in each place combining) ... my problem is understanding the application.Yeah, I have to stop and draw myself pictures every time I have to think about collisions, sprites, colour maps and bitplanes. Both the Amiga's strength (at the time) and its weakness, in that it takes a lot of planning to get what you want out of it. At least AMOS makes it easier to set up and test rather than doing it in C or Assembler.
Thank you for any help/advice!!!