Guide To Kernel Exports

2000.06.12
author: Geoffrey M.

(c) 1999-2000 Ultratech Creations
wildfireZ is a trademark of Ultratech Creations

website: www.UltratechCreations.com

Distributed under the terms of the GNU Lesser General Public License.
See copyleft.txt for details.

 

These functions are valid for version 2.0.1 of the wildfireZ Plugins kernel DLL, for Windows 95 or higher.

 

 

standard data types
naming conventions
plugin interface
runtime parameter overloading
plugin events
kernel functions

function GetAppHandle
function GetAppInstance
procedure GetAppPath
function GetEnvironmentState
function GetFrameRate
function GetFramesRendered
function GetGameState
function GetKernelVersion
procedure GetOSPath
procedure GetOSSystemPath
function GetWFZError
procedure GetWFZPath
procedure IncFramesRendered
procedure SetWFZError
procedure SetGameState
function StartupKernel

Plugin functions

function PluginAvailable
function GetDFC
function GetPluginCount
function LoadPlugin
procedure UnloadPlugin

Buffer functions

procedure ClearWFZBuffer
function GetWFZBuffer
function GetWFZBufferContentsSize
function GetWFZBufferSize
procedure SetWFZBufferContentsSize
procedure SetWFZBufferSize

Hires-DateTime functions

function ConvertGMTToIDL
function ConvertIDLToGMT
function ConvertToLocalDateTime
function DecodeHiresDateTime
function EncodeHiresDateTime
function GetCurrentHiresDateTime
function GetIDLOffset
function GetIDLMinutesOffset
function IsLocalHiresDateTime

Elapsed Time functions

function GetElapsedTimeCount
function GetElapsedTimeFrequency
function IsElapsedTimeAvailable
function GetStartupElapsedTime
function GetStartupTime

misc functions

function GetRandomNumber

 

 

standard data types
The kernel was coded in Delphi 4 (pascal), and all required function and procedure parameters use pascal data types. Developers using C/C++, or Visual Basic may not be familiar with what native types they should in the their own IDE, so here are the equivalent ranges and storage formats.

type range format
Integer
Cardinal

Shortint
Smallint
Longint
Int64
Byte
Word
Longword
–2147483648..2147483647
0..4294967295

–128..127
–32768..32767
–2147483648..2147483647
–2^63..2^63–1
0..255
0..65535
0..4294967295

signed 32-bit
unsigned 32-bit

signed 8-bit
signed 16-bit
signed 32-bit
signed 64-bit
unsigned 8-bit
unsigned 16-bit
unsigned 32-bit

 

 

naming conventions
All wildfireZ plugins have a ".wfz" extension.

Enumerated parameter/result values should contain the initals of the driver name, followed by an underscore, followed by the enum value name. For example, the wildfireZ kernel enum value to indicate that a plugin has loaded successfully would be "WFZK_PluginLoadSuccessful".

Errors follow the same naming scheme as enum vales, but a lowercase "e" is added to indicate that this an error enum value. For example, the kernel error enum for a plugin not being found is "eWFZK_PluginNotFound ".

 

 

plugin interface
Plugins are simply standard DLLs that use object naming conventions for their functions. All plugin functions are "Dynamic Function Calls", better known as "DFCs". A "DFC" can be a property, a method (procedure or function), an event, or an internally managed object made available through the DLL interface. Kind of like ActiveX, but without the overhead or automation.

When designing the pugin interface, its' functionality should first be divided into properties, methods, events, and objects. DFCs use the Infix Caps style, in which the first letter of each word is capitalized. When in doubt, look at the kernel source. Always use appropriate object naming conventions for the DFCs, which consist of a verb followed by a noun - e.g. StartupKernel, or RenderScene.

Properties are procedures or functions should, which always "Get" or "Set..." an internal value or state - e.g. GetFramesRendered, or SetGameState. If a property is "set", it is coded as a procedure. If you "get a property, then it is coded as a function. Any property which returns a boolean value, should be called "Is...", with the verb or state following the noun.- e.g. IsPluginMuckingUp, or IsKernelStarted.

Methods are closest to standard DLL functions and can be either procedures or functions. Methods do not change or read a state/value. They purely perform some action. E.g. LoadPlugin, OpenAudioFile.

Events from DLLs are a new thing for most developers. ActiveX is one of the few DLL types that actually make use of them. WildfireZ events are named "On...", and it is recommended to use runtime function overloading to implement them. E.g. OnMouseOver, OnSpriteCollision.

Objects can be made available thru a DLLs interface. The plugin must create, free, and manage the objects internally, so that the user only has to use minimal functions to perform these tasks. Object DFCs require an index value to be passed along with any other params, this is how the plugin knows which one of the multiple objects to perform the action on. A call to the plugin's Unload or Shutdown functions should free any objects that have been created by the user.

In this example 4 player objects have their properties updated, by using an index to the player objects to alter each value.

procedure SetPlayerObjectHealth(PlayerIndex: integer; HealthValue: integer); stdcall;

var i: integer;

for i:=0 to 3 do;
begin
SetPlayerObjectHealth(i, 94);
end;

 

EXPORTS
You will need to use "WildfireZDataTypes .pas" in your project. It contains all the wfz enum and error values.

All plugins must have the following exports:

function Load(): integer; stdcall;
function Unload(): integer; stdcall;
procedure Shutdown(); stdcall;

Drivers are loaded using either of two load models: resident and dynamic. Resident plugins can only be unloaded by shutting down the kernel. All calls to UnloadPlugin will fail. Any plugin which is vital or required by many other plugins should be loaded using the resident model. Dynamic plugins can be unloaded at any time, and are typically used to perform brief tasks, such as jpeg-to-bmp, etc.

Load and Unload return an enum integer value back to the kernel indicating success or failure:

Load must return one of these values...
WFZK_PluginLoadFailed
WFZK_PluginLoadSuccessful

Unload must return one of these values...
WFZK_PluginUnloadFailed
WFZK_PluginUnloadSuccessful

If Load fails, the plugin is unloaded from memory and not added to the kernel's internal Plugins List. If Unload fails, the plugin remains loaded - but it will automatically be unloded when ShutdownKernel is called. The plugin procedure Shutdown is called by ShutdownKernel to remove any remaining plugins.

When Unload is called, the plugin should free all data structures, but not de-initialize itself. The plugin should still be on standby. It does not have to unload any plugins that it may have loaded for its' own use.

When ShutDown is called, it means that the kernel is shutting down. The plugin must free all structures that have been created by it, unload any plugins it may have loaded, and de-initialize itself.

 

 

runtime parameter overloading
Runtime overloading is optional. Instead of passing params, a pointer to a data structure is passed, and can also be returned. This allows for an almost unlimited number of Call params and Result params to be passed to/from a DFC.

DLL functions can be overloaded at runtime, by including an OverloadDef param, and passing a pointer to a Call params structure. A pointer for any Result params can be returned. OverloadDef in an integer enum value to indicate which version of the overloaded function to use. Various structures are used depending on which OverloadDef is being used.

the actual exported function
MyFunction(OverloadDef: integer; CallParams: pointer) ResultParams: pointer; stdcall;

OverloadDefs for MyPlugin - note the multiple result params:
MP_DoThis(value: integer)state1: boolean; state2: boolean; value1:integer
MP_DoThat(Value1, value2, value3: integer)value1: integer;
MP_DoSomethingElse(value: integer: text: PChar)text: PChar; value1: integer;

sample structures for MP_DoThis

type Call_MP_DoThis = record
value: integer;
end;

type Result_MP_DoThis = record;
state1: boolean;
state2: boolean;
value1:integer
end;

Example usage:
This tells the function which overload version to use, passes the params in the Call structure, and recieves the results in the Result structure. The actual internal overload routing is performed by checking the OverloadDef value and using case statements.

@Result_MP_DoThis := MyFunction(MP_DoThis, @Call_MP_DoThis);

 

 

plugin events
When implementing events, two actions must be taken into account: the ability to assign an event handler, and the ability to trigger an event handler. To trigger an event, the user should be able to simply call the event with no parameters. To assign an event handler, the handler code must pass its' proc addr to the event trigger code.

When an event is triggered, the program flow jumps to the proc addr/method pointer that was assigned to this event. If you can get a proc address, you can jump to it. Pass one of your own proc addrs, and another plugin can execute you code - that is how you code DLL events.

In this example, MyPlugin assigns one of its' internal methods (MyCustomMouseOver) as the event handler for InputPlugin's OnMouseOver event. Since we are working with dynamically loaded DLLs, MyPlugin has already retrieved the OnMouseOver ProcAddress by calling GetDFC. The event is a runtime overloaded function, so we tell it which version of the func we will be using, and pass pointers to the Call and Result parameters. The code could be simpler, by having the EventHandler porc addr passed in the original exported function, and doesn't have any Result params, but this example merely illustrates how to pass a group of parameters to a function via a structure.

 

Here is InputPlugin's exported function > OnMouseOver(OverloadDef: integer; CallParams: pointer); stdcall;

Overload enums > WFZ_AssignEvent, WFZ_TriggerEvent

Here are the Call Params and Result Params (none) for each overloaded func, which are passed as a pointer to a structure that contains these params.

WFZ_AssignEvent > (EventHandler: pointer);

WFZ_TriggerEvent > ( );

 

[MyPlugin ]

type TProc = procedure();

type TAssignEventOverload = record
EventHandlerAddr: pointer;
end;

const eMP_CannotGetEventDFC = 1;

var eventDFC : TProc;
MyHandler: TAssignEventOverload;

// get proc addr
@eventDFC := nil; // always do this to so can tell if assigned properly
@eventDFC := GetDFC(PluginHandle, PChar("OnMouseOver')); // get the proc
if @eventDFC = nil then SetError(eMP_CannotGetEventDFC);
//
// assign event handler
MyHandler.EventHandlerAddr := @MyCustomMouseOver;
eventDFC(WFZ_AssignEvent, @MyHandler);
//
// trigger event
eventDFC(WFZ_TriggerEvent, nil);

 

 

kernel functions

function GetApplicationHandle( ): LongWord; stdcall;
This returns the Application Handle, which may be required by some plugins for display of separate windows.

var hnd: longword;

inst := GetApplicationHandle;

 

function GetApplicationInstance( ): Longint; stdcall;
This returns the Application Instance which may be required by some plugins.

var inst: longint;

inst := GetApplicationInstance;

 

function GetApplicationPath( ); stdcall;
This returns the path for the currently executing main application. A final "\" is present in the path. In this example, the main application's path is retrieved from the kernel, and copied to a label's caption.

var p: PChar;

GetAppPath;
p:= GetWFZBuffer;
Label1.Caption := string(p); // "Label1.Caption := StrPas(p)" is also valid.

 

function GetEnvironmentState( ): Integer; stdcall;
This returns the current environment state for the kernel. If the kernel is offline, then all kernel functions exit with a zero result. The environment state can only be changed by restarting the kernel.

var x: integer;

x := GetEnvironmentState;
if x = esRuntime then Label1.Caption := 'Kernel environment is runtime.' ;

 

function GetFrameRate( ):Integer; stdcall;
This returns the current frame rate for the currently executing application. A single "frame" includes multiple activities, such as: scene rendering, display to the screen, audio output, etc. The current frame rate is equal to how many render events have occured divided by the number of seconds that have elapsed since the kernel started up, i.e. the average frames per second. To increment the number of frames rendered, call IncFramesRendered.

var x: integer;

x := GetFrameRate;

 

function GetFramesRendered():Integer; stdcall;
Returns the total number of frames that have been rendered since kernel startup. To increment the value, call IncFramesRendered.

var x: integer;

x := GetFramesRendered;

 

function GetGameState(): Integer; stdcall;
Returns an integer value representing the current game state.

Game state values:
gsOffline = 0;
gsStartup = 1;
gsIntro = 2;
gsDemo = 3;
gsPlaying = 4;
gsPaused = 5;
gsGameOver = 6;
gsRuntime = 7;

var x: integer;

x := GetGameState;
if x = gsDemo then Label1.Caption := ' Demo is running.' ;

 

function GetKernelVersion(): Integer; stdcall;
Returns the current version of the kernel as an integer. Version 2.0.0.0 would be returned as $02000000;

var x: integer;

x := GetKernelVersion;

 

procedure GetOSPath(); stdcall;
This returns the path for the current operating system, generally "C:\Windows\". A final "\" is present in the path. In this example, the OS path is retrieved, and copied to a label's caption. p never needs to be allocated / deallocated because we use it merely as a pointer to the buffer, this is required on order to typecast the PChar to a string.

var p: PChar;

GetOSPath;
p:= GetWFZBuffer;
Label1.Caption := string(p); // "Label1.Caption := StrPas(p)" is also valid.

 

procedure GetOSSystemPath(); stdcall;
This returns the path for the system directory of the current operating system, generally "C:\Windows\System\". A final "\" is present in the path. In this example, the OS system path is retrieved, and copied to a label's caption. p never needs to be allocated / deallocated because we use it merely as a pointer to the buffer, this is required on order to typecast the PChar to a string.

var p: PChar;

GetOSSystemPath;
p:= GetWFZBuffer;
Label1.Caption := string(p); // "Label1.Caption := StrPas(p)" is also valid.

 

function GetWFZError( ): Integer; stdcall;
This returns the most recent error code. When calling a plugin function that may cause errors, always check the value of ErrorCode to ensure that no errors have occurred.

var x: integer;

x := GetWFZError;
if x := eWFZK_NoErrors then Label1.Caption := ' No errors.' ;

 

procedure IncFramesRendered(); stdcall;
Increments the kernel's internal frame counter. Call this function after a frame has been rendered. The frames rendered value is used by the GetFrameRate and GetFramesRendered functions

var x: integer;

IncFramesRendered;
x := GetFramesRendered;

 

procedure SetWFZError(Error: Integer); stdcall;
This sets the kernel internal error code to the desired value. This is used by plugins (and the kernel) to indicate that an error has occurred while processing a function call. In this example, the SmoothPlugin sets the error code (an enumerated integer value) to indicate an error in one of SmoothPlugin's functions.

SetWFZError(eSP_NotSoSmoothError);

 

procedure SetGameState(GameState: Integer); stdcall;
Sets the game state value to GameState. In this example, game state is set to paused.

Game state values:
gsOffline
gsStartup
gsIntro
gsDemo
gsPlaying
gsPaused
gsGameOver
gsRuntime

SetGameState(gsPaused);

 

function StartupKernel(AppPath: PChar; AppInstance: Longint; AppHandle: LongWord; EnvironmentState: Integer): Pointer; stdcall;
Before plugins may be loaded, the kernel must be initialized by the main application. The main application passes its' handle, instance, and path info to the kernel. The kernel returns a pointer to the ShutdownKernel function, this ensures that only the app that started the kernel can shut it down. AppPath must include a final '\' at the end. EnvironmentState tells the kernel wheteher you would like it to be in runtime, design-time, etc. Once set, the environment state cannot be changed without shutting down and restarting the kernel.
Remember to check GetWFZError when calling this function.

At shutdown, the kernel unloads any plugins that may currently be loaded. Internally, it calls UnloadPlugin so that all loaded plugins can save any necessary data before being unloaded. All kernel functions, except StartupKernel, are disabled after shutdown and will return a zero result if called.

Environment state values:
esDesign
esOffline
esRuntime

In this example, StartupKernel is called with the required values. Environmnet state is et to esRuntime. The OS ans OS System path are retrieved and displayed in label captions. Finally, ShutdownKernel is checked to see if it contains an address, and then it is called to shutdown the kernel. Remember to set ShutdownKernel to nil, before calling StartupKernel.

type ShutdownKernel = procedure(); stdcall;

var p: pchar;

@ShutdownKernel := nil;
@ShutdownKernel := StartupKernel(PChar(ExtractFilePath(Application.EXEName)), HInstance, Application.Handle, esRuntime);
GetOSPath;
p:= GetWFZBuffer;
Label2.Caption := 'OSPath: ' + string(p);
GetOSSystemPath;
p:= GetWFZBuffer;
Label2.Caption := Label2.Caption + '...' + string(p); // display both paths on same line
Label3.Caption := 'Startup Kernel: OK.';
if @ShutdownKernel = nil then Label3.Caption:='StartupKernel: Error!'
ShutdownKernel;

 

 

Plugin functions

function PluginAvailable(PluginName: PChar): integer; stdcall;
Returns a value indicating whether PluginName is currently loaded, and if it resides in the main application's directory. PluginAvailable will not search anywhere else except the main appp's directory. PluginName does not contain path info, only the name of the plugin itself. In this example, the kernel is queried about the plugin named 'SmoothPlugin'.
Remember to check GetWFZError when calling this function.

var x: integer;

x := PluginAvailable(PChar('SmoothPlugin'));

result values:
WFZK_PluginNotFound
WFZK_PluginLoaded
WFZK_PluginOnAppPath

 

function GetDFC(PluginHandle: LongWord; DFC: PChar): Pointer; stdcall;
All plugin functions are dynamically loaded, so your plugin must query for the proc address of any other plugin functions it requires. PluginHandle is a handle to the plugin, previously returned by a call to LoadPlugin. DFC is the name of the desired plugin function.
Remember to check GetWFZError when calling this function. In this example, a plugin is loaded, and its' handle is used to get the DFC "DisplayAnimationSplash" . Finally, the plugin is unloaded.

var PluginHandle: longword;
DFCAddr: pointer;

PluginHandle := LoadPlugin(PChar("C:\Program Files\wildfireZ\SmoothPlugin.wfz'), WFZK_DynamicPlugin);
DFCAddr := GetDFC(PluginHandle, PChar('DisplaySplashAnimation'));
UnloadPlugin(PChar('SmoothPlugin'));

 

function GetPluginCount(): Integer; stdcall;
Returns the number of plugins currently loaded.

var x: integer;

x := GetPluginCount;

 

function LoadPlugin(PluginName: PChar; LoadModel: Integer): LongWord; stdcall;
This function loads and initializes the named plugin and returns a handle for that plugin. Plugin name must include the path information for the location of the plugin. Duplicate plugin names are not allowed. In the event that the plugin to be loaded has the same name as an already loaded plugin, the new plugin will not be loaded and an error will occur. Plugins have two different load models: Resident model is for plugins needed for the entire time the kernel is active, and can only be unloaded at kernel shutdown. Attempting to unload a resident plugin with UnloadPlugin will result in an error. Dynamic model is for plugins that are only needed temporarily, and they can be unloaded at any time by calling UnloadPlugin.
Remember to check GetWFZError when calling this function.

var PluginHandle: longword;

PluginHandle := LoadPlugin(PChar("C:\Program Files\wildfireZ\SmoothPlugin.wfz'), WFZK_DynamicPlugin);

 

procedure UnloadPlugin(PluginName: PChar); stdcall;
Unloads a plugin which is currently loaded. PluginName is a the name of the plugin without the path info. Plugins have two different load models: Resident model is for plugins needed for the entire time the kernel is active, and can only be unloaded at kernel shutdown. Attempting to unload a resident plugin with UnloadPlugin will result in an error. Dynamic model is for plugins that are only needed temporarily, and they can be unloaded at any time by calling UnloadPlugin.
Remember to check GetWFZError when calling this function.

UnloadPlugin(PChar('SmoothPlugin'));

 

 

 

 

Buffer functions
Generally, when working with PChars, the calling functions must query for the length of the PChar, and then be responsible for allocating and deallocating memory for the PChar. The wildfireZ plugins kernel provides an easy way to move PChars to/from functions, by using a buffer dedicated solely for this purpose. The buffer exists once StartupKernel is called, and is automatically freed at kernel shutdown.

Call GetWFZBuffer to get a pointer to the block of memory used by the buffer. You are still responsible for copying the PChar to/from the buffer, but memory management is no longer a concern. If a PChar is larger than 8192 bytes, you will need to adjust the size of the buffer using the provided functions. Afterwards, you should reset the buffer back to it's default size by calling ClearWFZBuffer. The length of the PChar is stored by calling SetWFZBufferContentsSize, because the length of the PChar and the length of the buffer are rarely the same.

CAVEATS: The PChar copied to the buffer must have a null char at the end. The length of the PChar stored with SetWFZBufferContentsSize must be equal to the length plus the null char at the end - i.e. length+1.

 

procedure ClearWFZBuffer(); stdcall;
Resets the buffer's size to 8192 bytes and zeroes out the entire block of memory.

ClearWFZBuffer;

 

function GetWFZBuffer(): Pointer; stdcall;
Returns a pointer to the block of memory used by the buffer. Use this value as the PChar pointer value when reading and writing PChars. The PChar copied to the buffer must have a null char at the end. The length of the PChar stored with SetWFZBufferContentsSize must be equal to the length plus the null char at the end - i.e. length+1. In this example, the main application's path is retrieved from the kernel, and copied to a label's caption.

var p: PChar;

GetAppPath;
p:= GetWFZBuffer;
Label1.Caption := string(p); // "Label1.Caption := StrPas(p)" is also valid.

 

function GetWFZBufferContentsSize(): integer; stdcall;
Returns the current size of the PChar (including the null char at the end) residing in the WFZ buffer. The default size of the buffer is 8192 bytes, so any PChar smaller than this must have its' length stored by calling SetWFZBufferContentsSize. In this example, the size value of the PChar residing in the buffer is converted to a string and added to a label's caption.

var x: integer;

x := GetWFZBufferContentsSize;
Label1.Caption := IntToStr(x);

 

function GetWFZBufferSize(): integer; stdcall;
Returns the current size of the WFZ buffer in bytes, which will never be smaller than 8192 bytes. In this example, the buffer size value is converted to a string and added to a label's caption.

var x: integer;

x := GetWFZBufferSize;
Label1.Caption := IntToStr(x);

 

procedure SetWFZBufferContentsSize(Size: integer); stdcall;
Used to store the length value of a PChar that resides in the WFZ buffer. In this example, a string is copied to the buffer, and the length of the string is stored using SetWFZBufferContentsSize. The PChar copied to the buffer must have a null char at the end. The length of the PChar stored with SetWFZBufferContentsSize must be equal to the length plus the null char at the end - i.e. length+1.

var text: string;

text := ' Want to rule the world? Take a number. There's a really long line. ' ;
ClearWFZBuffer;
StrPCopy(GetWFZBuffer, text); // copies string to buffer and adds a null char at end
SetWFZBufferContentsSize(Length(text) +1 ); // the null char MUST ALWAYS be included in the length !!!

 

procedure SetWFZBufferSize(Size: integer); stdcall;
Resizes the WFZ buffer to a length of Size bytes. Size must be an integer value greater than 8192 bytes, because the buffer cannot be set to a size smaller than 8192 bytes. If a function must set the buffer to a larger size, it should reset the size after it is finished using the buffer, by calling ClearWFZBuffer. This example sets the buffer to 86000 bytes and then resets it back to its' standard buffer size.

SetWFZBuffer(86000);
...
... // perform various functions
...
ClearWFZBuffer;

 

 

Hires-DateTime functions
Ever received an email from the future? You know, the ones that have time stamps a few hours ahead of your local time.

The HiresDateTime structure was designed to work around this flaw, by incorporating local time zone info into itself. This allows a HiresDateTime value to be easily converted to your local time and date. For example, if you receive a file with a time stamp of 8:04 AM and the sender is 3 hours ahead of your time zone, that time would be converted to 5:04 AM - the equivalent local time when the file was created. More info on the HiresDateTime structure can be found here.

The HiresDateTime structure is based on a 24 clock originating at the International Date Line (IDL), unlike Greenwich Mean Time (GMT), which is based on a 12 hour clock. The GMT was somewhat mucky to covert to/from, so IDL was used instead. NOTE: All time zone information must be converted from GMT to IDL before adding it to the HiresDateTime structure. More info on IDL time zones can be found here.

 

function ConvertGMTToIDL(GMTOffset: Integer): Integer; stdcall;
Converts a +/- 12 hour based GMT time zone offset to a 24 hour (aka military time) IDL time zone offset.

var timeGMT, timeIDL: integer;

timeIDL := ConvertGMTToIDL(timeGMT);

 

function ConvertIDLToGMT(IDLOffset: Integer): Integer; stdcall;
Converts a 24 hour (aka military time) IDL time zone offset to a +/- 12 hour based GMT time zone offset.

var timeGMT, timeIDL: integer;

timeGMT := ConvertIDLToGMT(timeIDL);

 

function ConvertToLocalDateTime(UDT: TUnpackedHiresDateTime): TUnpackedHiresDateTime; stdcall;
Converts a given date and time to the local time zone equivalent date and time. Useful for finding out when something was created, relative to your own local time. Example: if a file was created at 6:15 PM in a time zone 2 hours behind your current one, then the file would have been created at 8:15 PM your time - (6:15 pm plus 2 hour difference between time zones). The HiresDateTime structure returned will have an IDL/IDL minutes offset equal to the current system offsets.

var UDT, LocalUDT: TUnpackedHiresDateTime;

LocalUDT := Convert ToLocalDatTime(UDT);

 

function DecodeHiresDateTime(HiresDateTime: THiresDateTime): TUnpackedHiresDateTime; stdcall;
Uncompresses a packed HiresdateTime structure into an easier to manipulate TUnpackedHiresDateTime structure.
More info TUnpackedHiresDateTime data fields can be found here.

var UHDT: TUnpackedHiresDateTime;
HDT: THiresDateTime;

UHDT := DecodeHiresDateTime(HDT);

 

function EncodeHiresDateTime(UnpackedDateTime: TUnpackedHiresDateTime): THiresDateTime; stdcall;
Compresses a TUnpackedHiresDateTIme data structure into a compact 96-bit value. NOTE: All time zone information must be converted from GMT to IDL before adding it to the HiresDateTime structure.
Remember to check GetWFZError when calling this function.

var UHDT: TUnpackedHiresDateTime;
HDT: THiresDateTime;

HDT := EncodeHiresDateTime(UHDT);

 

function GetCurrentHiresDateTime( ): TUnpackedHiresDateTime; stdcall;
Returns the current hi-resolution date and time for the local system. In this example, the current HiresDateTime is retreived, and the individual fields within it are converted to strings and added to a listbox.

varTempUDT: TUnpackedHiresDateTime;
ListBox1: TListBox;

TempUDT := GetCurrentHiresDateTime;
ListBox1.Items.Add('Year: '+IntToStr(TempUDT.Year));
ListBox1.Items.Add('Month: '+IntToStr(TempUDT.Month));
ListBox1.Items.Add('Day: '+IntToStr(TempUDT.Day));
ListBox1.Items.Add('GMTOffset: '+IntToStr(TempUDT.IDLOffset));
ListBox1.Items.Add('GMTMinutesOffset: '+IntToStr(TempUDT.IDLMinutesOffset));
case TempUDT.DayOfWeek of
1: ListBox1.Items.Add('DayOfWeek: Sunday');
2: ListBox1.Items.Add('DayOfWeek: Monday');
3: ListBox1.Items.Add('DayOfWeek: Tuesday');
4: ListBox1.Items.Add('DayOfWeek: Wednesday');
5: ListBox1.Items.Add('DayOfWeek: Thursday');
6: ListBox1.Items.Add('DayOfWeek: Friday');
7: ListBox1.Items.Add('DayOfWeek: Saturday');
end;
ListBox1.Items.Add('Hour: '+IntToStr(TempUDT.Hour));
ListBox1.Items.Add('Minute: '+IntToStr(TempUDT.Minute));
ListBox1.Items.Add('Second: '+IntToStr(TempUDT.Second));
ListBox1.Items.Add('Tick: '+IntToStr(TempUDT.Tick));

 

function GetIDLOffset( ): Integer; stdcall;
Returns the IDL time zone offset for this system. Always a value between 1and 24, and is equivalent to the time zone in which the local system resides.
More info on IDL time zones can be found here.

var offset: integer;

offset := GetIDLOffset;

 

function GetIDLMinutesOffset( ): Integer; stdcall;
Returns the IDL minutes offset for this system. Usually zero except for a few territories, which may have a time zone offset of 15 or 30 minutes.

var minutes: integer;

minutes := GetIDLMinutesOffset;

 

function IsLocalHiresDateTime(HiresDateTime: THiresDateTime): Boolean; stdcall;
Fast method to determine if a compressed HiresDateTime structure has the same time zone information as the current local system, i.e. both are in the same time zone. There is no need to uncompress the HiresDateTime structure, this function works directly on the compressed structure by checking individual bits. Returns True if both are in the same time zone, and False if they are different time zones.

var HDT: THiresDateTime;
State: Boolean;

State := IsLocalHiresDateTime(HDT);

 

 

Elapsed Time functions
An elapsed time counter is used instead of a Window's timer, because the Window's timer is to slow for demanding applications, such as games. Instead, an elapsed time counter is used, which has a time resolution of around .5 - 1 microseconds on a 233 MHz Pentium system, whereas the internal Window's timer has a resolution of about 50 milliseconds. The elapsed time counter does not trigger an event that plugins or the main application can respond to. The value must be queried and then compared to perevious values to determine if enough time has passed to perform the next action, such as animating a frame of animation.

 

function GetElapsedTimeCount( ): Int64; stdcall;
This returns the current value for the Windows high frequency counter. This value can be compared to a previously retrieved count value in order to determine how much time has elapsed between the two counts. Divide by the elapsed time frequency for this particular system to determine how many seconds have passed. In the example, x will contain the number of seconds that have passed since time1 was called.

var x, time1, time2: int64;

time1 := GetElapsedTimeCount;
time2 := GetElapsedTimeCount;
x := (time2 - time1) DIV GetElapsedTimeFrequency;

 

function GetElapsedTimeFrequency( ): Int64; stdcall;
This returns the elapsed time frequency, the number of count ticks that occur per second, for this particular system. For a Pentium 233 MHz system, the average tick count is around 1-2 MHz. Divide this value into the various elapsed time values to convert to seconds.

var x: int64;

x := GetElapsedTimeFrequency;

 

function IsElapsedTimeAvailable( ): Boolean; stdcall;
This returns a boolean value indicating whether or not the elapsed time counter is available on this particular system. True indicates that it is available, False means that it is not available.

var State: Boolean;

State := IsElapsedTimeAvailable;

 

function GetStartupElapsedTime( ): Int64; stdcall;
This returns the number of ticks of the Windows high frequency counter that have occurred since the kernel was started. i.e. how long the kernel has been active. In the example, x will contain the number of seconds that have passed since the kernel was started, by dividing the elapsed time value by the count frequency. X will be a whole number, to get the fractional remainder, use MOD instead of DIV.

var x: int64;

x := GetStartupElapsedTime DIV GetElapsedTimeFrequency;

 

function GetStartupTime( ): Int64; stdcall;
When the kernel is started, it gets the current value from the Windows high frequency counter. This function returns that tick count.

var x: int64;

x := GetStartupTime;

 

 

misc functions

function GetRandomNumber(Range: Integer): Integer; stdcall;
Generates a random 32-bit number within the range of 0 and Range-1. Range must be a value greater than 1, or the function will return a value of zero. In the example, x will contain a value in the range of 0-12344.

var x: integer;

x := GenerateRandomNumber(12345);