Alright, I think this should be quite a nice addition to the scripting language
With the options variable accessible from scripting, you can do a lot of things. Controlling the music and sound volume seperately, for example. Changing the amount of traffic on the fly, or having a settings menu where you can change your Visible Depth and other options.
Note: If you just want the code files, scroll to the bottom.
If you wish to add variables (things like the $engine variable) to the scripting language, I believe there are two things that are needed:
First, the class needs to be able to be converted to a TG2Variant type. This can be done (as is the case with the engine variable) by having the class derive from TPersistent.
Something like this:
Code:
type
EngineOptions = class(TPersistent)
Second, only the published variables of the class will be accessible through scripting. This means that if we want fields to be accessible, we need to wrap them around a property, like so:
Code:
private
FPlayerName : string;
published
property PlayerName: string read FPlayerName write FPlayerName;
So if we want to add the $options variable to the scripting language, here is how we would go about doing it:
First, we need to convert the options record to a class.
So in TssUtils.pas:
Replace
Code:
var
// TssEngine Global Options
Options: record
DisplayMode: string;
Window: Boolean;
ShowFPS: Boolean;
DebugMode: Boolean;
EditorMode: Boolean;
UseLogging: Boolean;
PreferPacked: Boolean;
Dithering: Boolean;
Filtering: integer;
Antialiasing: integer;
MipMapBias: Single;
SpeakerMode: integer;
SoundVolume: integer;
MusicVolume: integer;
SoundDriver: integer;
ClrTarget: Boolean;
LockData: Boolean;
UseRadio: Boolean;
VisibleDepth: Single;
Brightness: Single;
AimColor: D3DCOLOR;
InvertMouse: Boolean;
MaxTraffic: integer;
TXLPriority: integer;
TXLMaxThreads: integer;
UseStencil: Boolean;
UseCubeMap: Boolean;
UseMultiTx: Boolean;
UseDetailTx: Boolean;
UseDynamicSurfaces: Boolean;
UsePointSprites: Boolean;
PlayerName: string;
ScriptInit: string;
end;
with
Code:
type
// Needs to be persistent to be accessible through scripting.
EngineOptions = class(TPersistent)
private
FDisplayMode : string;
FWindow : Boolean;
FShowFPS : Boolean;
FDebugMode : Boolean;
FEditorMode : Boolean;
FUseLogging : Boolean;
FPreferPacked : Boolean;
FDithering : Boolean;
FFiltering : integer;
FAntiAliasing : integer;
FMipMapBias : Single;
FSpeakerMode: integer;
FSoundVolume: integer;
FMusicVolume: integer;
FSoundDriver: integer;
FClrTarget : Boolean;
FLockData : Boolean;
FUseRadio: Boolean;
FVisibleDepth: Single;
FBrightness: Single;
FAimColor: D3DCOLOR;
FInvertMouse: Boolean;
FMaxTraffic: integer;
FTXLPriority: integer;
FTXLMaxThreads: integer;
FUseStencil : Boolean;
FUseCubeMap : Boolean;
FUseMultiTx : Boolean;
FUseDetailTx : Boolean;
FUseDynamicSurfaces : Boolean;
FUsePointSprites : Boolean;
FScriptInit: string;
FPlayerName : string;
published
property DisplayMode: string read FDisplayMode write FDisplayMode;
property Window: Boolean read FWindow write FWindow;
property ShowFPS: Boolean read FShowFPS write FShowFPS;
property DebugMode: Boolean read FDebugMode write FDebugMode;
property EditorMode: Boolean read FEditorMode write FEditorMode;
property UseLogging: Boolean read FUseLogging write FUseLogging;
property PreferPacked: Boolean read FPreferPacked write FPreferPacked;
property Dithering: Boolean read FDithering write FDithering;
property Filtering: integer read FFiltering write FFiltering;
property Antialiasing: integer read FAntiAliasing write FAntiAliasing;
property MipMapBias: Single read FMipMapBias write FMipMapBias;
property SpeakerMode: integer read FSpeakerMode write FSpeakerMode;
property SoundVolume: integer read FSoundVolume write FSoundVolume;
property MusicVolume: integer read FMusicVolume write FMusicVolume;
property SoundDriver: integer read FSoundDriver write FSoundDriver;
property ClrTarget: Boolean read FClrTarget write FClrTarget;
property LockData: Boolean read FLockData write FLockData;
property UseRadio: Boolean read FUseRadio write FUseRadio;
property VisibleDepth: Single read FVisibleDepth write FVisibleDepth;
property Brightness: Single read FBrightness write FBrightness;
property AimColor: D3DCOLOR read FAimColor write FAimColor;
property InvertMouse: Boolean read FInvertMouse write FInvertMouse;
property MaxTraffic: integer read FMaxTraffic write FMaxTraffic;
property TXLPriority: integer read FTXLPriority write FTXLPriority;
property TXLMaxThreads: integer read FTXLMaxThreads write FTXLMaxThreads;
property UseStencil: Boolean read FUseStencil write FUseStencil;
property UseCubeMap: Boolean read FUseCubeMap write FUseCubeMap;
property UseMultiTx: Boolean read FUseMultiTx write FUseMultiTx;
property UseDetailTx: Boolean read FUseDetailTx write FUseDetailTx;
property UseDynamicSurfaces: Boolean read FUseDynamicSurfaces write FUseDynamicSurfaces;
property UsePointSprites: Boolean read FUsePointSprites write FUsePointSprites;
property ScriptInit: string read FScriptInit write FScriptInit;
property PlayerName: string read FPlayerName write FPlayerName;
end;
In essence, the code above basically converts the original options record into a class, with every variable being published. This means we can read or write to every variable in the options, through scripting.
Next, we need to add a variable of this class type.
So under our var section (that contains TimerFrequency: Int64;) add in
Code:
Options : EngineOptions;
The reason we named it Options, is so that it's still compatible with existing code that references the Options variable.
So the code under var will look something like this now:
Code:
var
TimerFrequency: Int64;
Options : EngineOptions;
implementation
Now we need to instantiate the Options class, so under TssUnit.pas, we create the class before we do any work with it:
Code:
Ini:=TIniFile.Create(ExtractFilePath(ParamStr(0))+'Settings.ini');
Options := EngineOptions.Create;
Options.DisplayMode:=Ini.ReadString('Display', 'Mode', '1024x768 32bit');
And if we want to use this Options class through scripting, we now need to add it as a scripting variable.
So under TssEngine.pas:
Find
Code:
FScript.SetVariable(G2Var(Self), 'engine');
And add the Options variable after it, to become:
Code:
FScript.SetVariable(G2Var(Self), 'engine');
FScript.SetVariable(G2Var(Options), 'options');
And now you can use it through scripting, like so:
Code:
$options.MaxTraffic = 100;
To make it easier for everyone, I've attached the code files, with the changes already made. You'll need to compile the code into an exe to actually use the options variable in scripting though.