Posted by
GuShH on June 4, 2010
Heres my ping routine, It’s the weapon of choice for checking online status, update servers, or just plain pinging an IP for whatever reason happens to float your boat!
EnableExplicit
Procedure.i NetPing( IP_Address.s = "209.85.225.105", Timeout.i = 5000 ) ; Timeout in Milliseconds, Defaults to 5 seconds.
;Returns => 0 Upon pinging. Otherwise returns < 0 -- The actual return value is the roundtrip time in milliseconds.
Define.i hIcmpFile, dwRetVal = -1
Define.s DataBuffer = "PING"
Define.i ReplyBufferSize = SizeOf(ICMP_ECHO_REPLY) + Len(DataBuffer) + SizeOf(character)
Define.ICMP_ECHO_REPLY *ReplyBuffer = AllocateMemory(ReplyBufferSize)
If ( *ReplyBuffer )
hIcmpFile = IcmpCreateFile_()
If hIcmpFile
If IcmpSendEcho_( hIcmpFile, inet_addr_(IP_Address), @DataBuffer, Len(DataBuffer), #Null, *ReplyBuffer, ReplyBufferSize + SizeOf(ICMP_ECHO_REPLY), Timeout )
dwRetVal = *ReplyBuffer\RoundTripTime
EndIf
IcmpCloseHandle_( hIcmpFile )
Else
Debug "NetPing -- IcmpCreateFile returned false."
EndIf
FreeMemory( *ReplyBuffer )
Else
Debug "NetPing -- Couldn't allocate memory."
EndIf
ProcedureReturn dwRetVal
EndProcedure
Enjoy!
Posted by
GuShH on April 6, 2010
I haven’t had much time to write, so I figured I could at least share some old -yet useful- PB code in the meantime, as promised.
Quite often you’ll need to load a file right into memory or dump memory into a file, these are relatively trivial tasks but I’m sure someone will eventually benefit from the functions, so here we go:
; Be careful trying to read big files into memory, always check the available RAM is enough before doing anything crazy.
Procedure.i FileToMemory( File.s ) ; Returns memory handle if the file was properly loaded, otherwise 0.
; Sanitize filename using your own routine.
Define.i fileHandle = ReadFile( #PB_Any, File )
If IsFile(fileHandle)
Define.i fileSize = Lof(fileHandle)
If fileSize
Define.i fileBuffer = AllocateMemory( fileSize )
If fileBuffer
If ReadData( fileHandle, fileBuffer, fileSize ) = fileSize
CloseFile( fileHandle )
ProcedureReturn fileBuffer
Else
FreeMemory(fileBuffer)
EndIf
EndIf
EndIf
CloseFile(fileHandle)
EndIf
ProcedureReturn #Null
EndProcedure
Procedure.i MemoryToFile( Memory.i, File.s ) ; Returns the amount of written data in bytes, otherwise 0.
If Memory
If File ; Sanitize filename using your own routine.
Define.i MemorySize = MemorySize(Memory)
If MemorySize > 0
Define.i fileHandle = CreateFile( #PB_Any, File )
If IsFile( fileHandle )
Define.i DataWritten = WriteData( fileHandle, Memory, MemorySize )
CloseFile( fileHandle )
ProcedureReturn DataWritten
EndIf
EndIf
EndIf
EndIf
ProcedureReturn #Null
EndProcedure
Filename sanitation was not included since this is often part of a separate lib.
Quite frankly functions like these should be part of the official libraries, seeing as how often they’re used… I really do think they should focus on adding new functionality to the language — I hear a rant coming!
Well, not today. Let’s keep it simple.
Cheers!
Posted by
GuShH on September 5, 2009
This is a tool that I’ve been using for quite a long while, just recently I fixed a small bug in the regexp and I thought it was time to share it.
For those of you using the official IDE, there’s no real solution to this “problem”. When you’re working on something small, it’s not a big deal to define a couple of declares here and there… However, on bigger code this becomes a real issue!. So why waste the time switching between IDEs or doing it by hand?…
Grab it and let me know how it runs! (nasty ugly source included).
The tool is very simple to install, I recommend you unzip directly into your PB directory and configure it as follows:

That’s it. You’re ready to declar’em!.
Cheers.
Posted by
GuShH on August 28, 2009
One of the most important things a programmer has to know and learn is proper code design, structuring of the code, etc. This may not be imperative for you if you’re just starting out, but sooner or later you’ll be able to spot the patterns and realize that your current way of doing things is not optimal but rather cumbersome. This is when you start to separate things into modules and you begin to design your code with more meaning and purpose.
By breaking your code into modules or “classes” you can have a finer granularity of the code itself, you can encapsulate the base code and work on top of it, you can also reuse the code in other projects if you have a good design. An example would be a log library (for logging useful debugging information onto text files) with proper design and care you’ll be able to use the same library in almost all of your projects with little to no modification at all.
More…
Posted by
GuShH on August 27, 2009
I keep forgetting the fact that PB is retarded when it comes to the modulo operator and floating point values!.
It’s time to write our own fmod() equivalent; lucky for us the Intel guys were kind enough as to implement quite a useful instruction called FPREM a few eons ago, which pretty much means “Partial REMinder” and what it does is rather simple: it computes the partial remainder of st(0)/st(1).
Procedure.f fmod( x.f, y.f )
EnableASM
FLD DWORD[p.v_y]
FLD DWORD[p.v_x]
!NOT_READY:
FPREM
FSTSW AX
TEST AH, 100b
!JNZ NOT_READY
FSTP ST1
DisableASM
ProcedureReturn
EndProcedure
Of course with great instructions comes great limitations: in this case we cannot produce the final reminder if the difference between X and Y is bigger than 63. We can solve this by implementing a loop and checking for the C2 bit of the status word to be cleared. This is all explained in the IA32 manuals.
It’s not pretty but until fpu modulo operations are officially supported in the language, this might well be your only sane choice.