aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code/Classes
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Game/Code/Classes/UMain.pas3
-rw-r--r--Game/Code/Classes/UPlatform.pas56
-rw-r--r--Game/Code/Classes/UPlatformLinux.pas66
-rw-r--r--Game/Code/Classes/UPlatformMacOSX.pas66
-rw-r--r--Game/Code/Classes/UPlatformWindows.pas58
-rw-r--r--Game/Code/Classes/USongs.pas222
6 files changed, 284 insertions, 187 deletions
diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas
index f25eaa87..c11b68d9 100644
--- a/Game/Code/Classes/UMain.pas
+++ b/Game/Code/Classes/UMain.pas
@@ -12,9 +12,6 @@ uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
- {$IFDEF DARWIN} // needed for initialization of cthreads
- cthreads,
- {$ENDIF}
SDL,
UGraphic,
UMusic,
diff --git a/Game/Code/Classes/UPlatform.pas b/Game/Code/Classes/UPlatform.pas
new file mode 100644
index 00000000..cc971bed
--- /dev/null
+++ b/Game/Code/Classes/UPlatform.pas
@@ -0,0 +1,56 @@
+unit UPlatform;
+
+// Comment by Eddie:
+// This unit defines an interface for platform specific utility functions.
+// The Interface is implemented in separate files for each platform:
+// UPlatformWindows, UPlatformLinux and UPlatformWindows.
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses Classes;
+
+type
+
+ TDirectoryEntry = Record
+ Name : WideString;
+ IsDirectory : Boolean;
+ IsFile : Boolean;
+ end;
+
+ TDirectoryEntryArray = Array of TDirectoryEntry;
+
+ IPlatform = interface
+
+ // DirectoryFindFiles returns all files matching the filter. Do not use '*' in the filter.
+ // If you set ReturnAllSubDirs = true all directories will be returned, if yout set it to false
+ // directories are completely ignored.
+ Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray;
+ end;
+
+var
+ Platform : IPlatform;
+
+implementation
+
+uses
+ {$IFDEF MSWINDOWS}
+ UPlatformWindows;
+ {$ENDIF}
+ {$IFDEF LINUX}
+ UPlatformLinux;
+ {$ENDIF}
+ {$IFDEF DARWIN}
+ UPlatformMacOSX;
+ {$ENDIF}
+
+initialization
+
+ Platform := TPlatform.Create;
+
+end.
diff --git a/Game/Code/Classes/UPlatformLinux.pas b/Game/Code/Classes/UPlatformLinux.pas
new file mode 100644
index 00000000..1713df1c
--- /dev/null
+++ b/Game/Code/Classes/UPlatformLinux.pas
@@ -0,0 +1,66 @@
+unit UPlatformLinux;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses Classes, UPlatform;
+
+type
+
+ TPlatform = class(TInterfacedObject, IPlatform)
+ public
+ Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray;
+ end;
+
+implementation
+
+uses SysUtils, oldlinux;
+
+Function TPlatform.DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray;
+var
+ i : Integer;
+ TheDir : oldlinux.pdir;
+ ADirent : oldlinux.pDirent;
+ Entry : Longint;
+ info : oldlinux.stat;
+ lAttrib : integer;
+begin
+ i := 0;
+ Filter := LowerCase(Filter);
+
+ TheDir := oldlinux.opendir( Dir );
+ if Assigned(TheDir) then
+ repeat
+ ADirent := oldlinux.ReadDir(TheDir);
+
+ 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;
+ end;
+ Until ADirent = nil;
+
+ oldlinux.CloseDir(TheDir);
+end;
+
+end.
diff --git a/Game/Code/Classes/UPlatformMacOSX.pas b/Game/Code/Classes/UPlatformMacOSX.pas
new file mode 100644
index 00000000..56469299
--- /dev/null
+++ b/Game/Code/Classes/UPlatformMacOSX.pas
@@ -0,0 +1,66 @@
+unit UPlatformMacOSX;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses Classes, UPlatform;
+
+type
+
+ TPlatform = class(TInterfacedObject, IPlatform)
+ public
+ Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray;
+ end;
+
+implementation
+
+uses SysUtils, baseunix;
+
+Function TPlatform.DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray;
+var
+ i : Integer;
+ TheDir : pdir;
+ ADirent : pDirent;
+ Entry : Longint;
+ info : stat;
+ lAttrib : integer;
+begin
+ i := 0;
+ Filter := LowerCase(Filter);
+
+ TheDir := FPOpenDir(Dir);
+ if Assigned(TheDir) then
+ repeat
+ ADirent := FPReadDir(TheDir);
+
+ 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;
+ end;
+ Until ADirent = nil;
+
+ FPCloseDir(TheDir);
+end;
+
+end.
diff --git a/Game/Code/Classes/UPlatformWindows.pas b/Game/Code/Classes/UPlatformWindows.pas
new file mode 100644
index 00000000..eb432335
--- /dev/null
+++ b/Game/Code/Classes/UPlatformWindows.pas
@@ -0,0 +1,58 @@
+unit UPlatformWindows;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses Classes, UPlatform;
+
+type
+
+ TPlatform = class(TInterfacedObject, IPlatform)
+ public
+ Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray;
+ end;
+
+implementation
+
+uses SysUtils, Windows;
+
+Function TPlatform.DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray;
+var
+ i : Integer;
+ SR : TSearchRecW;
+begin
+ i := 0;
+ Filter := LowerCase(Filter);
+
+ if ReturnAllSubDirs then begin
+ if FindFirstW(Dir + '*', faDirectory, SR) = 0 then
+ repeat
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ begin
+ SetLength( Result, i + 1);
+ Result[i].Name := SR.Name;
+ Result[i].IsDirectory := true;
+ Result[i].IsFile := false;
+ i := i + 1;
+ end;
+ until FindNextW(SR) <> 0;
+ FindCloseW(SR);
+ end;
+
+ if FindFirstW(Dir + '*' + Filter, 0, SR) = 0 then
+ repeat
+ SetLength( Result, i + 1);
+ Result[i].Name := SR.Name;
+ Result[i].IsDirectory := true;
+ Result[i].IsFile := false;
+ i := i + 1;
+ until FindNextW(SR) <> 0;
+ FindCloseW(SR);
+end;
+
+end.
diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas
index 9b9ab7bb..dcca08bd 100644
--- a/Game/Code/Classes/USongs.pas
+++ b/Game/Code/Classes/USongs.pas
@@ -30,6 +30,7 @@ uses
{$ENDIF}
SysUtils,
Classes,
+ UPlatform,
ULog,
UTexture,
UCommon,
@@ -299,198 +300,51 @@ begin
self.resume;
end;
-// TODO : JB - THis whole function SUX ! and needs refactoring ! :P
procedure TSongs.BrowseDir(Dir: widestring);
var
SLen: integer;
-
- {$ifdef Delphi}
- SR: TSearchRecW; // for parsing Songs Directory
- {$ENDIF}
-
- // eddie: can we merge that? is baseunix working on linux? oldlinux is
- // not available on mac os x.
- {$IFDEF LINUX}
- TheDir : oldlinux.pdir;
- ADirent : oldlinux.pDirent;
- Entry : Longint;
- info : oldlinux.stat;
- {$ENDIF}
- {$IFDEF DARWIN}
- TheDir : pdir;
- ADirent : pDirent;
- Entry : Longint;
- info : stat;
- lAttrib : integer;
- {$ENDIF}
+ i : Integer;
+ Files : TDirectoryEntryArray;
begin
- {$ifdef Delphi}
- if FindFirstW(Dir + '*', faDirectory, SR) = 0 then // JB_Unicode - windows
- begin
- repeat
- if (SR.Name <> '.') and (SR.Name <> '..') then
- begin
- BrowseDir(Dir + Sr.Name + PathDelim);
- end
- until FindNextw(SR) <> 0;
- end; // if
- FindClosew(SR);
-
- if FindFirstW(Dir + '*.txt', 0, SR) = 0 then
- begin
- repeat
- SLen := BrowsePos;
-
- Song[SLen].Path := Dir;
- Song[SLen].Folder := Copy(Dir, Length(SongPath)+1, 10000);
- Song[SLen].Folder := Copy(Song[SLen].Folder, 1, Pos( PathDelim , Song[SLen].Folder)-1);
- Song[SLen].FileName := SR.Name;
-
- if (AnalyseFile(Song[SLen]) = false) then
- Dec(BrowsePos)
- else
- begin
- if Song[SLen].Cover = '' then
- Song[SLen].Cover := FindSongFile(Dir, '*[CO].jpg');
- end;
-
- //Change Length Only every 50 Entrys
- Inc(BrowsePos);
-
- if (BrowsePos mod 50 = 0) AND (BrowsePos <> 0) then
- begin
- SetLength(Song, Length(Song) + 50);
- end;
-
- until FindNextW(SR) <> 0;
- end; // if FindFirst
- FindCloseW(SR);
- {$ENDIF}
-
- {$IFDEF LINUX}
- // Itterate the Songs Directory... ( With unicode capable functions for linux )
- TheDir := oldlinux.opendir( Dir ); // JB_Unicode - linux
- if TheDir <> nil then
- begin
- repeat
- ADirent := oldlinux.ReadDir(TheDir);
-
- If ADirent<>Nil then
- begin
- With ADirent^ do
- begin
-
- if ( name[0] <> '.') then
- BrowseDir( Dir + name + pathdelim );
-
- end;
- end;
- Until ADirent=Nil;
- end;
-
-
-
- TheDir := oldlinux.opendir( Dir ); // JB_Unicode - linux
- if TheDir <> nil then
- begin
- repeat
- ADirent := oldlinux.ReadDir(TheDir);
-
- if ( ADirent <> Nil ) AND
- ( pos( '.txt', ADirent^.name ) > 0 ) then
- begin
- writeln ('***** FOUND TXT' + ADirent^.name );
-
- SLen := BrowsePos;
-
- Song[SLen].Path := Dir;
- Song[SLen].Folder := Copy(Dir, Length(SongPath)+1, 10000);
- Song[SLen].Folder := Copy(Song[SLen].Folder, 1, Pos( PathDelim , Song[SLen].Folder)-1);
- Song[SLen].FileName := ADirent^.name;
-
- if (AnalyseFile(Song[SLen]) = false) then
- Dec(BrowsePos)
- else
- begin
- if Song[SLen].Cover = '' then
- Song[SLen].Cover := FindSongFile(Dir, '*[CO].jpg');
- end;
-
- //Change Length Only every 50 Entrys
- Inc(BrowsePos);
- if (BrowsePos mod 50 = 0) AND (BrowsePos <> 0) then
- begin
- SetLength(Song, Length(Song) + 50);
- end;
- end;
-
- Until ADirent=Nil;
- end; // if FindFirst
- {$endif}
-
- {$IFDEF DARWIN}
- // Itterate the Songs Directory... ( With unicode capable functions for linux )
- TheDir := FPOpenDir(Dir); // JB_Unicode - linux
- if TheDir <> nil then
- begin
- repeat
- ADirent := FPReadDir(TheDir);
-
- If assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then
- begin
- lAttrib := FileGetAttr(Dir + ADirent^.d_name);
- if (lAttrib and faDirectory) <> 0 then
- begin
- //Log.LogError('Entering dir "' + Dir + ADirent^.d_name + PathDelim + '" now.');
- BrowseDir(Dir + ADirent^.d_name + PathDelim);
- end
- else if Pos( '.txt', LowerCase(ADirent^.d_name)) > 0 then
- begin
- SLen := BrowsePos;
-
- try
- Song[SLen].Path := Dir;
- Song[SLen].Folder := Copy(String(Dir), Length(String(SongPath))+1, 10000);
- Song[SLen].Folder := Copy(String(Song[SLen].Folder), 1, Pos( PathDelim , Song[SLen].Folder)-1);
- Song[SLen].FileName := ADirent^.d_name;
- //Log.LogError( 'Song: ' + ADirent^.d_name + ', Length(Song) = ' + inttostr(Length(Song)) + ', BrowsePos = ' + IntToStr(BrowsePos) + ', Dir = "' + Dir + '"');
-
- if (AnalyseFile(Song[SLen]) = false) then
- begin
- Log.LogError('AnalyseFile failed for "' + ADirent^.d_name + '".');
- Dec(BrowsePos);
- end
- else
- begin
- if Song[SLen].Cover = '' then
- Song[SLen].Cover := FindSongFile(Dir, '*[CO].jpg');
- end;
- except
- end;
-
- //Change Length Only every 50 Entrys
- Inc(BrowsePos);
-
- if (BrowsePos mod 50 = 0) AND (BrowsePos <> 0) then
- begin
- SetLength(Song, Length(Song) + 50);
- end;
- end;
- end;
-
- Until ADirent=Nil;
-
- if (FPCloseDir(TheDir) <> 0) then
+ Files := Platform.DirectoryFindFiles( Dir, '.txt', true);
+ for i := 0 to Length(Files)-1 do
+ begin
+ if Files[i].IsDirectory then
+ begin
+ BrowseDir( Dir + Files[i].Name + PathDelim );
+ end
+ else
begin
- Log.LogError('TSongs.BrowseDir: Exception: Error closing dir: "' + Dir + '".')
+ SLen := BrowsePos;
+
+ Song[SLen].Path := Dir;
+ Song[SLen].Folder := Copy(String(Dir), Length(String(SongPath))+1, 10000);
+ Song[SLen].Folder := Copy(String(Song[SLen].Folder), 1, Pos( PathDelim , Song[SLen].Folder)-1);
+ Song[SLen].FileName := Files[i].Name;
+
+ if (AnalyseFile(Song[SLen]) = false) then
+ begin
+ Log.LogError('AnalyseFile failed for "' + Files[i].Name + '".');
+ Dec(BrowsePos);
+ end
+ else
+ begin
+ if Song[SLen].Cover = '' then
+ Song[SLen].Cover := FindSongFile(Dir, '*[CO].jpg');
+ end;
+
+ //Change Length Only every 50 Entrys
+ Inc(BrowsePos);
+
+ if (BrowsePos mod 50 = 0) AND (BrowsePos <> 0) then
+ begin
+ SetLength(Song, Length(Song) + 50);
+ end;
end;
- end;
+ end;
+ SetLength( Files, 0);
- {$endif}
-
// Log.LogStatus('Parsing directory: ' + Dir + SR.Name, 'LoadSongList');
-
-
end;
procedure TSongs.Sort(Order: integer);