gfxgfxFreeBASIC Games Directory Forumgfxgfx
gfx gfx
gfx
Welcome, Guest. Please login or register. May 19, 2013, 07:20:01 PM

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.0

22.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
gfx
gfx
*
gfxgfx
gfxgfx gfxgfx
gfxgfx Home Help Search Login Register   gfxgfx
gfx gfx
gfx
Pages: [1] 2
Print
Author Topic: Pixel perfect collision by Mysoft.  (Read 6172 times)
Lachie Dazdarian
Double dipper
Administrator
Forum Sage
*****
Gender: Male
Posts: 1195


lachie13
View Profile WWW Email
« 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_
        add ESI,EAX
        add EDI,[BPIT]
        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_:
        add ESI,2
        add EDI,2
        dec ECX
        jnz _CPNEXTPIXEL16_
        add ESI,EAX       
        add EDI,[BPIT]
        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_:     
        add ESI,4
        add EDI,4
        dec ECX
        jnz _CPNEXTPIXEL32_
        add ESI,EAX
        add EDI,[BPIT]
        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: Male
Posts: 180

Let's rocK~!

nkk_kan
View Profile WWW Email
« 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  Tongue
Logged

mysoft
Recruit
**
Gender: Male
Posts: 38


mysoft@bol.com.br
View Profile WWW Email
« 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: Male
Posts: 180

Let's rocK~!

nkk_kan
View Profile WWW Email
« 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 Tongue...
Logged

mysoft
Recruit
**
Gender: Male
Posts: 38


mysoft@bol.com.br
View Profile WWW Email
« 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 Tongue...

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: Male
Posts: 32


R[a]wr

smithcosoft@yahoo.com smithcosoft
View Profile WWW Email
« 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: Male
Posts: 38


mysoft@bol.com.br
View Profile WWW Email
« 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: Male
Posts: 32


R[a]wr

smithcosoft@yahoo.com smithcosoft
View Profile WWW Email
« 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
'. . .
'redefined your declare
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: Male
Posts: 38


mysoft@bol.com.br
View Profile WWW Email
« 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

const HeaderSize = sizeof(fb.image)

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
const HeaderSize = 0

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: Male
Posts: 351


Who's the guy from 21 Jump Street?

notthecheatr TheMysteriousStrangerFromMars
View Profile WWW Email
« 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: Male
Posts: 351


Who's the guy from 21 Jump Street?

notthecheatr TheMysteriousStrangerFromMars
View Profile WWW Email
« 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: Male
Posts: 38


mysoft@bol.com.br
View Profile WWW Email
« 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       
        ASTRT = OBJA + HeaderSize
        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)
        BSTRT = OBJB + HeaderSize
        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)
        BSTRT = OBJB + HeaderSize
        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)
        BSTRT = OBJB + HeaderSize
        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)
        BSTRT = OBJB + HeaderSize
        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
Administrator
Forum Sage
*****
Gender: Male
Posts: 1195


lachie13
View Profile WWW Email
« 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. Sad
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: Male
Posts: 363


The Thirsty Smiley


View Profile WWW Email
« 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. Wink
Logged

Lachie Dazdarian
Double dipper
Administrator
Forum Sage
*****
Gender: Male
Posts: 1195


lachie13
View Profile WWW Email
« 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
Print
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines
Cerberus design by Bloc
Valid XHTML 1.0! Valid CSS!
gfx
gfxgfx gfxgfx