From 329e2b8eabd0f4ecb6e6a9bdc66d595c988d399a Mon Sep 17 00:00:00 2001 From: tobigun Date: Thu, 17 Jul 2008 16:46:58 +0000 Subject: - UPlatformXYZ.pas clean-up - TPlatform now implements common behaviour - added TPlatform.Init() git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1207 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UMain.pas | 7 +- Game/Code/Classes/UPlatform.pas | 100 ++++++++++++----- Game/Code/Classes/UPlatformLinux.pas | 54 ++------- Game/Code/Classes/UPlatformMacOSX.pas | 175 ++++++++++++++++++++---------- Game/Code/Classes/UPlatformWindows.pas | 51 +++------ Game/Code/MacOSX/Wrapper/UMacResources.pp | 1 - 6 files changed, 216 insertions(+), 172 deletions(-) delete mode 100644 Game/Code/MacOSX/Wrapper/UMacResources.pp (limited to 'Game/Code') diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index a0bdbb94..768917ca 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -152,13 +152,12 @@ procedure Main; var WndTitle: string; begin -{$IFDEF DARWIN} - UMacResources.init; -{$ENDIF} try WndTitle := USDXVersionStr; - if Platform.TerminateIfAlreadyRunning( {var} WndTitle) then + Platform.Init; + + if Platform.TerminateIfAlreadyRunning(WndTitle) then Exit; // fix floating-point exceptions (FPE) diff --git a/Game/Code/Classes/UPlatform.pas b/Game/Code/Classes/UPlatform.pas index 2c0fc6ee..f75e5858 100644 --- a/Game/Code/Classes/UPlatform.pas +++ b/Game/Code/Classes/UPlatform.pas @@ -16,26 +16,26 @@ interface uses Classes; type - TDirectoryEntry = Record - Name : WideString; - IsDirectory : boolean; - IsFile : boolean; - end; - + TDirectoryEntry = record + Name : WideString; + IsDirectory : boolean; + IsFile : boolean; + end; + TDirectoryEntryArray = array of TDirectoryEntry; - - IPlatform = interface - ['{63A5EBC3-3F4D-4F23-8DFB-B5165FCA23DF}'] - function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : boolean) : TDirectoryEntryArray; - function TerminateIfAlreadyRunning(var WndTitle : string) : boolean; - function FindSongFile(Dir, Mask: WideString): WideString; - procedure Halt; - function GetLogPath : WideString; - function GetGameSharedPath : WideString; - function GetGameUserPath : WideString; + + TPlatform = class + procedure Init; virtual; + function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; virtual; abstract; + function TerminateIfAlreadyRunning(var WndTitle : string): boolean; virtual; + function FindSongFile(Dir, Mask: WideString): WideString; virtual; + procedure Halt; virtual; + function GetLogPath : WideString; virtual; abstract; + function GetGameSharedPath : WideString; virtual; abstract; + function GetGameUserPath : WideString; virtual; abstract; end; - function Platform : IPlatform; + function Platform(): TPlatform; implementation @@ -56,25 +56,65 @@ uses // so that this variable can NOT be overwritten from anywhere else in the application. // the accessor function platform, emulates all previous calls to work the same way. var - Platform_singleton : IPlatform; + Platform_singleton : TPlatform; + +function Platform : TPlatform; +begin + Result := Platform_singleton; +end; + +(** + * Default Init() implementation + *) +procedure TPlatform.Init; +begin +end; -function Platform : IPlatform; +(** + * Default Halt() implementation + *) +procedure TPlatform.Halt; begin - result := Platform_singleton; + // Note: Application.terminate is NOT the same + System.Halt; +end; + +(** + * Default TerminateIfAlreadyRunning() implementation + *) +function TPlatform.TerminateIfAlreadyRunning(var WndTitle : string): Boolean; +begin + Result := false; +end; + +(** + * Default FindSongFile() implementation + *) +function TPlatform.FindSongFile(Dir, Mask: WideString): WideString; +var + SR: TSearchRec; // for parsing song directory +begin + Result := ''; + if SysUtils.FindFirst(Dir + Mask, faDirectory, SR) = 0 then + begin + Result := SR.Name; + end; + SysUtils.FindClose(SR); end; initialization - {$IFDEF MSWINDOWS} - Platform_singleton := TPlatformWindows.Create; - {$ENDIF} - {$IFDEF LINUX} - Platform_singleton := TPlatformLinux.Create; - {$ENDIF} - {$IFDEF DARWIN} - Platform_singleton := TPlatformMacOSX.Create; - {$ENDIF} +{$IFDEF MSWINDOWS} + Platform_singleton := TPlatformWindows.Create; +{$ENDIF} +{$IFDEF LINUX} + Platform_singleton := TPlatformLinux.Create; +{$ENDIF} +{$IFDEF DARWIN} + Platform_singleton := TPlatformMacOSX.Create; +{$ENDIF} finalization - Platform_singleton := nil; + Platform_singleton.Free; + end. diff --git a/Game/Code/Classes/UPlatformLinux.pas b/Game/Code/Classes/UPlatformLinux.pas index f9b83f2c..7e9cac23 100644 --- a/Game/Code/Classes/UPlatformLinux.pas +++ b/Game/Code/Classes/UPlatformLinux.pas @@ -14,20 +14,15 @@ uses UConfig; type - - TPlatformLinux = class(TInterfacedObject, IPlatform) + TPlatformLinux = class(TPlatform) private function GetHomeDir(): string; public - function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; - function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; - function FindSongFile(Dir, Mask: widestring): widestring; - - procedure Halt; + function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray; override; - function GetLogPath : WideString; - function GetGameSharedPath : WideString; - function GetGameUserPath : WideString; + function GetLogPath : WideString; override; + function GetGameSharedPath : WideString; override; + function GetGameUserPath : WideString; override; end; implementation @@ -41,9 +36,9 @@ uses SysUtils, ULog; -function TPlatformLinux.DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; +function TPlatformLinux.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: Boolean): TDirectoryEntryArray; var - i : Integer; + i: Integer; TheDir : pDir; ADirent : pDirent; Entry : Longint; @@ -84,7 +79,7 @@ begin end; end; -function TPlatformLinux.GetLogPath : WideString; +function TPlatformLinux.GetLogPath: WideString; begin if FindCmdLineSwitch( cUseLocalPaths ) then begin @@ -99,10 +94,11 @@ begin {$ENDIF} end; - forcedirectories( result ); + // create non-existing directories + ForceDirectories(Result); end; -function TPlatformLinux.GetGameSharedPath : WideString; +function TPlatformLinux.GetGameSharedPath: WideString; begin if FindCmdLineSwitch( cUseLocalPaths ) then Result := ExtractFilePath(ParamStr(0)) @@ -161,32 +157,4 @@ begin {$IFEND} end; -// FIXME: Maybe this should be TPlatformBase.Halt() for all platforms -procedure TPlatformLinux.Halt; -begin - System.Halt; -end; - -function TPlatformLinux.TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; -begin - // Linux does not check for running apps at the moment - Result := false; -end; - -// FIXME: just a dirty-fix to make the linux build work again. -// This i the same as the corresponding function for windows -// (and MacOSX?). -// Maybe this should be TPlatformBase.FindSongFile() -function TPlatformLinux.FindSongFile(Dir, Mask: widestring): widestring; -var - SR: TSearchRec; // for parsing song directory -begin - Result := ''; - if SysUtils.FindFirst(Dir + Mask, faDirectory, SR) = 0 then - begin - Result := SR.Name; - end; // if - SysUtils.FindClose(SR); -end; - end. diff --git a/Game/Code/Classes/UPlatformMacOSX.pas b/Game/Code/Classes/UPlatformMacOSX.pas index b6ced926..223908d4 100644 --- a/Game/Code/Classes/UPlatformMacOSX.pas +++ b/Game/Code/Classes/UPlatformMacOSX.pas @@ -44,30 +44,110 @@ interface {$I switches.inc} -uses Classes, UPlatform; +uses + Classes, + UPlatform; type - - TPlatformMacOSX = class(TInterfacedObject, IPlatform) - public - function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : boolean) : TDirectoryEntryArray; - function TerminateIfAlreadyRunning(var WndTitle : string) : boolean; - procedure Halt(); - function GetLogPath : WideString; - function GetGameSharedPath : WideString; - function GetGameUserPath : WideString; - function FindSongFile(Dir, Mask: WideString): WideString; + TPlatformMacOSX = class(TPlatform) + private + function GetBundlePath: WideString; + function GetApplicationSupportPath: WideString; + procedure CreateUserFolders(); + public + procedure Init; override; + + function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; override; + + function GetLogPath : WideString; override; + function GetGameSharedPath : WideString; override; + function GetGameUserPath : WideString; override; end; implementation -uses SysUtils, baseunix; +uses + SysUtils, + baseunix; + +procedure TPlatformMacOSX.Init; +begin + CreateUserFolders(); +end; + +procedure TPlatformMacOSX.CreateUserFolders(); +var + RelativePath, BaseDir, OldBaseDir: string; + SearchInfo: TSearchRec; + DirectoryList, FileList: TStringList; + DirectoryIsFinished: longint; + counter: longint; + + UserPathName: string; + SourceFile, TargetFile: TFileStream; + FileCopyBuffer: array [1..4096] of byte; + NumberOfBytes: integer; +const + PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources'; +begin + getdir (0, OldBaseDir); + BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents/Resources'; + chdir (BaseDir); + UserPathName := GetEnvironmentVariable('HOME') + PathName; + + DirectoryIsFinished := 0; + DirectoryList := TStringList.Create(); + FileList := TStringList.Create(); + DirectoryList.Add('.'); + repeat + RelativePath := DirectoryList[DirectoryIsFinished]; + chdir (BaseDir + '/' + RelativePath); + if (FindFirst('*', faAnyFile, SearchInfo) = 0) then + begin + repeat + if DirectoryExists(SearchInfo.Name) then + begin + if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then + DirectoryList.Add(RelativePath + '/' + SearchInfo.Name); + end + else + Filelist.Add(RelativePath + '/' + SearchInfo.Name); + until (FindNext(SearchInfo) <> 0); + end; + FindClose(SearchInfo); + DirectoryIsFinished := succ(DirectoryIsFinished); + until (DirectoryIsFinished = DirectoryList.Count); + + if not DirectoryExists(UserPathName) then + mkdir (UserPathName); + + for counter := 0 to DirectoryList.Count-1 do + if not DirectoryExists(UserPathName + '/' + DirectoryList[counter]) then + mkdir (UserPathName + '/' + DirectoryList[counter]); + DirectoryList.Free(); + + for counter := 0 to Filelist.Count-1 do + if not FileExists(UserPathName + '/' + Filelist[counter]) then + begin + SourceFile := TFileStream.Create(BaseDir + '/' + Filelist[counter], fmOpenRead); + TargetFile := TFileStream.Create(UserPathName + '/' + Filelist[counter], fmCreate); + repeat + NumberOfBytes := SourceFile.Read(FileCopyBuffer, SizeOf(FileCopyBuffer)); + TargetFile.Write(FileCopyBuffer, NumberOfBytes); + until (NumberOfBytes < SizeOf(FileCopyBuffer)); + SourceFile.Free; + TargetFile.Free; + end; + FileList.Free(); + + chdir (OldBaseDir); +end; // Mac applications are packaged in directories. // We have to cut the last two directories // to get the application directory. -function GetBundlePath : WideString; +function TPlatformMacOSX.GetBundlePath: WideString; var i, pos : integer; begin @@ -82,37 +162,37 @@ begin end; end; -function GetApplicationSupportPath : WideString; +function TPlatformMacOSX.GetApplicationSupportPath: WideString; const PathName : string = '/Library/Application Support/UltraStarDeluxe/Resources'; begin Result := GetEnvironmentVariable('HOME') + PathName + '/'; end; -function TPlatformMacOSX.GetLogPath : WideString; +function TPlatformMacOSX.GetLogPath: WideString; begin // eddie: Please read the note at the top of this file, why we use the application directory and not the user directory. Result := GetApplicationSupportPath + 'Logs'; end; -function TPlatformMacOSX.GetGameSharedPath : WideString; +function TPlatformMacOSX.GetGameSharedPath: WideString; begin // eddie: Please read the note at the top of this file, why we use the application directory and not the user directory. Result := GetApplicationSupportPath; end; -function TPlatformMacOSX.GetGameUserPath : WideString; +function TPlatformMacOSX.GetGameUserPath: WideString; begin // eddie: Please read the note at the top of this file, why we use the application directory and not the user directory. Result := GetApplicationSupportPath; end; -function TPlatformMacOSX.DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : boolean) : TDirectoryEntryArray; +function TPlatformMacOSX.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; var i : integer; TheDir : pdir; ADirent : pDirent; - lAttrib : integer; + lAttrib : integer; begin i := 0; Filter := LowerCase(Filter); @@ -124,50 +204,27 @@ begin if Assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then begin - lAttrib := FileGetAttr(Dir + ADirent^.d_name); - if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then - begin - SetLength(Result, i + 1); - Result[i].Name := ADirent^.d_name; - Result[i].IsDirectory := true; - Result[i].IsFile := false; - i := i + 1; - end - else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then - begin - SetLength(Result, i + 1); - Result[i].Name := ADirent^.d_name; - Result[i].IsDirectory := false; - Result[i].IsFile := true; - i := i + 1; - end; + lAttrib := FileGetAttr(Dir + ADirent^.d_name); + if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then + begin + SetLength(Result, i + 1); + Result[i].Name := ADirent^.d_name; + Result[i].IsDirectory := true; + Result[i].IsFile := false; + i := i + 1; + end + else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then + begin + SetLength(Result, i + 1); + Result[i].Name := ADirent^.d_name; + Result[i].IsDirectory := false; + Result[i].IsFile := true; + i := i + 1; + end; end; until ADirent = nil; FPCloseDir(TheDir); end; -function TPlatformMacOSX.TerminateIfAlreadyRunning(var WndTitle : string) : boolean; -begin - result := false; -end; - -procedure TPlatformMacOSX.Halt; -begin - System.Halt; -end; - -function TPlatformMacOSX.FindSongFile(Dir, Mask: WideString): WideString; -var - SR : TSearchRec; // for parsing song directory -begin - Result := ''; - // faDirectory = $00000010; Attribute of a Ūle, meaning the Ūle is a directory. - if SysUtils.FindFirst(Dir + Mask, faDirectory, SR) = 0 then - begin - Result := SR.Name; - end; // if - SysUtils.FindClose(SR); -end; - end. diff --git a/Game/Code/Classes/UPlatformWindows.pas b/Game/Code/Classes/UPlatformWindows.pas index 3f9eb56b..eb4e4189 100644 --- a/Game/Code/Classes/UPlatformWindows.pas +++ b/Game/Code/Classes/UPlatformWindows.pas @@ -8,32 +8,30 @@ interface {$I switches.inc} -uses Classes, - UPlatform; +uses + Classes, + UPlatform; type - - TPlatformWindows = class( TInterfacedObject, IPlatform) - public - Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; - function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; - function GetGamePath: WideString; - function FindSongFile(Dir, Mask: widestring): widestring; - - procedure Halt; - - function GetLogPath : WideString; - function GetGameSharedPath : WideString; - function GetGameUserPath : WideString; + TPlatformWindows = class(TPlatform) + private + function GetGamePath: WideString; + public + function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; override; + function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; override; + + function GetLogPath : WideString; override; + function GetGameSharedPath : WideString; override; + function GetGameUserPath : WideString; override; end; implementation -uses SysUtils, - Windows; +uses + SysUtils, + Windows; type - TSearchRecW = record Time: Integer; Size: Integer; @@ -191,11 +189,6 @@ begin Result := ExtractFilePath(ParamStr(0)); end; -procedure TPlatformWindows.Halt; -begin - System.Halt; // Application.terminate does NOT do the same thing.. -end; - function TPlatformWindows.GetLogPath : WideString; begin result := ExtractFilePath(ParamStr(0)); @@ -211,16 +204,4 @@ begin result := ExtractFilePath(ParamStr(0)); end; -function TPlatformWindows.FindSongFile(Dir, Mask: widestring): widestring; -var - SR: TSearchRec; // for parsing song directory -begin - Result := ''; - if SysUtils.FindFirst(Dir + Mask, faDirectory, SR) = 0 then begin - Result := SR.Name; - end; // if - SysUtils.FindClose(SR); -end; - - end. diff --git a/Game/Code/MacOSX/Wrapper/UMacResources.pp b/Game/Code/MacOSX/Wrapper/UMacResources.pp deleted file mode 100644 index 65c817fc..00000000 --- a/Game/Code/MacOSX/Wrapper/UMacResources.pp +++ /dev/null @@ -1 +0,0 @@ -unit UMacResources; interface procedure init; implementation uses SysUtils, Classes; procedure init; const PathName : string = '/Library/Application Support/UltraStarDeluxe/Resources'; var RelativePath, BaseDir, OldBaseDir : string; SearchInfo : TSearchRec; DirectoryList, FileList : TStringList; DirectoryIsFinished : longint; counter : longint; UserPathName : string; SourceFile, TargetFile : TFileStream; FileCopyBuffer : array [1..4096] of byte; NumberOfBytes : integer; begin getdir (0, OldBaseDir); BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents/Resources'; chdir (BaseDir); UserPathName := GetEnvironmentVariable('HOME') + PathName; DirectoryIsFinished := 0; DirectoryList := TStringList.Create(); FileList := TStringList.Create(); DirectoryList.Add('.'); repeat RelativePath := DirectoryList[DirectoryIsFinished]; chdir (BaseDir + '/' + RelativePath); if (FindFirst('*', faAnyFile, SearchInfo) = 0) then repeat if DirectoryExists(SearchInfo.Name) then begin if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then DirectoryList.Add(RelativePath + '/' + SearchInfo.Name); end else Filelist.Add(RelativePath + '/' + SearchInfo.Name); until (FindNext(SearchInfo) <> 0); FindClose(SearchInfo); DirectoryIsFinished := succ(DirectoryIsFinished); until (DirectoryIsFinished = DirectoryList.Count); if not DirectoryExists(UserPathName) then mkdir (UserPathName); for counter := 0 to DirectoryList.Count-1 do if not DirectoryExists(UserPathName + '/' + DirectoryList[counter]) then mkdir (UserPathName + '/' + DirectoryList[counter]); DirectoryList.Free(); for counter := 0 to Filelist.Count-1 do if not FileExists(UserPathName + '/' + Filelist[counter]) then begin SourceFile := TFileStream.Create(BaseDir + '/' + Filelist[counter], fmOpenRead); TargetFile := TFileStream.Create(UserPathName + '/' + Filelist[counter], fmCreate); repeat NumberOfBytes := SourceFile.Read(FileCopyBuffer, SizeOf(FileCopyBuffer)); TargetFile.Write(FileCopyBuffer, NumberOfBytes); until (NumberOfBytes < SizeOf(FileCopyBuffer)); SourceFile.Free; TargetFile.Free; end; FileList.Free(); chdir (OldBaseDir); end; end. \ No newline at end of file -- cgit v1.2.3