Author Topic: Hardly to read  (Read 3992 times)

0 Members and 2 Guests are viewing this topic.

Peter

  • Guest
Hardly to read
« on: February 27, 2011, 05:25:46 AM »
Deleted.
« Last Edit: May 05, 2015, 12:36:42 PM by Peter »

Charles Pegge

  • Guest
Re: Hardly to read
« Reply #1 on: February 27, 2011, 01:02:47 PM »

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

Charles Pegge

  • Guest
Re: Hardly to read
« Reply #2 on: February 27, 2011, 08:10:13 PM »
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

Code: [Select]
% 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)

Charles Pegge

  • Guest
Re: Hardly to read
« Reply #3 on: February 28, 2011, 01:15:24 AM »
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.

Code: [Select]
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
« Last Edit: February 28, 2011, 01:24:04 AM by Charles Pegge »

Charles Pegge

  • Guest
Re: Hardly to read
« Reply #4 on: February 28, 2011, 10:17:14 AM »
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
Code: [Select]

'-----------------------------------------
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

Code: [Select]
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.
« Last Edit: February 28, 2011, 10:40:01 AM by Charles Pegge »

Charles Pegge

  • Guest
Re: Hardly to read
« Reply #5 on: February 28, 2011, 06:40:26 PM »
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

...

Code: [Select]
string m
LoadFile "Hello.txt",m,8
print m
byte map at *m
indexbase 0
print map[4]

User Defined Type:
Code: [Select]
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



Charles Pegge

  • Guest
Re: Hardly to read
« Reply #6 on: March 01, 2011, 01:57:53 PM »
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