I have added a direct call function that will call an address and push the parameters to support it. It assumes STDCALL. I have slightly altered the "dll" call function so that it passes integer data by its value and added a "ptr" function for when a value needs to be an address. I have added a browse dialog for getting a directory path which allows you to either select a directory or create a new one.
The "fhexout" file function seems to be working correctly. I have a rough utiliy that converts a normal binary file to the notation supported by the script but I need to finish it off before I include it.
[attachment deleted by admin]
Hutch,
Very nice. :U
Attached is a script (and accompanying library) showcasing the new external call capability. Just something I threw together.
Regards,
Tim
[attachment deleted by admin]
Tim,
This is a masterpiece. :U
Here is the tool for coverting any file to a SE script file so it can be written back to disk as a binary file.
[attachment deleted by admin]
Here is a quick example simulating a structure.
INTEGER &prct
INTEGER rct_left
INTEGER rct_top
INTEGER rct_right
INTEGER rct_bottom
INTEGER void
INTEGER GetWindowRect
INTEGER hUser
INTEGER hDsk
&prct = ptr rct_left
hUser = dll "kernel32" "LoadLibraryA" "user32"
GetWindowRect = dll "kernel32" "GetProcAddress" hUser "GetWindowRect"
hDsk = dll "user32" "GetDesktopWindow"
void = calladdr GetWindowRect hDsk &prct
num2str rct_right $1
msgbox "Screen Width" $1 MB_OK
num2str rct_bottom $1
msgbox "Screen Height" $1 MB_OK
void = dll "kernel32" "FreeLibrary" hLib
end
Hutch,
The file2se tool provokes the evil thoughts in my mind. :8) I can see from the structure simulation example you posted that declarations are allocated continguously. Is this guaranteed? Any words to offer on the thread-safety of operations within the script? It appears that the execution is strictly synchronous as it stands.
Also, how soon till your parser is capable of pulling auxillary script files into the "main script file"? :green :lol :green2
I'm hooked. I'm already considering shell integration here. :eek
The spice must flow,
Tim
Tim,
The data naming always allocates the variable sequentially and the data is 4 byte aligned. This is done in the preprocessor stage and it is reliable. With other scripts the best it can do at the moment is the "run" command which is synchronous. I have stayed away from this at the moment as it is being developed in an EXE file. What I had in mind further along the track was to build the guts of the script engine into a DLL that could then call itself as it gives me a viable way to get return values from an external script.
What I would like to be able to do is perform large string operations in external scripts and pass back the OLE string handle which I think can be done with a DLL but I doubt it can safely be done with one EXE calling another, even with a memory mapped file between them for passing data.
The other method that I have not yet thought about much is a normal "include" preprocessor command that simply included the script at the location of the include statement which is simple enough to do.
Hutch,
Another bug:
When making a "call" just before "end" such as:
call DoSomething
end
The script wraps around to the beginning.
Keep the good work coming. I'm looking forward to the next release.
Tim
Tim,
Could you post the test piece that shows the problem as I cannot duplicate it.
goto lbl0
lbl1:
msgbox "text" "title" MB_OK
ret
lbl0:
call lbl1
end
This small script works fine.
Hutch,
I cannot duplicate it with a small script either. It seems to have something to do with the size of your instruction array. The problem originally manifested itself as a "wraparound" effect with the script and now is resulting in an access violation being thrown.
Attached is a larger version of the previous script with the audio library embedded in it (using your tool). It now accepts wav and ogg vorbis files so that you can use something with a short playback duration to test with. Btw, ASCII packs quite nicely, no?
Tim
[attachment deleted by admin]
Tim,
I ran it and the player worked but it GP faulted on exit. Just this much as a question,. is the DLL a single thread or does it start a new thread ? I will have a good look at how I calculate the instruction array size in the loaded but I don't yet know what the problem is.
Tim,
I had a play with the instructions and it now runs correctly. If you pressed cancel on the file open dialog before I put the empty string test, it would fall into the following code with no file to open and would loop back to the start..
I have tested it writing the DLL before the dialog box and I set it up so it jumps past the hex data to the end to exit and the "goto label" code seems to work OK.
With the audio dll hex data removed, this is what I have running at the moment.
INTEGER HFMOD ;handle to the fmod library
;library function pointers
INTEGER FMOD_INIT
INTEGER FMOD_CLOSE
INTEGER FMOD_STR_OPEN
INTEGER FMOD_STR_STOP
INTEGER FMOD_STR_CLOSE
INTEGER FMOD_STR_PLAY
INTEGER FMOD_STR_GETLENGTHMS
INTEGER rv ; general-purpose ret value
INTEGER hStream ; handle to an open fmod stream
INTEGER hProcess ; handle to script engine process
INTEGER stream_length ; used to hold the stream length (in milliseconds)
; ------------------------
; let's get a file to open
; ------------------------
cstr $2 "Supported Audio Files\0*.mp3;*.wav;*.ogg\0\0"
fileopen "Please select an mp3 to play ..." $2
if$ $0 = ""
goto quit
call droplib
; -----------------------------------
; load fmod and get function pointers
; -----------------------------------
HFMOD = dll "kernel32" "LoadLibraryA" "fmod"
FMOD_INIT = dll "kernel32" "GetProcAddress" HFMOD "_FSOUND_Init@12"
FMOD_CLOSE = dll "kernel32" "GetProcAddress" HFMOD "_FSOUND_Close@0"
FMOD_STR_OPEN = dll "kernel32" "GetProcAddress" HFMOD "_FSOUND_Stream_Open@16"
FMOD_STR_STOP = dll "kernel32" "GetProcAddress" HFMOD "_FSOUND_Stream_Stop@4"
FMOD_STR_CLOSE = dll "kernel32" "GetProcAddress" HFMOD "_FSOUND_Stream_Close@4"
FMOD_STR_PLAY = dll "kernel32" "GetProcAddress" HFMOD "_FSOUND_Stream_Play@8"
FMOD_STR_GETLENGTHMS = dll "kernel32" "GetProcAddress" HFMOD "_FSOUND_Stream_GetLengthMs@4"
; ---------------
; initialize fmod
; ---------------
rv = calladdr FMOD_INIT 44100 32 2
;load the file returned by "fileopen" into fmod
hStream = calladdr FMOD_STR_OPEN $0 304 0 0
if hStream == 0 ;do we have a null stream?
goto null_stream_found
;begin mp3 playback
rv = calladdr FMOD_STR_PLAY -1 hStream
;get the length of the track in milliseconds
stream_length = calladdr FMOD_STR_GETLENGTHMS hStream
;the script engine has done the work needed, so lets shrink the workingset
;then put it to sleep until the track has finished
;I would have used the script function "sleep" but it seems
;that it doesn't like script vars :(
hProcess = dll "kernel32" "GetCurrentProcess"
rv = dll "kernel32" "SetProcessWorkingSetSize" hProcess -1 -1
rv = dll "kernel32" "Sleep" stream_length
;ok the script is running again, so let's close the open stream,
;shutdown fmod, unload the library (just to be polite), and exit the script.
rv = calladdr FMOD_STR_STOP hStream
rv = calladdr FMOD_STR_CLOSE hStream
rv = calladdr FMOD_CLOSE
rv = dll "kernel32" "FreeLibrary" HFMOD
quit:
rv = dll "kernel32" "DeleteFileA" "fmod.dll"
goto theend
null_stream_found:
rv = dll "user32" "MessageBoxA" 0 "Null Stream returned!" "Uh-oh!" 0
rv = dll "kernel32" "DeleteFileA" "fmod.dll"
goto theend
droplib:
INTEGER hFile
INTEGER rv2
hFile = fcreate "fmod.dll"
[ SNIP ]
theend:
msgbox "This is the END !" "Bye" MB_OK
end
Hutch,
The dll does spawn threads (3 or 4 of them). The behavior the script was showing before (the wrap-around) was as follows:
The script would run normally until the time for the script to end came...to my surprise it popped the openfile dialog back up and when I selected a track, it began playback again...it did this several times without GP faulting. I removed the hex data and restored the script back to its original state. Later when I added the data back, it started GP faulting.
I am going to see how much data I can pack into a script and keep it functional; perhaps an asm project complete with resource script and resources for the script to build.
Tim
Tim,
There is already a size limit on how big a file can be run with the hex to disk format then it GP faults. I have not tracked this down yet.
I have just attached the main binary and a few scripts with the syntax text file. I have added the integer variable support for the "sleep" command, added a "lasterror" command that displays the last system error in a message box and I have tracked down the large file size limit, I was not allocating enough memory for the hash driven global replace.
It seems to happily write a file like win32.hlp which is 12 meg on disk and 30 meg as a script.
[attachment deleted by admin]
Tim,
Your MP3 player works very well on my machine. I tested it with a 3.2 mb mp3 file and it handled it with ease.
Paul
Hutch,
You could probably give the option of appending the script to the end of the engine and then the user could rename the engine as their exe. In action, the engine would check to see if it is carrying a script and run it if it is else it would check if there is a script specified as a tail and run it if there is else spawn an open file dialog.
Just an idea. :8)
Paul