PDA

View Full Version : A Cross platform User Preferences unit...



jasonf
13-01-2005, 04:47 PM
I noticed that there is a SDLUserPreferences.pas unit but it doesn't contain any implementation, looks like I should inherit from this and add my own code...

Is there a ready written cross platform User Preferences module which will let me Get and Set values? Something similar to GetPrivateProfile in Windows.

I'd expect it to write to /home/<user>/.<appname>/settings.cfg under Linux
and in the game directory under Windoze (or wherever)

I don'treally care where the settings go as long as the user has permissions to write there and its unique to the application.

If such a class doesn't exist, I'll write one. But I could really do with focussing my resources elsewhere.

savage
13-01-2005, 06:49 PM
I totally forgot, about SDLUserPreferences.pas, but I did write it for the purposes of cross-platform configuration settings. It should write to the registry on Windows and to an INI file on other platforms. This of course assums that FreePascal supports INI files on all of it's targets.

If you are around later tonight I can send you an example of how to use the SDLUserPreferences.pas file.

technomage
13-01-2005, 07:26 PM
just my 10pence worth, I think this should be totally ini file driven (including windoz) or an xml config file? I use an xml config file in my own applications. We ship the libXmlParser.pas with JEDI-SDL so we could use that.??

Just my thoughts. :D

jasonf
13-01-2005, 07:45 PM
Well, XML is a little too hefty for my needs, I have a few settings to save, nothing substantial and certainly nothing which would benefit from XML.

I'd be more in favour of an INI file format, with at the most a Section header and a setting name.

[Player]
Name=Jason
[Display]
Fullscreen=True
[Sound]
MusicVolume=50
SoundVolume=70
[Controls]
Left=A
Right=D
Up=W
Down=S
Fire=Space

I agree that we should leave the registry well alone. A normal user has no place looking in the registry, it's too dangerous. A settings file is easier to edit with minimal tools. The registry is for O/S stuff in my book, no applications should store anything in there.

An ini file should be easier to make cross platform too.

Keep it simple :wink:

savage
13-01-2005, 10:08 PM
If you inherit from TRegistryUserPreferences which is found in registryuserpreferences.pas, by default it will write all info to INI files. If you define a compiler directive of REG then it will try and write to the Registry.

The machine that contains the example I was hoping to send you, is refusing to start up right now, so I will have to send it to you later.

savage
13-01-2005, 11:37 PM
FYI, Here is the User preferences file that I am using for the JEDI-SDL port of Siege of Avalon.

unit SoAPreferences;

interface

uses
registryuserpreferences;

type
TSoAUserPreferences = class( TRegistryUserPreferences )
private

protected
function GetSection( const Index : Integer ) : string; override;
function GetIdentifier( const Index : Integer ) : string; override;
function GetDefaultBoolean( const Index : Integer ) : Boolean; override;
function GetDefaultDateTime( const Index : Integer ) : TDateTime; override;
function GetDefaultInteger( const Index : Integer ) : Integer; override;
function GetDefaultFloat( const Index : Integer ) : single; override;
function GetDefaultString( const Index : Integer ) : string; override;
public
constructor Create( const FileName : string = '' ); reintroduce;
property ShadowsOn : Boolean index 0 read GetBoolean write SetBoolean;
property ScreenWidth : Integer index 1 read GetInteger write SetInteger;
property ScreenHeight : Integer index 2 read GetInteger write SetInteger;
property ScreenBPP : Integer index 3 read GetInteger write SetInteger;
property FullScreen: Boolean index 4 read GetBoolean write SetBoolean;
property ArtPath : string index 5 read GetString write SetString;
property TilePath : string index 6 read GetString write SetString;
property SoundPath : string index 7 read GetString write SetString;
property ItemDB : string index 8 read GetString write SetString;
property XRefDB : string index 9 read GetString write SetString;
property TitlesDB : string index 10 read GetString write SetString;
property InterfacePath : string index 11 read GetString write SetString;
property LanguagePath : string index 12 read GetString write SetString;
property OpeningMovie : string index 13 read GetString write SetString;
property ClosingMovie : string index 14 read GetString write SetString;
property JournalFont: Integer index 15 read GetInteger write SetInteger;
property SoundVolume : Integer index 16 read GetInteger write SetInteger;
property MusicVolume : Integer index 17 read GetInteger write SetInteger;

end;


implementation

uses
SysUtils,
IniFiles;

// Enumerated type for easier identification of case statements. This order must match the index order of the class property to function properly
type
TGameSettingType = (
gsShadowsOn,
gsScreenWidth,
gsScreenHeight,
gsScreenBPP,
gsFullScreen,
gsArtPath,
gsTilePath,
gsSoundPath,
gsItemDB,
gsXRefDB,
gsTitlesDB,
gsInterfacePath,
gsLanguagePath,
gsOpeningMovie,
gsClosingMovie,
gsJournalFont,
gsSoundVolume,
gsMusicVolume );

{ TGameRegistryUserPreferences }
constructor TSoAUserPreferences.Create(const FileName: string);
var
defFileName : string;
begin
AutoSave := false;
if FileName <> '' then
defFileName := FileName
else
defFileName := ExtractFilePath( ParamStr( 0 ) ) + 'Siege.ini';

Registry := TIniFile.Create( defFileName );
end;

function TSoAUserPreferences.GetDefaultBoolean( const Index: Integer ): Boolean;
begin
case TGameSettingType( Index ) of
gsShadowsOn : Result := true;
gsFullScreen : Result := false;
else
result := false;
end;
end;

function TSoAUserPreferences.GetDefaultDateTime( const Index: Integer ): TDateTime;
begin
result := Now;
end;

function TSoAUserPreferences.GetDefaultFloat( const Index: Integer ): single;
begin
case Index of
0 : Result := 0.0;
1 : Result := 0.0;
else
result := 0.0;
end;
end;

function TSoAUserPreferences.GetDefaultInteger( const Index: Integer ): Integer;
begin
case TGameSettingType( Index ) of
gsScreenWidth : Result := 800;
gsScreenHeight : Result := 600;
gsScreenBPP : Result := 16;
gsJournalFont : Result := 0;
gsSoundVolume : Result := 0;
gsMusicVolume : Result := 0;
else
result := 0;
end;
end;

function TSoAUserPreferences.GetDefaultString( const Index: Integer ): string;
begin
case TGameSettingType( Index ) of
gsArtPath : Result := 'ArtLib/Resources/';
gsTilePath : Result := 'ArtLib/Tiles/';
gsSoundPath : Result := 'ArtLib/Resources/Audio/';
gsItemDB : Result := 'ArtLib/Resources/Database/Items.DB';
gsXRefDB : Result := 'ArtLib/Resources/Database/xref.db';
gsTitlesDB : Result := 'ArtLib/Resources/Database/Title.db';
gsInterfacePath : Result := 'Interface/';
gsLanguagePath : Result := 'english/';
gsOpeningMovie : Result := 'english/';
gsClosingMovie : Result := 'english/';
else
result := '';
end;
end;

function TSoAUserPreferences.GetIdentifier( const Index : Integer ) : string;
begin
case TGameSettingType( Index ) of
gsShadowsOn : Result := 'Shadows';
gsScreenWidth : Result := 'ScreenWidth';
gsScreenHeight : Result := 'ScreenHeight';
gsScreenBPP : Result := 'ScreenBPP';
gsFullScreen : Result := 'FullScreen';
gsArtPath : Result := 'ArtPath';
gsTilePath : Result := 'TilePath';
gsSoundPath : Result := 'SoundPath';
gsItemDB : Result := 'ItemDB';
gsXRefDB : Result := 'XRefDB';
gsTitlesDB : Result := 'TitlesDB';
gsInterfacePath : Result := 'Interface';
gsLanguagePath : Result := 'LanguagePath';
gsOpeningMovie : Result := 'Open.mpeg';
gsClosingMovie : Result := 'Closing.mpeg';
gsJournalFont : Result := 'JournalFont';
gsSoundVolume : Result := 'SoundVolume';
gsMusicVolume : Result := 'MusicVolume';
else
result := '';
end;
end;

function TSoAUserPreferences.GetSection( const Index : Integer ) : string;
begin
case TGameSettingType( Index ) of
gsShadowsOn..gsMusicVolume : Result := 'Settings';
//gsPlayerEmail..gsPlayerHighScore : Result := 'PlayerInfo';
else
result := '';
end;
end;

end.

technomage
13-01-2005, 11:37 PM
Thinking about it , if Free Pascal doesn't have ini support for all platforms, we could use TStringList to implement something, it has the Values property which parses a b=B format string. All we could need to implement issearching for the [header].. just a thought. :D

marcov
14-01-2005, 09:26 AM
Thinking about it , if Free Pascal doesn't have ini support for all platforms, we could use TStringList to implement something, it has the Values property which parses a b=B format string. All we could need to implement issearching for the [header].. just a thought. :D

FPC has had .ini support for all OSes since the previous century

Lightning
14-01-2005, 09:38 AM
XML support too, Lazarus uses XML.