View Full Version : Storing not allows
Hi Eros,
i have some problems with FILE_Get and FILE_Put !
Are there only STRINGS that i can read and write ?
I am not able to store a Byte into an array !
What is wrong here ? ???
Here my Routine:
Function LoadMaps()
Local F, j as Long
F = FILE_Open("Maps/Map" + Lev + "-1.bin","Binary")
iF F =0 Then MsgBox(0,"What did you do !")
For j = 1 To 300
Map1(j) = FILE_Get(F, 1)
Next
FILE_Close(F)
End Function
Do you know an answer ?
Peter
Michael Hartlef
11-10-2008, 17:29
Hi Peter,
I hope that I'm allowed to answer as you asked Eros specifically. The FILE module stores binary files as strings. But you can do what you want to do with thinBasic. You just have to use some conversion commands. Look in the helpfile under the MKx commands for your write activities and the CVx commands for when you read. But here are some functions to get you started:
'------------------------------------------------------------
SUB FileWriteInt( f AS DWORD, i AS INTEGER )
FILE_PUT( f, MKI$( i ))
END SUB
'------------------------------------------------------------
SUB FileWriteLong( f AS DWORD, l AS LONG )
FILE_PUT( f, MKL$( l ))
END SUB
'------------------------------------------------------------
SUB FileWriteSingle( f AS DWORD, s AS SINGLE )
FILE_PUT( f, MKS$( s ))
END SUB
'------------------------------------------------------------
SUB FileWriteByte( f AS DWORD, b as byte)
FILE_PUT( f, MKbyt$( b ))
End SUB
'------------------------------------------------------------
sub FileWriteString( f AS DWORD, s as string )
local ch as byte
local k as long
For k = 1 To Len( s )
ch=Asc(Mid$(s,k,1))
FileWriteByte(f,ch)
If ch=0 then exit for
Next
FileWriteByte( f, 0 )
End sub
'------------------------------------------------------------
FUNCTION FileReadByte( f AS DWORD ) AS byte
DIM b AS byte
DIM buffer AS STRING
buffer = FILE_GET( f, 1 )
b = CVbyt( buffer, 1 )
RETURN b
END FUNCTION
'------------------------------------------------------------
FUNCTION FileReadInt( f AS DWORD ) AS INTEGER
DIM i AS INTEGER
DIM buffer AS STRING
buffer = FILE_GET( f, 2 )
i = CVI( buffer, 1 )
RETURN i
END FUNCTION
'------------------------------------------------------------
FUNCTION FileReadLong( f AS DWORD ) AS LONG
DIM l AS LONG
DIM buffer AS STRING
buffer = FILE_GET( f, 4 )
l = CVL( buffer, 1 )
RETURN l
END FUNCTION
'------------------------------------------------------------
FUNCTION FileReadSingle( f AS DWORD ) AS SINGLE
DIM s AS SINGLE
DIM buffer AS STRING
buffer = FILE_GET( f, 4 )
s = CVS( buffer, 1 )
RETURN s
END FUNCTION
'------------------------------------------------------------
Function FileReadString( f as dword ) as string
local s as string
local ch as byte
do
ch=fileReadByte( f )
If ch=0 then exit do
s = s + Chr$(ch)
loop
return s
End Function
I hope that helps
Michael
Petr Schreiber
11-10-2008, 18:03
I know I will repeat myself,
but when me and DIM ... AT saw each other, it was love at first sight :D
You can overlay array of BYTE over string, see this demo:
' -- Saving BYTE data, and receiving them
uses "FILE"
dim s as string
dim i as long
' -- Create dummy data
for i = 1 to 300
s += MKBYT$(rnd(0, 255))
next
' -- Save test file
FILE_SAVE(APP_SOURCEPATH+"Test.txt", s)
' -- Now we will retrieve what we have written
' -- Array to receive data
dim ta(300) AS BYTE
' -- We pass name of file and target array
LoadMap(APP_SOURCEPATH+"Test.txt", ta)
msgbox 0, "Look what I have loaded:"+$CRLF+Join$(ta, ",")
function LoadMap( fName AS STRING, BYREF targetArray() AS BYTE)
' -- Check if output array is properly dimensioned
if ubound(targetArray) <> 300 then REDIM PRESERVE targetArray(300)
' -- Buffer we load whole file into
LOCAL rawData AS STRING = FILE_LOAD(fName)
' -- Magic - BYTE array overlayed over raw file data = instant conversion to BYTE
LOCAL TemporaryArray(300) AS BYTE at strptr(rawData)
' -- Copy data from overlay array to the output one
LOCAL i AS LONG
FOR i = 1 to 300
targetArray(i) = TemporaryArray(i)
next
' -- Note: Instead of using FOR we could use STAT_COPYARRAY
END FUNCTION
Petr
Hi Michael,
thank you very much !
I will try out it.
I have two other question:
How i get a Pointer on an array ?
How i get a NULL terminating STRING ?
Is this okay ?
Dim Map1(300) as Byte
Dim a$ = "MyFile" + %VT_EMPTY as String, Pointer1,Pointer2 as Long
Pointer1 = VarPtr(Map1(1))
Pointer2 = VarPtr(a$)
Peter
[quote=peter ]
Hi Michael,
thank you very much !
I will try out it.
I have two other question:
How i get a Pointer on an array ?
How i get a NULL terminating STRING ?
Is this okay ?
Dim Map1(300) as Byte
Dim a$ = "MyFile" + %VT_EMPTY as String, Pointer1,Pointer2 as Long
Pointer1 = VarPtr(Map1(1))
Pointer2 = VarPtr(a$)
Also much thanks for Petr !
Peter
Petr Schreiber
11-10-2008, 18:55
Hi Peter,
Dim Map1(300) as Byte
Dim a$ = "MyFile" + %VT_EMPTY as String, Pointer1,Pointer2 as LONG
Pointer1 = VarPtr(Map1(1))
Pointer2 = VarPtr(a$)
I think it is almost correct, but I would do it like this:
Dim Map1(300) as Byte
Dim a$ AS STRING = "MyFile"
DIM Pointer1,Pointer2 as Long
Pointer1 = VarPtr(Map1(1))
Pointer2 = StrPtr(a$)
You must use StrPtr for STRING variables.
There are 3 kinds of string variables in ThinBasic:
STRING - the most flexible, the most comfortable. It can take any size, and you do not have to care about ending
null character. To get pointer use STRPTR.
STRING * n - fixed length string. It can be n characters long at max. To get pointer use VARPTR.
ASCIIZ * n - fixed length string. It can be (n-1) characters long at max. Why n-1? Because nth character is null. This is closest to C like strings. To get pointer use VARPTR.
I am not sure for what you need to get NULL character in string, to get length of STRING you can use LEN function.
If you want to use NULL character in string, you can use CHR$(0) or more straightforward $NULL equates.
Petr
Michael Hartlef
11-10-2008, 19:13
Hi Michael,
thank you very much !
I will try out it.
I have two other question:
How i get a Pointer on an array ?
How i get a NULL terminating STRING ?
Is this okay ?
Dim Map1(300) as Byte
Dim a$ = "MyFile" + %VT_EMPTY as String, Pointer1,Pointer2 as Long
Pointer1 = VarPtr(Map1(1))
Pointer2 = VarPtr(a$)
Peter
Hi Peter,
Petr answered your questions. Thanks Petr.
Hi Petr,
thanks for your advices and help.
I will write a File system for me.
greeting...
Peter
ErosOlmi
11-10-2008, 20:13
Peter,
I think Michael and Petr have already replied. I just wanted to add few indications.
thinBasic is quite restrictive in declaring variables. You HAVE TO always declare variables and its type. For this reasons it is not necessary to add $ or % other signe inside variable name to set the type. I know, this is a common way of doing in Basic languages but not in thinBasic. You can define DIM MyVar$ AS LONG. It is the AS clause that define the type.
You used %VT_EMPTY equates mixed with a string. All equates starting with %VT are referring to VARIANT variables and should not be mixed with other concepts.
As Petr said, dynamic strings in thinBasic are very powerful and flexible, very easy to be used but at the same time not so easy to understand.
Here I will just say that thinBasic dynamic strings are implemented on the basis of Microsoft OLE string as described at: http://msdn.microsoft.com/en-us/library/ms221069.aspx
When you allocate a string, in reality thinBasic is allocating a pointer to a memory are that will hold the string. VARPTR will return a pointer to the string pointer. STRPTR will return a pointer to the data area. See image attached to the following post for more help (http://community.thinbasic.com/index.php?topic=2009.msg14858#msg14858).
Regarding files, as Michael said, you have to decide if to go with some text file format (comma or tab delimited or other kind) or with binary format. If you go with binary format, you have to transform numeric values in their binary representations for example using thinBasic MK... functions. Also transform strings into something you will be able to load again later because thinBasic strings can have NUL chars inside. So to save and restore a string into a binary file you have to adopt some personal strategy (there is no THE WAY but many ways) to store info about the type of data you are saving and if string you need to save the length of the string otherwise it would be difficult to retrieve it later.
Ciao
Eros
Hi Eros,
That's was a great description from you.
Many thanks therefor.
I think that i have understood this stuff.
It's really different than so many Basic dialects.
But in the principle, it's the same thing.
A bunch of greetings...
Peter
Hi peter, it looks like you're working on another game. :)
Michael Clease
12-10-2008, 18:37
Hi peter, it looks like you're working on another game. :)
arent we all ;D
Hi Matthew,
you are right !
i will check thinBasic whether i can write some games like my old Projects.
Now, i have litttle trouble with the array index.
My levels are displaced and i find at the moment no solution therefor !
The game engine is already running .
I need a formula for the array index.
Example:
Dim Map(300)
for y =1 to 20
for x =1 to 15
c = y * 20 + x
Tile = Map(c)
iF Tile =8 Then Sprite Wall, x*16, y*16, 0 ( 0 is here the Sprite Frame !)
(Sprites are 16 x 16) !
First element in the array must to the screen on 0, 0 position.
But the first element is ( 20*1 +1 = 21) !
The solution therefor is :
c = (y *20 + x) -20
Tile = Map(c)
iF tile =8 then Sprite Wall, x*16 -16, y*16 -16, 0
This is okay. But my hero runs wrong in the Labyrinth !
You knows now my problem , have a meditation over it !
Peter
Petr Schreiber
13-10-2008, 16:26
Hi Peter,
you were used to zero based arrays I presume.
ThinBasic uses base 1.
So what about:
for y = 1 to 20
for x = 1 to 15
c = (y-1) * 15 + x ' one Y series contain 15 elements ( determined by X 1 to 15 )
Tile = Map(c)
IF Tile =8 Then Sprite Wall, x*16, y*16, 0
Did you considered using 2D arrays?
Petr
Hi Petr,
That is already done ! ::)
I found the solution before a short time.
Indeed, it was not so difficult how i thought .
I think i need more sleep , beer and food.
Thank you for your endeavor.
By the way: I need a better sound engine !
Possibly i could use DirectX7 or DirectX8 for my sounds .
Can this go ?
Peter
ErosOlmi
13-10-2008, 21:08
Petr,
check TBASS module and example in \thinBasic\SampleScripts\TBASS