FreeBASIC Games Directory Forum
 Welcome, Guest. Please login or register. May 21, 2013, 02:37:46 AM 1 Hour 1 Day 1 Week 1 Month Forever Login with username, password and session length 11.5.2013 - Added a webpage for the latest FBGD competition.13.3.2013 - Members registrations temporary disabled. For all membership requests, please email me: lachie13@yahoo.com 30.11.2012 - The ninth issue of BASIC Gaming is out! Read it here: http://games.freebasic.net/forum/index.php?topic=560.022.11.2012 - Be sure to check our currently running annual FBGD game making competition. This year's theme is SEASONS OF THE YEAR, 300 \$ first place prize, and the competition runs till 18th of February. Link: http://games.freebasic.net/forum/index.php?topic=559.0

Pages: [1] 2
 Author Topic: Pixel perfect collision by Mysoft.  (Read 6176 times)
Lachie Dazdarian
Double dipper
Forum Sage

Gender:
Posts: 1195

 « on: January 12, 2008, 06:59:27 PM »

Another excellent FreeBASIC function by Mysoft. In ASM again.

#include once "fbgfx.bi"

declare function Collision(OBJA as any ptr, OAX as integer, OAY as integer, _
OBJB as any ptr, OBX as integer, OBY as integer) as integer

function Collision(OBJA as any ptr, OAX as integer, OAY as integer, OBJB as any ptr, OBX as integer, OBY as integer) as integer
dim as integer COLLI,TX,TY,RESULT,IBPP
dim as integer OASX,OASY,OBSX,OBSY
dim as integer OAXX,OAYY,OBXX,OBYY
dim as integer APIT,BPIT,XCNT,YCNT
dim as any ptr ASTRT,BSTRT,CSTRT
OASX = cptr(fb.image ptr,OBJA)->width-1
OASY = cptr(fb.image ptr,OBJA)->height-1
OBSX = cptr(fb.image ptr,OBJB)->width-1
OBSY = cptr(fb.image ptr,OBJB)->height-1
OAXX = OAX+OASX:OAYY = OAY+OASY
OBXX = OBX+OBSX:OBYY = OBY+OBSY
APIT = cptr(fb.image ptr,OBJA)->PITCH
BPIT = cptr(fb.image ptr,OBJB)->PITCH
IBPP = cptr(fb.image ptr,OBJA)->BPP
if IBPP = 1 then
IBPP = 0
elseif IBPP = 2 then
IBPP = 1
elseif IBPP = 4 then
IBPP = 2
else
return 0
end if

do
if OAX >= OBX and OAX <= OBXX then
' ********** 11 ***********
if OAY >= OBY and OAY <= OBYY then
if OBXX > OAXX then TX = OAXX else TX = OBXX
if OBYY > OAYY then TY = OAYY else TY = OBYY
ASTRT = OBJA + sizeof(fb.image)
BSTRT = OBJB + sizeof(fb.image) + _
((OAX-OBX) shl IBPP) + ((OAY-OBY)*BPIT)
XCNT = (TX-OAX)+1:YCNT = (TY-OAY)+1
APIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
BPIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
RESULT = 11: exit do
end if
' ********** >12< ***********
if OAYY >= OBY and OAYY <= OBYY then
if OBXX > OAXX then TX = OAXX else TX = OBXX
ASTRT = OBJA + sizeof(fb.image) + ((OBY-OAY)*APIT)
BSTRT = OBJB + sizeof(fb.image) + ((OAX-OBX) shl IBPP)
XCNT = (TX-OAX)+1:YCNT = (OAYY-OBY)+1
APIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
BPIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
RESULT = 12: exit do
end if
' *********** 13 *************
if OAY <= OBY and OAYY >= OBYY then
ASTRT = OBJA + sizeof(fb.image) + ((OBY-OAY)*APIT)
BSTRT = OBJB + sizeof(fb.image) + ((OAX-OBX) shl IBPP)
XCNT = (OBXX-OAX)+1:YCNT = OBSY+1
APIT -= ((OBXX-OAX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBXX-OAX) shl IBPP)+(1 shl IBPP)
RESULT = 13: exit do
end if
end if

if OAXX >= OBX and OAXX <= OBXX then
' *********** <21> *************
if OAY >= OBY and OAY <= OBYY then
if OBYY > OAYY then TY = OAYY else TY = OBYY
ASTRT = OBJA + sizeof(fb.image) + ((OBX-OAX) shl IBPP)
BSTRT = OBJB + sizeof(fb.image) + ((OAY-OBY)*BPIT)
XCNT = (OAXX-OBX)+1:YCNT = (TY-OAY)+1
APIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
RESULT = 21: exit do
end if
' *********** <22> ************
if OAYY >= OBY and OAYY <= OBYY then
ASTRT = OBJA + sizeof(fb.image) + _
((OASY-(OAYY-OBY))*APIT) + _
((OASX-(OAXX-OBX)) shl IBPP)
BSTRT = OBJB + sizeof(fb.image)
XCNT = (OAXX-OBX)+1:YCNT = (OAYY-OBY)+1
APIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
RESULT = 22: exit do
' *********** <23> ************
end if
if OAY <= OBY and OAYY >= OBYY then
ASTRT = OBJA + sizeof(fb.image) + _
((OBY-OAY)*APIT) + ((OBX-OAX) shl IBPP)
BSTRT = OBJB + sizeof(fb.image)
XCNT = (OAXX-OBX)+1:YCNT = OBSY+1
APIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
RESULT = 23: exit do
end if
end if

if OAX <= OBX and OAXX >= OBXX then
' ********** <31> *************
if OAY >= OBY and OAY <= OBYY then
ASTRT = OBJA + sizeof(fb.image) + ((OBX-OAX) shl IBPP)
BSTRT = OBJB + sizeof(fb.image)  + ((OAY-OBY)*BPIT)
XCNT = OBSX+1:YCNT = (OBYY-OAY)+1
APIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
RESULT = 31: exit do
end if
' ********** <32> *************
if OAYY >= OBY and OAYY <= OBYY then
ASTRT = OBJA + sizeof(fb.image) + _
((OBY-OAY)*APIT) + ((OBX-OAX) shl IBPP)
BSTRT = OBJB + sizeof(fb.image)
XCNT = OBSX+1:YCNT = (OAYY-OBY)+1
APIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
RESULT = 32: exit do
end if
' ********** <33> *************
if OAY <= OBY and OAYY >= OBYY then
ASTRT = OBJA + sizeof(fb.image) + _
((OBY-OAY)*APIT) + ((OBX-OAX) shl IBPP)
BSTRT = OBJB + sizeof(fb.image)
XCNT = OBSX+1:YCNT = OBSY+1
APIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
RESULT = 33: exit do
end if
end if
return 0
loop

if XCNT then
select case IBPP
case 0
' ******** 8 bpp pixel check ******
asm
mov ESI,[ASTRT]
mov EDI,[BSTRT]
mov EAX,[APIT]
mov EBX,[XCNT]
mov EDX,[YCNT]
_CPNEXTLINE8_:
mov ECX,EBX
_CPNEXTPIXEL8_:
cmp byte ptr [ESI],0
je _CPSKIPPIXEL8_
cmp byte ptr [EDI],0
je _CPSKIPPIXEL8_
jmp _CPENDCOLISION8_
_CPSKIPPIXEL8_:
inc ESI
inc EDI
dec ECX
jnz _CPNEXTPIXEL8_
dec EDX
jnz _CPNEXTLINE8_
neg dword ptr [RESULT]
_CPENDCOLISION8_:
end asm
case 1
' ******** 16 bpp pixel check ******
asm
mov ESI,[ASTRT]
mov EDI,[BSTRT]
mov EBX,[XCNT]
mov EDX,[YCNT]
mov EAX,[APIT]
_CPNEXTLINE16_:
mov ECX,EBX
_CPNEXTPIXEL16_:
cmp word ptr [ESI],0xF81F
je _CPSKIPPIXEL16_
cmp word ptr [EDI],0xF81F
je _CPSKIPPIXEL16_
jmp _CPENDCOLISION16_
_CPSKIPPIXEL16_:
dec ECX
jnz _CPNEXTPIXEL16_
dec EDX
jnz _CPNEXTLINE16_
neg dword ptr [RESULT]
_CPENDCOLISION16_:
end asm
case 2
' ******** 32 bpp pixel check ******
asm
mov ESI,[ASTRT]
mov EDI,[BSTRT]
mov EBX,[XCNT]
mov EDX,[YCNT]
mov EAX,[APIT]
_CPNEXTLINE32_:
mov ECX,EBX
_CPNEXTPIXEL32_:
cmp dword ptr [ESI],0xFFFF00FF
je _CPSKIPPIXEL32_
cmp dword ptr [EDI],0xFFFF00FF
je _CPSKIPPIXEL32_
jmp _CPENDCOLISION32_
_CPSKIPPIXEL32_:
dec ECX
jnz _CPNEXTPIXEL32_
dec EDX
jnz _CPNEXTLINE32_
neg dword ptr [RESULT]
_CPENDCOLISION32_:
end asm
end select
end if

return RESULT

end function

As you see it works simple as:

Collision_Variable = Collision(Object1_Image_Buffer_Pointer, Object1_PositionX, Object1_PositionY, Object2_Image_Buffer_Pointer, Object2_PositionX, Object2_PositionX)

This zipped with a nice compiled example: http://lachie.phatcode.net/mysoft_collision.zip

Screenshot:
 Logged

"Things like Basic and Free Basic provide much-needed therapy and a return to sanity and a correct appreciation of people. The arrogant folk really hate a word like 'Basic' - fine, and good riddance." ~ pragmatist
nkk_kan
Forum Howler

Gender:
Posts: 180

Let's rocK~!

 « Reply #1 on: January 12, 2008, 09:51:32 PM »

Cool~!

it also does That Square Block Testing ( i forgot what it was called..) and pixel perfect too!
i guess the only hitch is that i don't know how he did that.....
and that assembly code looks intimidating
 Logged

mysoft
Recruit

Gender:
Posts: 38

 « Reply #2 on: January 12, 2008, 10:42:52 PM »

The Result will be...

0  (no collision at alll)
<0 (box collision)
>0 (pixel collision)

so generally you only want to do:

if collision(....) > 0 then ...
 Logged

Programming is like love... you will never acomplish anything by treating your language as if it was a tool, or a slave of yours...
nkk_kan
Forum Howler

Gender:
Posts: 180

Let's rocK~!

 « Reply #3 on: January 13, 2008, 12:00:31 AM »

no no...i understand that...
but what i mean is i don't understand what the asm code does...
i've to figure out how you check the collision ...
 Logged

mysoft
Recruit

Gender:
Posts: 38

 « Reply #4 on: January 13, 2008, 02:42:53 AM »

no no...i understand that...
but what i mean is i don't understand what the asm code does...
i've to figure out how you check the collision ...

ha yes... my last post is just to explain the result (since it isnt simple 0 or 1)
anywayz despite than that... i guess it not hurt try to explain:

1) both rectangle have 4 points... so, check if one of the 4 points  are inside the other rectangle and the reserve (that is 8 checks) - ps: i have used a slight different method.. but the base is the same
2) so if there are some point inside the rectange... you will be able to get the intersection rectangle (that is showed in rect in the example), so the intersection rectangle will be made with the borders of both rectangles (isnt easy to explain... but is easy to get when seeing the example...)
3) since its a intersection... this rectangle will existe in both boxes... and then they have the same size (width/height) now you know that a pixel is only a byte a short or a integer inside one block of memory (it depends of the bpp of the screen of course), (this is important for the ASM code)
4) you need to get the the position of the intersection rectangle in both boxes...  in my case instead of getting the X,Y position... i get the address of the pixel (object address + header size + (Y position * pitch) + (X position * bytes per pixel)... let's call them OBJA_INTPTR and OBJB_INTPTR then here goes the trick...
5) let's say OBJA have size of 64x64 and OBJB have 80x40 and the intersection rectangle have 32x20. So you already got the start address of the instersection rectangle in both objects... it's width is 32, so you check 32 pixels (read the pixel pointed by OBJA_INTPTR and the one pointed OBJB_INTPTR, if no one of them is transparent... then you found a collision (the function can return TRUE), or else point to the next pixel (just ADD (num bytes/pixel) to the OBJA_INTPTR and OBJB_INTPTR... and decrease the pixel(width of the intersect rectangle) variable counter until it reaches to 0
6) so... it have tested the whole line and didnt find a pixel... then you decrease the line variable counter (height of the intersect rectangle) and ofcourse set the width variable to 32 again... but now we need to pointer to the next line... how to do that?
7) well the OBJA have 64 pixels of width (64 bytes in 8bpp) so the pitch of that line is 64... and the intersection rectangle have a pitch of 32... subtract the intersection rectangle pitch from the OBJA pitch... (that is 64-32=32) and then adding this value to OBJA... get the pitch diference with the OBJB and the intersection... and then add the result to the OBJA_INTPTR and OBJB_INTPTR respectively
6) so now go back to step 5... until there are no more lines to check (the height of the intersect rectangle variable reaches 0)...  if after all that no pixel collided then.. return FALSE (no collision)

so there it is... (the explanation have something related to asm programming as you can see) at least i tried to explain ;P
 Logged

Programming is like love... you will never acomplish anything by treating your language as if it was a tool, or a slave of yours...
SSC
Recruit

Gender:
Posts: 32

R[a]wr

 « Reply #5 on: January 13, 2008, 05:41:26 AM »

Well the explanation sounded reasonable enough, but the code is another story . . . I know little to nothing of asm heh. I was wondering though, how difficult would this be to port to opengl graphics? Doesn't seem like it would be very hard (just change the pointer information to the new graphics type?) but I tried a quick hack and slash of the variables to make it work from what I actually did understand of the code, no luck though.
 Logged
mysoft
Recruit

Gender:
Posts: 38

 « Reply #6 on: January 13, 2008, 06:20:10 AM »

Well the explanation sounded reasonable enough, but the code is another story . . . I know little to nothing of asm heh. I was wondering though, how difficult would this be to port to opengl graphics? Doesn't seem like it would be very hard (just change the pointer information to the new graphics type?) but I tried a quick hack and slash of the variables to make it work from what I actually did understand of the code, no luck though.

well you need to update this variables
OASX = cptr(fb.image ptr,OBJA)->width-1 '(width of the object A minus one in pixels)
OASY = cptr(fb.image ptr,OBJA)->height-1 '(height of the object A minus one in pixels )
OBSX = cptr(fb.image ptr,OBJB)->width-1 '(width of the object B minus one in pixels )
OBSY = cptr(fb.image ptr,OBJB)->height-1 '(height of the object B minus one in pixels)

APIT = cptr(fb.image ptr,OBJA)->PITCH '(pitch ([b]bytes[/b] per line) of the A object)
BPIT = cptr(fb.image ptr,OBJB)->PITCH  '(pitch ([b]bytes[/b] per line) of the B object)
IBPP = cptr(fb.image ptr,OBJA)->BPP '(bytes per pixel)

but there's another thing....

you will found a lot of
OBJA + sizeof(fb.image)
OBJB + sizeof(fb.image)

that was the pointer of the bits of the image...

 Logged

Programming is like love... you will never acomplish anything by treating your language as if it was a tool, or a slave of yours...
SSC
Recruit

Gender:
Posts: 32

R[a]wr

 « Reply #7 on: January 14, 2008, 05:36:03 AM »

Alright so I made a real attempt this time instead of a quick hack test, but it isnt working, so here is what I did.

1. I added 2 variables to pass to the function image and image2, both as gfxtype
2. changed the variables in your code to my defined graphics type

my code attempts to collide a moving character to a stationary character of the same graphic.

type gfxtype
handle as gluint
width as integer
height as integer
texturefilter as integer
imagedata as ubyte ptr
bpp as uinteger
textype as uinteger
end type

dim char_tex as gfxtype
'. . .
declare function collision(image as gfxtype, image2 as gfxtype, OBJA as any ptr, OAX as integer, OBJB as any ptr, OBX as integer, OBY as integer)
'. . .
'I called it like this

count = collision(char_tex, char_tex, char_tex.imagedata, charatcer.xpos, character.ypos, char_tex.image_data, 80, 80)

in your code I changed it to

OASX = image.width - 1
OASY = image.height - 1
OBSX = image2.width - 1
OBSY = image2.height - 1

APIT = image.width * 4
BPIT = image2.width * 4
'the pitch is prolly where it went wrong if anything, I wasn't sure how to calculate it and pulled it out of some old code on the forums
IBPP = image.bpp

'and for all of the sizeof(fb.image) statements
'I changed them to

sizeof(image.imagedata)
 « Last Edit: January 14, 2008, 05:38:06 AM by SSC » Logged
mysoft
Recruit

Gender:
Posts: 38

 « Reply #8 on: January 14, 2008, 06:15:53 AM »

OASX = image.width - 1
OASY = image.height - 1
OBSX = image2.width - 1
OBSY = image2.height - 1

OK!

APIT = image.width * 4
BPIT = image2.width * 4
'the pitch is prolly where it went wrong if anything, I wasn't sure how to calculate it and pulled it out of some old code on the forums
IBPP = image.bpp

APIT and BPIT are right considering a 32bpp image...
IBPP is actually BYTES per pixel (that is 1,2 or 4) not BITS per pixel (8,16 or 32) (im pretty sure that it was in BITS per pixel in the OpenGL data)... i also recommend do this:

IBPP = (image.bpp shr 3) 'bits/8 = bytes (32bpp = 4 bytes per pixel)
APIT = image.width * IBPP 'ok it will get the right pitch for the real bpp
BPIT = image2.width * IBPP 'same

Quote
'and for all of the sizeof(fb.image) statements
'I changed them to sizeof(image.imagedata)

i guess that image.imagedata is already the pointer of the first pixel in the image... then there's no need to add   the size of the buffer again...

so i guess that you can add a CONST in the end of the collision function... like this

and then change all sizeof(fb.image) to HeaderSize
this way you can change only one line to avoid errors since the same repeats many times...
and in the OGL case since you are giving the image data pointer you can use simple

sorry i forgot to add that CONST myself ^^"
good luck![/u]

 Logged

Programming is like love... you will never acomplish anything by treating your language as if it was a tool, or a slave of yours...
notthecheatr
Global Moderator
Forum Sage

Gender:
Posts: 351

Who's the guy from 21 Jump Street?

 « Reply #9 on: January 14, 2008, 12:41:04 PM »

Sweet, this will really be great.
 Logged

The funniest thing happened yesterday.
notthecheatr
Global Moderator
Forum Sage

Gender:
Posts: 351

Who's the guy from 21 Jump Street?

 « Reply #10 on: January 14, 2008, 12:45:46 PM »

By the way, does it support alpha mapping or only trans?  Either way is fine, I can always use my Trans->Alpha converter to create a map, but does it have built-in alpha support?
 Logged

The funniest thing happened yesterday.
mysoft
Recruit

Gender:
Posts: 38

 « Reply #11 on: January 14, 2008, 02:33:44 PM »

By the way, does it support alpha mapping or only trans?  Either way is fine, I can always use my Trans->Alpha converter to create a map, but does it have built-in alpha support?

one small update... added one extra (optional) param to check for a maximum alpha value to be considered transparent... (32bpp only)

#include once "fbgfx.bi"

declare function Collision(OBJA as any ptr, OAX as integer, OAY as integer, _
OBJB as any ptr, OBX as integer, OBY as integer, USEALPHA as integer=0) as integer

screenres 400,300,32

dim as any ptr A,B,C
dim as integer MX,MY

A = ImageCreate(64,64)
B = ImageCreate(64,64,rgba(0,0,0,0))
C = ImageCreate(400,300,0)

Circle A,(32,32),31,rgb(0,255,0),,,,f
Circle B,(32,32),31,rgba(255,0,0,64),,,,f
Circle B,(32,32),15,rgb(0,0,255),,,,f

for COUNT as integer = 0 to 65535
pset C,(rnd*400,rnd*300),rgb(rnd*64,rnd*64,rnd*64)
next COUNT

do

getmouse MX,MY

screenlock
put(0,0),C,pset
put(200-32,150-32),B,alpha
put(MX-32,MY-32),A,trans

if COllision(A,MX-32,MY-32,B,200-32,150-32,1) > 0 then
locate 1,1
print "Collision!"
end if

screenunlock

sleep 1
loop until inkey\$ = chr\$(27)

function Collision(OBJA as any ptr, OAX as integer, OAY as integer, OBJB as any ptr, OBX as integer, OBY as integer,USEALPHA as integer=0) as integer
dim as integer COLLI,TX,TY,RESULT,IBPP
dim as integer OASX,OASY,OBSX,OBSY
dim as integer OAXX,OAYY,OBXX,OBYY
dim as integer APIT,BPIT,XCNT,YCNT
dim as any ptr ASTRT,BSTRT,CSTRT

const MaximumAlpha = 64 'Max alpha value that will be considered transparent
const HeaderSize = sizeof(fb.image) 'size of the image header (if any) (32 bytes for fbgfx)
OASX = cptr(fb.image ptr,OBJA)->width-1 'width of the object A minus one
OASY = cptr(fb.image ptr,OBJA)->height-1 'height of the object A minus one
OBSX = cptr(fb.image ptr,OBJB)->width-1 'width of the object B minus one
OBSY = cptr(fb.image ptr,OBJB)->height-1 'height of the object B minus one
IBPP = cptr(fb.image ptr,OBJA)->BPP  'BYTES per pixel (1(8), 2(16), 4(32)
APIT = cptr(fb.image ptr,OBJA)->PITCH 'width*BPP object A (16 byte granularity for fbgfx)
BPIT = cptr(fb.image ptr,OBJB)->PITCH 'width*BPP object B (16 byte granularity for fbgfx)
OAXX = OAX+OASX:OAYY = OAY+OASY
OBXX = OBX+OBSX:OBYY = OBY+OBSY

if IBPP = 1 then
IBPP = 0
elseif IBPP = 2 then
IBPP = 1
elseif IBPP = 4 then
IBPP = 2
else
return 0
end if

do
if OAX >= OBX and OAX <= OBXX then
' ********** 11 ***********
if OAY >= OBY and OAY <= OBYY then
if OBXX > OAXX then TX = OAXX else TX = OBXX
if OBYY > OAYY then TY = OAYY else TY = OBYY
BSTRT = OBJB + HeaderSize + _
((OAX-OBX) shl IBPP) + ((OAY-OBY)*BPIT)
XCNT = (TX-OAX)+1:YCNT = (TY-OAY)+1
APIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
BPIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
RESULT = 11: exit do
end if
' ********** >12< ***********
if OAYY >= OBY and OAYY <= OBYY then
if OBXX > OAXX then TX = OAXX else TX = OBXX
ASTRT = OBJA + HeaderSize + ((OBY-OAY)*APIT)
BSTRT = OBJB + HeaderSize + ((OAX-OBX) shl IBPP)
XCNT = (TX-OAX)+1:YCNT = (OAYY-OBY)+1
APIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
BPIT -= ((TX-OAX) shl IBPP)+(1 shl IBPP)
RESULT = 12: exit do
end if
' *********** 13 *************
if OAY <= OBY and OAYY >= OBYY then
ASTRT = OBJA + HeaderSize + ((OBY-OAY)*APIT)
BSTRT = OBJB + HeaderSize + ((OAX-OBX) shl IBPP)
XCNT = (OBXX-OAX)+1:YCNT = OBSY+1
APIT -= ((OBXX-OAX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBXX-OAX) shl IBPP)+(1 shl IBPP)
RESULT = 13: exit do
end if
end if

if OAXX >= OBX and OAXX <= OBXX then
' *********** <21> *************
if OAY >= OBY and OAY <= OBYY then
if OBYY > OAYY then TY = OAYY else TY = OBYY
ASTRT = OBJA + HeaderSize + ((OBX-OAX) shl IBPP)
BSTRT = OBJB + HeaderSize + ((OAY-OBY)*BPIT)
XCNT = (OAXX-OBX)+1:YCNT = (TY-OAY)+1
APIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
RESULT = 21: exit do
end if
' *********** <22> ************
if OAYY >= OBY and OAYY <= OBYY then
ASTRT = OBJA + HeaderSize + _
((OASY-(OAYY-OBY))*APIT) + _
((OASX-(OAXX-OBX)) shl IBPP)
XCNT = (OAXX-OBX)+1:YCNT = (OAYY-OBY)+1
APIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
RESULT = 22: exit do
' *********** <23> ************
end if
if OAY <= OBY and OAYY >= OBYY then
ASTRT = OBJA + HeaderSize + _
((OBY-OAY)*APIT) + ((OBX-OAX) shl IBPP)
XCNT = (OAXX-OBX)+1:YCNT = OBSY+1
APIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OAXX-OBX) shl IBPP)+(1 shl IBPP)
RESULT = 23: exit do
end if
end if

if OAX <= OBX and OAXX >= OBXX then
' ********** <31> *************
if OAY >= OBY and OAY <= OBYY then
ASTRT = OBJA + HeaderSize + ((OBX-OAX) shl IBPP)
BSTRT = OBJB + HeaderSize  + ((OAY-OBY)*BPIT)
XCNT = OBSX+1:YCNT = (OBYY-OAY)+1
APIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
RESULT = 31: exit do
end if
' ********** <32> *************
if OAYY >= OBY and OAYY <= OBYY then
ASTRT = OBJA + HeaderSize + _
((OBY-OAY)*APIT) + ((OBX-OAX) shl IBPP)
XCNT = OBSX+1:YCNT = (OAYY-OBY)+1
APIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
RESULT = 32: exit do
end if
' ********** <33> *************
if OAY <= OBY and OAYY >= OBYY then
ASTRT = OBJA + HeaderSize + _
((OBY-OAY)*APIT) + ((OBX-OAX) shl IBPP)
XCNT = OBSX+1:YCNT = OBSY+1
APIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
BPIT -= ((OBSX) shl IBPP)+(1 shl IBPP)
RESULT = 33: exit do
end if
end if
return 0
loop

if XCNT then
select case IBPP
case 0
' ******** 8 bpp pixel check ******
asm
mov ESI,[ASTRT]         'ESI = ObjectA intersected rect pointer
mov EDI,[BSTRT]         'EDI = ObjectB intersected rect pointer
mov EAX,[APIT]          'EAX = Pitch of objecta excluding intersect size
mov EBX,[XCNT]          'EBX = width of intersect area
mov EDX,[YCNT]          'EDX = height of intersect area
_CPNEXTLINE8_:        'compare next 8 bit line
mov ECX,EBX             'ECX=EBX (intersected width)
_CPNEXTPIXEL8_:       'compare next 8 bit pixel
cmp byte ptr [ESI],0    'pixel in object A is transparent?
je _CPSKIPPIXEL8_       'yes? than no collision is possible (skip that pixel)
cmp byte ptr [EDI],0    'pixel in object B is transparent?
je _CPSKIPPIXEL8_       'yes? than no collision is possible (skip that pixel)
jmp _CPENDCOLISION8_    'collision found (go to end of verification code)
_CPSKIPPIXEL8_:       'skipped a pixel
inc ESI                 'point obj A to the next pixel
inc EDI                 'point obj B to the next pixel
dec ECX                 'decrease the width counter (one pixel less)
jnz _CPNEXTPIXEL8_      'go test next pixel until it reaches 0
add ESI,EAX             'point obj A to the next line
add EDI,[BPIT]          'point obj B to the next line
dec EDX                 'decrease height counter (one line less)
jnz _CPNEXTLINE8_       'go test next line until it reaches 0
neg dword ptr [RESULT]  'change RESULT signal (to negative)
_CPENDCOLISION8_:     'end of verification
end asm
case 1
' ******** 16 bpp pixel check ******
asm
mov ESI,[ASTRT]             'ESI = ObjectA intersected rect pointer
mov EDI,[BSTRT]             'EDI = ObjectB intersected rect pointer
mov EBX,[XCNT]              'EBX = width of intersect area
mov EDX,[YCNT]              'EDX = height of intersect area
mov EAX,[APIT]              'EAX = Pitch of objecta excluding intersect size
_CPNEXTLINE16_:           'compare next 16 bit line
mov ECX,EBX                 'ECX=EBX (intersected width)
_CPNEXTPIXEL16_:          'compare next 16 bit pixel
cmp word ptr [ESI],0xF81F   'pixel in object A is transparent?
je _CPSKIPPIXEL16_          'yes? than no collision is possible (skip that pixel)
cmp word ptr [EDI],0xF81F   'pixel in object B is transparent?
je _CPSKIPPIXEL16_          'yes? than no collision is possible (skip that pixel)
jmp _CPENDCOLISION16_       'collision found (go to end of verification code)
_CPSKIPPIXEL16_:          'skipped a pixel
add ESI,2                   'point obj A to the next pixel
add EDI,2                   'point obj B to the next pixel
dec ECX                     'decrease the width counter (one pixel less)
jnz _CPNEXTPIXEL16_         'go test next pixel until it reaches 0
add ESI,EAX                 'point obj A to the next line
add EDI,[BPIT]              'point obj B to the next line
dec EDX                     'decrease height counter (one line less)
jnz _CPNEXTLINE16_          'go test next line until it reaches 0
neg dword ptr [RESULT]      'change RESULT signal (to negative)
_CPENDCOLISION16_:        'end of verification
end asm
case 2
if USEALPHA then
' ******** 32 bpp pixel check (including alhpa) ******
asm
mov ESI,[ASTRT]             'ESI = ObjectA intersected rect pointer
mov EDI,[BSTRT]             'EDI = ObjectB intersected rect pointer
mov EBX,[XCNT]              'EBX = width of intersect area
mov EDX,[YCNT]              'EDX = height of intersect area
_CPNEXTLINE32A_:          'compare next 32 bit line
mov ECX,EBX                 'ECX=EBX (intersected width)
_CPNEXTPIXEL32A_:         'compare next 32 bit pixel
mov EAX,[ESI]               'EAX = Pixel in object A
cmp EAX,0xFFFF00FF          'pixel in object A is transparent?
je _CPSKIPPIXEL32A_         'yes? than no collision is possible (skip that pixel)
shr EAX,24                  'Getting alpha value
cmp AL,MaximumAlpha         'Is alpha below or equal Maximum Alpha?
jbe _CPSKIPPIXEL32A_        'yes? than no collision is possible (skip that pixel)
mov EAX, [EDI]              'EAX = Pixel in object B
cmp EAX,0xFFFF00FF          'pixel in object B is transparent?
je _CPSKIPPIXEL32A_         'yes? than no collision is possible (skip that pixel)
shr EAX,24                  'Getting alpha value
cmp AL,MaximumAlpha         'Is alpha below or equal Maximum Alpha?
jbe _CPSKIPPIXEL32A_        'yes? than no collision is possible (skip that pixel)
jmp _CPENDCOLISION32A_      'collision found (go to end of verification code)
_CPSKIPPIXEL32A_:         'skipped a pixel
add ESI,4                   'point obj A to the next pixel
add EDI,4                   'point obj B to the next line
dec ECX                     'decrease height counter (one line less)
jnz _CPNEXTPIXEL32A_        'go test next pixel until it reaches 0
add ESI,[APIT]              'point obj A to the next line
add EDI,[BPIT]              'point obj B to the next line
dec EDX                     'decrease height counter (one line less)
jnz _CPNEXTLINE32A_         'go test next line until it reaches 0
neg dword ptr [RESULT]      'change RESULT signal (to negative)
_CPENDCOLISION32A_:       'end of verification
end asm
else
' ******** 32 bpp pixel check ******
asm
mov ESI,[ASTRT]             'ESI = ObjectA intersected rect pointer
mov EDI,[BSTRT]             'EDI = ObjectB intersected rect pointer
mov EBX,[XCNT]              'EBX = width of intersect area
mov EDX,[YCNT]              'EDX = height of intersect area
mov EAX,[APIT]              'EAX = Pitch of objecta excluding intersect size
_CPNEXTLINE32_:             'compare next 32 bit line
mov ECX,EBX                 'ECX=EBX (intersected width)
_CPNEXTPIXEL32_:          'compare next 32 bit pixel
cmp dword ptr [ESI],0xFFFF00FF   'pixel in object A is transparent?
je _CPSKIPPIXEL32_          'yes? than no collision is possible (skip that pixel)
cmp dword ptr [EDI],0xFFFF00FF   'pixel in object B is transparent?
je _CPSKIPPIXEL32_          'yes? than no collision is possible (skip that pixel)
jmp _CPENDCOLISION32_       'collision found (go to end of verification code)
_CPSKIPPIXEL32_:          'skipped a pixel
add ESI,4                   'point obj A to the next pixel
add EDI,4                   'point obj B to the next line
dec ECX                     'decrease height counter (one line less)
jnz _CPNEXTPIXEL32_         'go test next pixel until it reaches 0
add ESI,EAX                 'point obj A to the next line
add EDI,[BPIT]              'point obj B to the next line
dec EDX                     'decrease height counter (one line less)
jnz _CPNEXTLINE32_          'go test next line until it reaches 0
neg dword ptr [RESULT]      'change RESULT signal (to negative)
_CPENDCOLISION32_:        'end of verification
end asm
end if
end select
end if

return RESULT

end function
 Logged

Programming is like love... you will never acomplish anything by treating your language as if it was a tool, or a slave of yours...
Lachie Dazdarian
Double dipper
Forum Sage

Gender:
Posts: 1195

 « Reply #12 on: August 09, 2008, 10:14:13 AM »

Anyone knows how to get this working with PNGLOAD? Because I loaded two PNG files with transparent backgrounds into ANY PTRs, and tried to collide those sprites. I get box collision.
 Logged

"Things like Basic and Free Basic provide much-needed therapy and a return to sanity and a correct appreciation of people. The arrogant folk really hate a word like 'Basic' - fine, and good riddance." ~ pragmatist
KristopherWindsor
Forum Sage

Gender:
Posts: 363

The Thirsty Smiley

 « Reply #13 on: August 09, 2008, 01:12:40 PM »

Probably the alpha value is different - if the collision check assumes alpha is &HFFFF00FF, then if PNG Load is setting alpha = &H00FF00FF, then it won't work.
 Logged

Lachie Dazdarian
Double dipper
Forum Sage

Gender:
Posts: 1195

 « Reply #14 on: August 09, 2008, 03:48:06 PM »

Well, I found a way to work around it. I just need to paste the sprites with ALPHA on a magic pink rectangle, and grab them again with GET.

I'm in OPENGL window so this is basically happening off screen (it just needs proper memory buffers).
 Logged

"Things like Basic and Free Basic provide much-needed therapy and a return to sanity and a correct appreciation of people. The arrogant folk really hate a word like 'Basic' - fine, and good riddance." ~ pragmatist
Pages: [1] 2