Ya so since it's my first stab at FPU it comes as no surprise it doesn't work.
IsCircleColl proc x1:REAL4, y1:REAL4, x2:REAL4, y2:REAL4, r:REAL4
LOCAL dist:REAL4
fld x1 ;ST0 = x1
fsub x2 ;ST0 = x1-x2
fabs ;ST0 = abs(x1-x2)
fld y1 ;ST0 = y1
;ST1 = abs(x1-x2)
fsub y2 ;ST0 = y1-y2
fabs ;ST0 = abs(y1-y2)
fmul st, st ;ST0 = abs(x1-x2)^2
fld st(1) ;ST0 = abs(y1-y2)
;ST1 = abs(x1-x2)^2
;ST2 = abs(y1-y2)
fmulp st(2), st ;ST0 = abs(x1-x2)^2
;ST1 = abs(y1-y2)^2
faddp st(1), st ;ST0 = abs(x1-x2)^2 + abs(y1-y2)^2
fsqrt ;ST0 = sqrt(abs(x1-x2)^2 + abs(y1-y2)^2)
fcom r ;if (r < ST0) return 0
;else return dist
jl @F
fstp dist ;ST0 popped into dist - stack balanced
mov eax, dist
ret
@@:
mov eax, 0
ret
IsCircleColl endp
It first checks the distance between two circles (of varying size), then checks that against the sum of both circle's radii to see if they're touching/colliding or not. Any idea whats wrong?
You are calling FINIT somewhere, aren't you? :wink
Alright adding fninit seems to have gotten rid of the random crashing. Good 'ol initializing saves the day. Now onto the good stuff, the anglo in asm is giving strange results to my ball collisions. Here's the pseuseudoe code for it:
float IsCircleColl (float x1, float x2, float y1, float y2, float rad)
{
float X = abs(x1 - x2);
float Y = abs(y1 - y2);
X = X * X;
Y = Y * Y;
float dist = sqrt(X + Y);
if (dist <= r) return dist;
return 0;
}
Any ideas where I went wrong?
Are all balls the same size?
Do the (x:y) coords refer to the center of the ball?
Is "r" just a typo in your post where you meant to write "rad" ?
If all of the above are true, then you'll be wanting to do "if (dist <= 2 * rad) ...." (the distance between the center of ball1 and the center of ball2 is less than twice the radius of the balls) right?
BTW it's probaby faster to return a BOOL for (collision/no collision) unless the return value is used by the calling code.
regards,
-Brent
Quote from: doomsday on April 03, 2005, 06:05:59 PM
Are all balls the same size?
Do the (x:y) coords refer to the center of the ball?
Is "r" just a typo in your post where you meant to write "rad" ?
If all of the above are true, then you'll be wanting to do "if (dist <= 2 * rad) ...." (the distance between the center of ball1 and the center of ball2 is less than twice the radius of the balls) right?
BTW it's probaby faster to return a BOOL for (collision/no collision) unless the return value is used by the calling code.
regards,
-Brent
For testing the balls are the same radius, XY in this case refers to the top-left corner, r is a typo, and rad is (rad1 + rad2) before the function is called, so no math has to be done on that inside this function. I need to return the distance between them so I can calculate the angle between the balls if there is a collision and bounce them away properly.
Updated it to remove the abs's, don't need them since a negative squared equals a positive anyways. It's still miscalculating collisions though, and runs 1-2 fps slower then the c++ version =[
; r = radius of the two circles added together
LOCAL dist:REAL4
fninit
fld x1 ;ST0 = x1
fsub x2 ;ST0 = x1-x2
fld y1 ;ST0 = y1
;ST1 = x1-x2
fsub y2 ;ST0 = y1-y2
;ST1 = x1-x2
fmul st, st ;ST0 = (y1-y2)^2
;ST1 = x1-x2
fld st(1) ;ST0 = x1-x2
;ST1 = (y1-y2)^2
;ST2 = x1-x2
fmulp st(2), st ;ST0 = (x1-x2)^2
;ST1 = (y1-y2)^2
faddp st(1), st ;ST0 = (x1-x2)^2 + (y1-y2)^2
fsqrt ;ST0 = sqrt((x1-x2)^2 + (y1-y2)^2)
fcom r ;if (r < ST0) return 0
;else return dist
jl down
fstp dist
mov eax, dist
ret
down:
mov eax, 0
ret
The first detail to clear up is if the "r" (sum of the 2 radii) is in the REAL4 format or not. If not, you could never get a proper comparison.
The second detail is a wrong assumption on your part. The "fcom" instruction DOES NOT CHANGE CPU FLAGS. It only changes some of the bits in the Status Word. Look at the following for a description of that instruction:
http://www.ray.masmcode.com/tutorial/fpuchap7.htm#fcom
If you want the CPU flags modified based on the result of a comparison on the FPU, you will have to use the "fcomi" (or fcomip) instruction. Look at the following to understand the requirements.
http://www.ray.masmcode.com/tutorial/fpuchap7.htm#fcomi
Raymond
Thanks a lot, that would be the reason I'm getting weird results.