I'm finding better results working on various projects for my 2D engine, citing necessity is the mother of invention (or re-invention) - rather than lay out specific functions and try to test them.. anyway my question is:

I'm working on a simple 'cannon-ball physics' type game, and I can never keep this straight:

Do my angles need to be expressed in degrees or radians?

An observation from an FPU tutorial from Raymond Filiatreault's site.. It makes sense but I didn't know you could do:

add esp,4 instead of pop to keep from trashing it the current register.. that is too kewlll...

then if I sub esp,4 do I mov esp,value?

Thnx.

I'm working on a simple 'cannon-ball physics' type game, and I can never keep this straight:

Do my angles need to be expressed in degrees or radians?

An observation from an FPU tutorial from Raymond Filiatreault's site.. It makes sense but I didn't know you could do:

add esp,4 instead of pop to keep from trashing it the current register.. that is too kewlll...

then if I sub esp,4 do I mov esp,value?

Thnx.

Angles should be in radians. You know you could just have tried both and see which worked.

ty - well I am already working with one unknown and I try to keep those to a minimum.

rewrite the first unknown 10 times ten different ways only to find out I had the second unknown wrong, at that would have been an easy fix...

rewrite the first unknown 10 times ten different ways only to find out I had the second unknown wrong, at that would have been an easy fix...

?The angle must be expressed in radians

is clearly specified in the first paragraph of the description for each of the fsin, fcos, fsincos and ftptan instructions in the quoted tutorial.
You can keep track of your angles in degrees (which I personally do most of the time) but you then have to convert them to radians before using them with the above trig instructions. The conversion is also explained in the tutorial.

As for the

**add esp,4**, POPing the stack effectively adds 4 to the ESP register after retrieving the value at into a register or a memory variable. If that value is useless, modifying directly the ESP avoids the trashing of a commodity.

The

**sub esp,4**would only reserve space on the stack without modifying the content of that space. You would often see a similar instruction generated by an assembler for LOCAL variables in a procedure.

Raymond

alright, I've tried several times to get it right, I am close but still no cigar...

in pseudocode, this is what I need:

.for ex = 0 to 120

vx=vo*cos(a*pi/180)

vy=vo*sin(a*pi/180)

vy=vy + (-0.0000981*ex*ex) ;ex is the current time increment, for gravity's sake

x=x+vx

y=y-vy

plot x,y

next ex

definitions:

... and code:

in pseudocode, this is what I need:

.for ex = 0 to 120

vx=vo*cos(a*pi/180)

vy=vo*sin(a*pi/180)

vy=vy + (-0.0000981*ex*ex) ;ex is the current time increment, for gravity's sake

x=x+vx

y=y-vy

plot x,y

next ex

definitions:

```
```

.data

blax REAL4 0.0

blay REAL4 0.0 ;coords x/y for flight of ball

PIdiv180 REAL4 0.0174533

angl REAL4 15.0 ;angle of descent

cspd REAL4 1.2

gravity REAL4 -0.0000981

VX REAL4 0.0 ;horizontal velocity = CSPD * cos(angl)

VY REAL4 0.0 ;vertical velocity = CSPD * sin(angl)

ex REAL4 0.0

... and code:

```
```

finit

fild angl

fimul PIdiv180

fcos

fmul cspd

fistp VX

fild angl

fimul PIdiv180

fsin

fmul cspd

fistp VY

fild ex

fimul ex

fmul gravity

fistp vy

;gravity seems to be working ok, the angle don't fly.. 15 shoots it at 45

; and 45 shoots it straight up in the air

mov eax,vy

add VY,eax

add ex,1

mov eax,VX

add eax,1

add blax,eax

mov eax,VY

sub blay,eax

invoke PlotPixel, blax, blay

```
```

finit

[COLOR=red]fild angl[/COLOR]

[COLOR=red]fimul PIdiv180[/COLOR]

fcos

fmul cspd

[COLOR=red]fistp VX[/COLOR]

[COLOR=red]fild angl[/COLOR]

[COLOR=red]fimul PIdiv180[/COLOR]

fsin

fmul cspd

[COLOR=red]fistp VY[/COLOR]

[COLOR=red]fild ex

fimul ex[/COLOR]

fmul gravity

[COLOR=red]fistp vy[/COLOR]

;gravity seems to be working ok, the angle don't fly.. 15 shoots it at 45

; and 45 shoots it straight up in the air

mov eax,vy

add VY,eax

add ex,1

mov eax,VX

add eax,1

add blax,eax

mov eax,VY

sub blay,eax

invoke PlotPixel, blax, blay

There is a bunch of stuff going wrong here. All your memory is defined as IEEE floating point however your intructing your FPU to treat the memory as registered memory (integers). This can not be good!...

I would try this for your PSEUDO code (i didnt test this):

```
```

.data

PI_by_180 REAL4 0.0174533

Gravity REAL4 -0.0000981

.data?

Angle REAL4 ?

Vo REAL4 ?

Vx REAL4 ?

Vy REAL4 ?

PlotFunct PROC uses ebx esi edi integer_Vo:DWORD, integer_degrees:DWORD, integer_X:DWORD, interger_Y:DWORD

LOCAL ex :DWORD

LOCAL int_X :DWORD

LOCAL int_Y :DWORD

LOCAL TempAngle :REAL4

; Set initial values

finit

; Init Pixel positions

;_____________________

mov eax, integer_X

mov int_X, eax

mov eax, integer_Y

mov int_Y, eax

; Vo = (REAL4) interger_Vo

;_________________________

lea edx, Vo

fild integer_Vo

fstp REAL4 PTR [edx]

; Angle = (REAL4) integer_Angle

;______________________________

lea edx, Angle

fild integer_degrees

fld st(0)

fstp REAL4 PTR [edx]

; TempAngle = Degrees * (Pi/180)

; Note: Angle already on stack at ST(0)

;______________________________________

lea edx, PI_by_180

lea ecx, TempAngle

fld REAL4 PTR [edx]

fmul

fstp REAL4 PTR [ecx]

; Stack is now empty, begin loop

;_______________________________

xor ebx, ebx

.while ebx <= 120

; Loop Begins Here

;vx=vo*cos(a*pi/180)

;vy=vo*sin(a*pi/180)

;___________________

lea esi, Vx

lea edi, Vy

lea edx, Vo

lea ecx, TempAngle

fld REAL4 PTR [ecx] ; St0 = TempAngle

fld st(0) ; st1 = st0

fcos

fld REAL4 PTR [edx] ; St0 = Vo & St1 = Cos(@) & st2 = TempAngle

fmul

fstp REAL4 PTR [esi] ; St0 = TempAngle

fsin

fld REAL4 PTR [edx] ; St0 = Vo & St1 = Sin(@)

fmul ; St0 = Vo*sin(@)

; vy=vy + (-0.0000981*ex*ex)

;___________________________

lea edx, ex

mov [edx], ebx

fild DWORD PTR [edx]

fld st(0)

fmul ; St0 = Ex*Ex & St1 = Vy

lea edx, Gravity

fld REAL4 PTR [edx]

fmul ; Sto = -Gravity*(Ex^2) & St1 = Vy

fadd ; St0 = Vy + (-Gravity*(Ex^2))

fstp REAL4 PTR [edi] ; Stack is emtpy

; x=x+vx

;_______

lea edx, ex

fld REAL4 PTR [esi] ; st0 = vx

fistp DWORD PTR [edx] ; ex = (integer)Vx

mov eax, [edx]

add int_X, eax

; y=y-vy

;_______

fld REAL4 PTR [edi] ; st0 = Vy

fispt DWORD PTR [edx] ; ex = (integer)Vy

mov eax, [edx]

sub int_y, eax

; Plot the new pixels

;____________________

invoke PlotMyPixels, int_X, int_Y

; Loop ends here

inc ebx

.endw

ret

PlotFunct ENDP

Its not opimized or anything, but hopefully it should help you see thru it... I kept it simple deliberately. The first half is initialization stuff (guess work on my behalf), and the loop is your Pseudo code translated...

Hope it helps..

:NaN:

I noticed that only Vy is changing due to gravity and Ex. So i pulled the reduntant stuff out of the inner loop as it can be pre-calculated and stored for speed in the loop. Vx is calculated once and converted to integer from in "x_const". As well Vx and Vy is calculated only once initially, but in the loop Vy is modified from each itteration. Lastly the intergers X & Y are updated and the plot call is made.

Here is a more lean & mean version of your above Pseudo code, Hope you like:

Here is a more lean & mean version of your above Pseudo code, Hope you like:

```
```

.data

PI_by_180 REAL4 0.0174533

Gravity REAL4 -0.0000981

.data?

Vo REAL4 ?

Vx REAL4 ?

Vy REAL4 ?

PlotFunct PROC uses ebx esi edi integer_Vo:DWORD, integer_degrees:DWORD, integer_X:DWORD, interger_Y:DWORD

LOCAL ex :DWORD

LOCAL x_const :DWORD

; Set initial values

finit

; Vo = (REAL4) interger_Vo

;_________________________

lea edx, Vo

fild integer_Vo

fstp REAL4 PTR [edx]

; TempAngle = Degrees * (Pi/180)

; Note: Angle already on stack at ST(0)

;______________________________________

lea edx, PI_by_180

fild integer_degrees

fld REAL4 PTR [edx]

fmul ; St0 = TempAngle

;vx=vo*cos(a*pi/180)

;vy=vo*sin(a*pi/180)

;___________________

lea edi, Vy

lea edx, Vo

lea ecx, x_const

fld st(0) ; st1 = st0 = TempAgnle

fcos

fld REAL4 PTR [edx] ; St0 = Vo & St1 = Cos(@) & st2 = TempAngle

fmul ' St0 = Vx

fistp DWORD PTR [ecx] ; St0 = TempAngle

fsin

fld REAL4 PTR [edx] ; St0 = Vo & St1 = Sin(@)

fmul ; St0 = Vo*sin(@)

fstp REAL4 PTR [edi] ; St0 = emtpy

; Stack is now empty, begin loop (ESI & EBX must be preserved)

;_______________________________

xor ebx, ebx

.while ebx <= 120

; Loop Begins Here

lea edx, ex

lea ecx, Gravity

; vy=vy + (-0.0000981*ex*ex)

;___________________________

fld REAL4 PTR [edi] ; st0 = Vy

mov [edx], ebx ; Ex = ebx

fild DWORD PTR [edx]

fld st(0)

fmul ; St0 = Ex*Ex & St1 = Vy

fld REAL4 PTR [ecx]

fmul ; Sto = -Gravity*(Ex^2) & St1 = Vy

fadd ; St0 = Vy + (-Gravity*(Ex^2))

fst REAL4 PTR [edi] ; St0 = Vy + (-Gravity*(Ex^2))

; y=y-vy

;_______

fispt DWORD PTR [edx] ; ex = (integer)Vy

mov eax, [edx]

sub integer_y, eax

; x=x+vx

;_______

mov eax, x_const

add integer_X, eax

; Plot the new pixels

;____________________

invoke PlotMyPixels integer_X, integer_Y

; Loop ends here

inc ebx

.endw

ret

PlotFunct ENDP

1st:

I don't know if your source is case sensitive, but I don't see any variable labeled "vy" in the .data section.

2nd:

In addition to NaN's remarks about directing the FPU to load the wrong data types, your balistics seem to be totally wrong.

You need to compute the horizontal and vertical velocities of the projectile based on the initial angle, but those remain constant throughout the trajectory; only the negative velocity due to gravity will change.

Technically, you should be plotting the distances travelled; but, by plotting at every unit of time, you can accumulate the calculated velocities as if they were distances.

This would be my version (not tested) assuming your PlotPixel function used integers as parameters.

Raymond

I don't know if your source is case sensitive, but I don't see any variable labeled "vy" in the .data section.

2nd:

In addition to NaN's remarks about directing the FPU to load the wrong data types, your balistics seem to be totally wrong.

You need to compute the horizontal and vertical velocities of the projectile based on the initial angle, but those remain constant throughout the trajectory; only the negative velocity due to gravity will change.

Technically, you should be plotting the distances travelled; but, by plotting at every unit of time, you can accumulate the calculated velocities as if they were distances.

This would be my version (not tested) assuming your PlotPixel function used integers as parameters.

```
.data
```

ex dd 0

coordx dd 0 ;the integers used for plotting

coordy dd 0 ; id

angle0 dw 15 ;assuming only integer values to be used

w180 dw 180 ;WORDS can also be used with the FPU

cspd REAL4 1.2

gravity REAL4 -0.0000981

VX REAL4 0.0 ;horizontal distance per unit time

VY REAL4 0.0 ;vertical distance per unit time

distX REAL4 0.0 ;total horizontal distance travelled

distY REAL4 0.0 ;total vertical distance travelled

.code

finit

fldpi

fidiv w180

fimul angle0 ;start angle now in radians

fsincos ;st=cos, st1=sin

fmul cspd ;st=cspd*cos, st1=sin

fstp VX ;st=sin

fmul cspd ;st=cspd*sin

fstp VY

invoke PlotPixel, coordx,coordy ;plot starting point

loop_here:

inc ex

fild ex

fmul st,st ;st=ex*ex

fmul gravity ;st=ex*ex*gravity

fadd VY ;st=ex*ex*gravity+VY

fadd distY ;st=ex*ex*gravity+VY+distY

fst distY ;keep as REAL4

fistp coordy ;store as rounded integer

fld distX ;st=distX

fadd VX ;st=distX+VX

fst distX ;keep as REAL4

fistp coordx ;store as rounded integer

invoke PlotPixel, coordx,coordy

cmp ex,120

jbe loop_here

Raymond

Sorry for error. My head must have gone a little balistic late at night.

The a*(t^2) calculates the cumulative distance travelled due to an accelaration

It must not be accumulated in each iteration. The computation of the "coordy" in my previous post should thus be altered as follows:

The a*(t^2) calculates the cumulative distance travelled due to an accelaration

**a**over a period of time**t**(technically it should read 0.5a*t^2).It must not be accumulated in each iteration. The computation of the "coordy" in my previous post should thus be altered as follows:

```
fld VY ;st=VY
```

fadd distY ;st=VY+distY

fst distY ;cumulative distance due to velocity

inc ex

fild ex ;st=ex, st1=VY+distY

fmul st,st ;st=ex*ex, st1=VY+distY

fmul gravity ;st=ex*ex*gravity, st1=VY+distY

fadd ;st=ex*ex*gravity+VY+distY

fistp coordy ;store as rounded integer

Raymondthank you Nan and Raymond, for your help.. I think I will try Nan's way first, it seems like I will learn more from it.. as for your way Raymond, I tried plugging it in and the ball goes down and then back up. I think it has to do with:

vy=vy+(gravity*t*t)

Y=Y-vy ;<=== this needs to be separate, (VY+distY) - (gravity*t^2) working on parenthesis before subtraction

X=X+vx

why can't I do fmul ST (or fmul ex) - it wont multiply the value by its stored value?

when does the value stored in the ST(n) shift.. when you specify the P , or can it do it on an add? Is there a general rule of thumb to know when that happens? I think that is the most confusing for me.

I take it I can't use FADD to add integers or FIADD for floating point??

I've come to realize also, fild works with integers and fld with floating point numbers (as it says in your docs) - I take it dwords, real4's, etc.. can be signed or unsigned and I don't have to worry bout that as I do with the decimals.

vy=vy+(gravity*t*t)

Y=Y-vy ;<=== this needs to be separate, (VY+distY) - (gravity*t^2) working on parenthesis before subtraction

X=X+vx

why can't I do fmul ST (or fmul ex) - it wont multiply the value by its stored value?

when does the value stored in the ST(n) shift.. when you specify the P , or can it do it on an add? Is there a general rule of thumb to know when that happens? I think that is the most confusing for me.

I take it I can't use FADD to add integers or FIADD for floating point??

I've come to realize also, fild works with integers and fld with floating point numbers (as it says in your docs) - I take it dwords, real4's, etc.. can be signed or unsigned and I don't have to worry bout that as I do with the decimals.

thank you Nan and Raymond, for your help.. I think I will try Nan's way first, it seems like I will learn more from it.. as for your way Raymond, I tried plugging it in and the ball goes down and then back up. I think it has to do with:

vy=vy+(gravity*t*t)

Y=Y-vy ;<=== this needs to be separate, (VY+distY) - (gravity*t^2) working on parenthesis before subtraction

X=X+vx

why can't I do fmul ST (or fmul ex) - it wont multiply the value by its stored value?

when does the value stored in the ST(n) shift.. when you specify the P , or can it do it on an add? Is there a general rule of thumb to know when that happens? I think that is the most confusing for me.

I take it I can't use FADD to add integers or FIADD for floating point??

I've come to realize also, fild works with integers and fld with floating point numbers (as it says in your docs) - I take it dwords, real4's, etc.. can be signed or unsigned and I don't have to worry bout that as I do with the decimals.

(1) FMUL if i remember correctlly will only work on ST(0) and ST(1), or ST(0) and Memory.

(2) Yes, the stack drops when "popped", just like the normal ESP stack, except the FPU stack has only 8 positions. When FLD is like Push, and FSTP is like POP. However, FST is only a memory write, the stack is unaffected.

(3) The "I" commands are only for bringing data into or out of the FPU stack. Then stack is *ALWAYS* a 10 byte IEEE floating point. So your REAL4's or REAL8's, or DWORDS are all converted to a "REAL10 or TWORD" on the stack. This is why you specificy the data size to the command. So no, the FIADD is not needed even if 4.0 is on the stack. FADD will surfice, since its already converted to floating point.

(4) As for signed dwords, im not too sure. I would check the doc's.

Regards,

:NaN:

My suggestion would be that you reread Chap.1 and Chap.2 of the tutorial a few times. It may take some time for all that info to sink in.

Then make sure you read the description of each instruction you intend to use. Some of the instructions may shift register numbers back or forth.

For example, you would read that the fsincos instruction replaces the angle in st(0) with its "sin" value and then pushes all the registers to load the "cos" value into the new top register. But only if the angle is within the acceptable range. If it is "out-of-range", the angle value would then stay unaltered in the top register and no register is "pushed"!!!

Raymond

Then make sure you read the description of each instruction you intend to use. Some of the instructions may shift register numbers back or forth.

For example, you would read that the fsincos instruction replaces the angle in st(0) with its "sin" value and then pushes all the registers to load the "cos" value into the new top register. But only if the angle is within the acceptable range. If it is "out-of-range", the angle value would then stay unaltered in the top register and no register is "pushed"!!!

Raymond