Blitz changes var types in userlibs!?

Blitz3D Forums/Blitz3D Userlibs/Blitz changes var types in userlibs!?

Very, very strange things are happening here on my pc... :(

I've created a simple userlib-dll with powerbasic:

#Compile Dll "xpldebug.dll"
#Debug Error On
#Dim All
#Option Version4
#Register Default

%c = 1

Declare Function xplTest SDecl Alias "xplTest" () As Long

Function LibMain (ByVal hInstance As Long, ByVal fwdReason As Long, ByVal lpvReserved As Long) Export As Long
  Function = 1
End Function

Function xplTest() Export As Long
  Local i As Long
  
  i = 345
  MsgBox "i = " + Str$(i) + ", c = " + Str$(%c)
  
  Function = 0
End Function


It exports only a single function, that should show an int var (= 345) and an int const value (= 1) in a message box.

The decl file is pretty simple:

.lib "xpldebug.dll"
xplTest%()


Well, and here's my Blitz3D code:

xplTest
Graphics3D 1024, 768, 32, 3
xplTest


Guess what's happening when I run this piece of code?

The first call of xplTest shows this:

i=345, c=1



Everything looks fine.

But the second one won't:

i=344,99998255992, c=10



I cannot use ints in my DLL after entering 3d graphics. How can this be? And no, this is not a bug in PB's message box, because I noted this strange thing after getting mysterious results when doing simple calculation with int vars (e.g. some results were one less than expected).

Maybe I should ask this over there at powerbasic forums. But since this happens only after a Graphics3D call, it seems to have something to do with Blitz' 3d engine, too.

Anyone else experienced this?

I can give you a partial explanation.

The CPU's floating point unit can be set to various modes. Blitz3D switches to single precision mode at the Graphics3D command. It really could have switched before this since it has only single precision floating point variables.

Here is a non-DLL example.
preG = PrecisionTest()

Graphics3D 300, 200, 0, 2

postG = PrecisionTest()

Text 50, 70,  "Before Graphics3D: " + preG
Text 50, 90, " After Graphics3D: " + postG

WaitKey : End


Function PrecisionTest() ; 119 for single precision, 30 if higher precision.
    x# = 0.1
    x = ( (x*x) * 100.0 - 1.0 ) * 100000.0
    Return Int( 10000.0 * x )
End Function
Your DLL inherits the Blitz3D FPU mode. That explains how it is possible to get different results before and after Graphics3D.

What it does not explain is why you don't get exactly 345 in every mode.

This might/might not be worth a read:

"...the first problem, where the FPU stack is destroyed and the value of numeric variables is changed...":
http://www.powerbasic.com/support/forums/Forum8/HTML/001283.html

http://www.powerbasic.com/support/forums/Forum2/HTML/000027.html

http://www.powerbasic.com/files/pub/docs/gazette/gaz025.txt

same in pb6.1 but i use this

LOCAL i AS LONG
LOCAL o AS INTEGER
o = 345
i = 345
MSGBOX "i = " + STR$(i) + ", c = " + STR$(%c)
MSGBOX "o = " + STR$(o) + ", c = " + STR$(%c)

Okay, maybe Blitz is changing the size of mantissa or something, but why should this affect my integer vars?

The only reason I could see is a statement by PowerBasic, that NPU registers are used to store vars temporarily for faster access. Maybe this causes a side effect to my integers too?!

@Panno: Wow, you're right, 16 bit integers work! But since I need at least 32 bit it isn't an option for me.

Btw, I discovered that only constants with value = 1 are displayed as "10", every other constant value stays the same. Well, I tried this:

%c = 1
MsgBox Str$(%c) ' Displays "10"
For i = 1 To %c
  MsgBox "Hi there"
Next

The MsgBox shows up only once.

%c = 1
MsgBox Str$(%c) ' Displays "10"
For i = 1 To Val(Str$(%c))
  MsgBox "Hi there"
Next

Now the MsgBox will be displayed ten times. Seems that Str$() causes the problem.

But all this is still mysterious to me. :(

Well, everything seems to work when I simply don't use STR$(). But then I discovered that SEEK command is broken when used with some higher file offsets. If I 'seek' a position and then check back with SEEK() function I get a different position (one less or three bytes ahead). This makes more complex file i/o impossible. :-(

This really drives me crazy...

PB's support wrote to me that this must be a bug in Blitz, so they won't give me any help solving this. :-((

Mark, what's going on here??