Oxygen Basic
Programming => Problems & Solutions => Topic started by: Peter on February 27, 2011, 05:25:46 AM
-
Deleted.
-
Hi Peter,
That looks like a syntax error that has fallen through to the essembler. An extra comma somewhere?
I need specimins, so I can work out how to trap these errors earlier.
Charles
-
Hi Peter,
This is probably the cleanest solution.
It's the usual hassle with null pointers being used in the Windows API. And also trying to avoid unnecessary structure definitions.
To Anonymise the Map type, I pass the address of Map (& Map)
Charles
% GENERIC_WRITE = &H40000000
% GENERIC_READ = &H80000000
% FILE_SHARE_READ = &H1
% OPEN_ALWAYS = 4
Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByVal lpBuffer As any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByVal lpOverlapped As any) As Long
Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Long sys_count
Function LoadFile(byval file as string, byval Dest as any, byval count as long) as long '<-- This Function here!
Long fHandle
fHandle = CreateFile file,
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ,
0,
OPEN_ALWAYS,
128,
0
ReadFile fHandle,Dest,count,sys_count, 0
CloseHandle fHandle
End Function
Dim Map(200) As Byte
LoadFile "map1-1.bin",&Map,100
print map(1)
-
You can also use the built-in getfile / putfile which handle whole files.
This is how to overlay your byte array "map" onto a dynamic string containing the file data. So it has a similar functionality to your code but there are no limitations on array size and you can treat the data both as a dynamic string and an array of bytes.
string s=getfile "map1-1.bin"
byte map at *s
print map[1]
Note that for overlays like this, any variable can be used as a one dimensional array. You do not have to declare it as an array :)
Charles
-
Hi Peter,
you need to create the string buffer first with enough bytes before reading the file contents into it.
Here is how I do it in Oxygen (o2runt.bas) FreeBasic
'-----------------------------------------
function getfile(byval w as bstr) as bstr
'=========================================
'
dim as sys b,h,p,pf,ph,le,leh
'
asm
'
'CHECK VALID NAME
'
cmp dword ptr [w],0
jz ngetfile
'
'OPEN FILE
'
push 0 'HANDLE hTemplateFile OPT
push 128 'FILE_ATTRIBUTE_NORMAL
push 3 'CREATE (NEW 1) (ALWAYS 2) (OPEN 4) (OPEN EXISTING 3)
push 0 'LP SECURITY ATTRIBUTES OPT
push 1 'SHARE MODE read(1) write(2)
push &h80000000 'GENERIC_READ (0x80000000) GENERIC_WRITE (0x40000000)
push [w] 'name
call Createfile
mov [h],eax
'
'SET FILE POINTER
'
push 0 'DWORD dwMoveMethod 0,FILE_BEGIN(0) FILE_CURRENT(1) FILE_END (2)
lea eax,[ph] 'PLONG lpDistanceToMoveHigh
push eax
push 0 'LONG lDistanceToMove
push [h] 'DWORD HANDLE
call SetFilePointer '
mov [pf],eax 'File Pointer position low
'
'GET FILE SIZE
'
lea eax,[leh] 'PLONG lpFileSizeHigh
push eax '
push [h] 'DWORD HANDLE
call GetFileSize '
mov [le],eax '
'
'CREATE STRING BUFFER
'
push [le] 'FILE LENGTH
push 0 'OPTIONAL COPY POINTER
call SysAllocStringByteLen 'CREATE BSTR
mov [p],eax
mov [function],eax
'
'READ FILE
'
push 0 'LPOVERLAPPED lpOverlapped
lea eax,[b] 'lpNumberOfBytesRead
push eax '
push [le] 'DWORD nNumberOfBytesToRead
push [p] 'LPVOID lpBuffer
push [h] 'DWORD HANDLE
call ReadFile
'
'CLOSE HANDLE
'
push [h]
call CloseHandle
'
ngetfile:
'
end asm
end function
Anyway I got your code working with a few alterations. I did not need to do much. You nearly had it working :)
shl in RGB
lea sys_len
String param byref pDest in Loadfile
create the string with required length
then pass the *pDest to read
Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByRef lpOverlapped As OVERLAPPED) As Long
Declare Function WriteFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByRef lpOverlapped As OVERLAPPED) As Long
Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
long sys_count
Function RGB(byval red as long,byval green as long,byval blue as long) as long
long color
xor eax, eax
mov al, blue
shl eax, 8
mov al, green
shl eax, 8
mov al, red
mov function, eax
End Function
Function SaveFile(byval file as string, byval dest as string, byval count as long) as long
Long fHandle
push 0
push 128
push 4
push 0
push 1
push &h40000000
push file
call CreateFile
mov fHandle,eax
Function = fHandle
push 0
lea eax,sys_count
push eax
push count
push Dest
push fHandle
call WriteFile
push fHandle
call CloseHandle
End Function
Function LoadFile(byval file as string, byref pdest as string,byval count as long) as long
pdest=nuls count
long dest=*pdest
Long fHandle
push 0
push 128
push 4
push 0
push 1
push &h80000000
push file
call CreateFile
mov fHandle,eax
Function = fHandle
push 0
lea eax,sys_count
push eax
push count
push Dest
push fHandle
call ReadFile
push fHandle
call CloseHandle
End Function
string s
string m
Long a
s ="come stai" + chr(13) + chr(10)
SaveFile "Hello.txt",s,Len(s)
LoadFile "Hello.txt",m,4
print m
print hex RGB &hAA,&hBB,&hCC
Charles
PS: even if your maps are huge it is still worth loading them into memory complete - even if they are multi megabytes. Modern PCs will do this in milliseconds.
-
Peter
I configured your functions to load/save dynamic strings. They will not work correctly with byte arrays
You will still need to set indexbase 0 since the default first element is 1.
Any type may be overlayed onto the string
short map at *m
long map at *m
This includes User defined types (or even Classes).
type color byte r,g,b,a
color map at *m
...
string m
LoadFile "Hello.txt",m,8
print m
byte map at *m
indexbase 0
print map[4]
User Defined Type:
string m
LoadFile "Hello.txt",m,8
type color byte r,g,b,a
color map at *m
indexbase 0
byte a=map[1].g
print hex a 's
Does this help?
Charles
-
Hi Peter,
You need to pass the address of m: & m, with dest specified byval dest as long
then push dest instead of lea eax,dest .
My previous code was for dynamic strings rather than static arrays. The technique of using strings for data has many advantages when programs get complex.
Charles