aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreddie-0815 <eddie-0815@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-11-03 09:33:35 +0000
committereddie-0815 <eddie-0815@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-11-03 09:33:35 +0000
commitd29ff5bed651115af3c63b6fe4768690fb46a916 (patch)
tree27dce0917f0d46689245ee0487b0c32f50e825ae
parent84a799853df75973fe4560576d9257f20b5bef85 (diff)
downloadusdx-d29ff5bed651115af3c63b6fe4768690fb46a916.tar.gz
usdx-d29ff5bed651115af3c63b6fe4768690fb46a916.tar.xz
usdx-d29ff5bed651115af3c63b6fe4768690fb46a916.zip
Mac OS X: Added unit cthreads. USDX now runs on OS X! But you can't do anything :-) Fonts are not working, but you can quit the program cleanly by pressing ESC and ENTER (MainLoop works).
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@565 b956fd51-792f-4845-bead-9b4dfca2ff2c
-rw-r--r--Game/Code/Classes/UGraphic.pas71
-rw-r--r--Game/Code/Classes/UMain.pas3
-rw-r--r--Game/Code/Classes/USongs.pas2093
-rw-r--r--Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1127
-rw-r--r--Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser326
5 files changed, 1333 insertions, 1287 deletions
diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas
index e13fdf43..02c06002 100644
--- a/Game/Code/Classes/UGraphic.pas
+++ b/Game/Code/Classes/UGraphic.pas
@@ -566,6 +566,11 @@ begin
W := 800;
H := 600;
{$endif}
+
+ {$IFDEF DARWIN}
+ // Todo : eddie: remove before realease
+ Ini.FullScreen := 0;
+ {$ENDIF}
if (Ini.FullScreen = 0) and (Not Params.FullScreen) then
begin
@@ -702,39 +707,39 @@ begin
end;
procedure UnLoadScreens;
-begin
- freeandnil( ScreenMain );
- freeandnil( ScreenName );
- freeandnil( ScreenLevel);
- freeandnil( ScreenSong );
- freeandnil( ScreenSongMenu );
- freeandnil( ScreenSing );
- freeandnil( ScreenScore);
- freeandnil( ScreenTop5 );
- freeandnil( ScreenOptions );
- freeandnil( ScreenOptionsGame );
- freeandnil( ScreenOptionsGraphics );
- freeandnil( ScreenOptionsSound );
- freeandnil( ScreenOptionsLyrics );
-// freeandnil( ScreenOptionsThemes );
- freeandnil( ScreenOptionsRecord );
- freeandnil( ScreenOptionsAdvanced );
- freeandnil( ScreenEditSub );
- freeandnil( ScreenEdit );
- freeandnil( ScreenEditConvert );
- freeandnil( ScreenOpen );
- freeandnil( ScreenSingModi );
- freeandnil( ScreenSongMenu );
- freeandnil( ScreenSongJumpto);
- freeandnil( ScreenPopupCheck );
- freeandnil( ScreenPopupError );
- freeandnil( ScreenPartyNewRound );
- freeandnil( ScreenPartyScore );
- freeandnil( ScreenPartyWin );
- freeandnil( ScreenPartyOptions );
- freeandnil( ScreenPartyPlayer );
- freeandnil( ScreenStatMain );
- freeandnil( ScreenStatDetail );
+begin
+ freeandnil( ScreenMain );
+ freeandnil( ScreenName );
+ freeandnil( ScreenLevel);
+ freeandnil( ScreenSong );
+ freeandnil( ScreenSongMenu );
+ freeandnil( ScreenSing );
+ freeandnil( ScreenScore);
+ freeandnil( ScreenTop5 );
+ freeandnil( ScreenOptions );
+ freeandnil( ScreenOptionsGame );
+ freeandnil( ScreenOptionsGraphics );
+ freeandnil( ScreenOptionsSound );
+ freeandnil( ScreenOptionsLyrics );
+// freeandnil( ScreenOptionsThemes );
+ freeandnil( ScreenOptionsRecord );
+ freeandnil( ScreenOptionsAdvanced );
+ freeandnil( ScreenEditSub );
+ freeandnil( ScreenEdit );
+ freeandnil( ScreenEditConvert );
+ freeandnil( ScreenOpen );
+ freeandnil( ScreenSingModi );
+ freeandnil( ScreenSongMenu );
+ freeandnil( ScreenSongJumpto);
+ freeandnil( ScreenPopupCheck );
+ freeandnil( ScreenPopupError );
+ freeandnil( ScreenPartyNewRound );
+ freeandnil( ScreenPartyScore );
+ freeandnil( ScreenPartyWin );
+ freeandnil( ScreenPartyOptions );
+ freeandnil( ScreenPartyPlayer );
+ freeandnil( ScreenStatMain );
+ freeandnil( ScreenStatDetail );
end;
end.
diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas
index 1be4b463..48928cbd 100644
--- a/Game/Code/Classes/UMain.pas
+++ b/Game/Code/Classes/UMain.pas
@@ -12,6 +12,9 @@ uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
+ {$IFDEF DARWIN} // needed for initialization of cthreads
+ cthreads,
+ {$ENDIF}
SDL,
UGraphic,
UMusic,
diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas
index 2fa3ea4a..96d9ad2e 100644
--- a/Game/Code/Classes/USongs.pas
+++ b/Game/Code/Classes/USongs.pas
@@ -1,1045 +1,1048 @@
-unit USongs;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- {$IFDEF MSWINDOWS}
- Windows,
- {$ifdef Delphi}
- DirWatch,
- {$endif}
- {$ELSE}
- {$IFNDEF DARWIN}
- oldlinux,
- syscall,
- {$ENDIF}
- baseunix,
- UnixType,
- {$ENDIF}
- SysUtils,
- Classes,
- ULog,
- UTexture,
- UCommon,
- UCatCovers;
-
-type
-
- TBPM = record
- BPM: real;
- StartBeat: real;
- end;
-
- TScore = record
- Name: widestring;
- Score: integer;
- Length: string;
- end;
-
- TSong = record
- Path: widestring;
- Folder: widestring; // for sorting by folder
- FileName: widestring;
-
- // sorting methods
- Category: array of widestring; // I think I won't need this
- Genre: widestring;
- Edition: widestring;
- Language: widestring; // 0.5.0: new
-
- Title: widestring;
- Artist: widestring;
-
- Text: widestring;
- Creator: widestring;
-
- Cover: widestring;
- CoverTex: TTexture;
- Mp3: widestring;
- Background: widestring;
- Video: widestring;
- VideoGAP: real;
- VideoLoaded: boolean; // 0.5.0: true if the video has been loaded
- NotesGAP: integer;
- Start: real; // in seconds
- Finish: integer; // in miliseconds
- Relative: boolean;
- Resolution: integer;
- BPM: array of TBPM;
- GAP: real; // in miliseconds
-
- Score: array[0..2] of array of TScore;
-
- // these are used when sorting is enabled
- Visible: boolean; // false if hidden, true if visible
- Main: boolean; // false for songs, true for category buttons
- OrderNum: integer; // has a number of category for category buttons and songs
- OrderTyp: integer; // type of sorting for this button (0=name)
- CatNumber: integer; // Count of Songs in Category for Cats and Number of Song in Category for Songs
- end;
-
- TSongs = class( TThread )
- private
- BrowsePos : Cardinal; //Actual Pos in Song Array
- fNotify ,
- fWatch : longint;
- fParseSongDirectory : boolean;
- fProcessing : boolean;
- {$ifdef Delphi}
- fDirWatch : TDirectoryWatch;
- {$endif}
- procedure int_LoadSongList;
- procedure DoDirChanged(Sender: TObject);
- protected
- procedure Execute; override;
- public
- Song : array of TSong; // array of songs
- Selected : integer; // selected song index
- constructor create();
- procedure LoadSongList; // load all songs
- procedure BrowseDir(Dir: widestring); // should return number of songs in the future
- procedure Sort(Order: integer);
- function FindSongFile(Dir, Mask: widestring): widestring;
- property Processing : boolean read fProcessing;
- end;
-
- TCatSongs = class
- Song: array of TSong; // array of categories with songs
- Selected: integer; // selected song index
- Order: integer; // order type (0=title)
- CatNumShow: integer; // Category Number being seen
- CatCount: integer; //Number of Categorys
-
- procedure Refresh; // refreshes arrays by recreating them from Songs array
-// procedure Sort(Order: integer);
- procedure ShowCategory(Index: integer); // expands all songs in category
- procedure HideCategory(Index: integer); // hides all songs in category
- procedure ClickCategoryButton(Index: integer); // uses ShowCategory and HideCategory when needed
- procedure ShowCategoryList; //Hides all Songs And Show the List of all Categorys
- function FindNextVisible(SearchFrom:integer): integer; //Find Next visible Song
- function VisibleSongs: integer; // returns number of visible songs (for tabs)
- function VisibleIndex(Index: integer): integer; // returns visible song index (skips invisible)
-
- function SetFilter(FilterStr: String; const fType: Byte): Cardinal;
- end;
-
-var
- Songs: TSongs; // all songs
- CatSongs: TCatSongs; // categorized songs
- AktSong: TSong; // one song *unknown use)
-
-const
- IN_ACCESS = $00000001; //* File was accessed */
- IN_MODIFY = $00000002; //* File was modified */
- IN_ATTRIB = $00000004; //* Metadata changed */
- IN_CLOSE_WRITE = $00000008; //* Writtable file was closed */
- IN_CLOSE_NOWRITE = $00000010; //* Unwrittable file closed */
- IN_OPEN = $00000020; //* File was opened */
- IN_MOVED_FROM = $00000040; //* File was moved from X */
- IN_MOVED_TO = $00000080; //* File was moved to Y */
- IN_CREATE = $00000100; //* Subfile was created */
- IN_DELETE = $00000200; //* Subfile was deleted */
- IN_DELETE_SELF = $00000400; //* Self was deleted */
-
-
-implementation
-
-uses StrUtils,
- UGraphic,
- UCovers,
- UFiles,
- UMain,
- UIni;
-
-{$IFDEF DARWIN}
-function AnsiContainsText(const AText, ASubText: string): Boolean;
-begin
- Result := AnsiPos(AnsiUppercase(ASubText), AnsiUppercase(AText)) > 0;
-end;
-{$ENDIF}
-
-constructor TSongs.create();
-begin
- inherited create( false );
- self.freeonterminate := true;
-
- {$ifdef Delphi}
- fDirWatch := TDirectoryWatch.create(nil);
- fDirWatch.OnChange := DoDirChanged;
- fDirWatch.Directory := SongPath;
- fDirWatch.WatchSubDirs := true;
- fDirWatch.active := true;
- {$ENDIF}
-
- {$IFDEF linux}
- (*
- Thankyou to : http://www.linuxjournal.com/article/8478
- http://www.tin.org/bin/man.cgi?section=2&topic=inotify_add_watch
- *)
-(*
- fNotify := -1;
- fWatch := -1;
-
- writeln( 'Calling inotify_init' );
- fNotify := Do_SysCall( syscall_nr_inotify_init );
- if ( fNotify < 0 ) then
- writeln( 'Filesystem change notification - disabled' );
- writeln( 'Calling inotify_init : '+ inttostr(fNotify) );
-
- writeln( 'Calling syscall_nr_inotify_init ('+SongPath+')' );
- fWatch := Do_SysCall( syscall_nr_inotify_init , TSysParam( fNotify ), longint( pchar( SongPath ) ) , IN_MODIFY AND IN_CREATE AND IN_DELETE );
-
- if (fWatch < 0) then
- writeln ('inotify_add_watch');
- writeln( 'Calling syscall_nr_inotify_init : '+ inttostr(fWatch) );
-*)
- {$endif}
-
- Setlength(Song, 0);
-end;
-
-procedure TSongs.DoDirChanged(Sender: TObject);
-begin
- LoadSongList();
-end;
-
-procedure TSongs.Execute();
-var
- fChangeNotify : THandle;
-begin
- fParseSongDirectory := true;
-
- while not self.terminated do
- begin
-
- if fParseSongDirectory then
- begin
- writeln( 'int_LoadSongList' );
- int_LoadSongList();
- end;
-
- self.suspend;
- end;
-
-end;
-
-procedure TSongs.int_LoadSongList;
-begin
- try
- fProcessing := true;
- Setlength(Song, 0);
-
- Log.LogError('SongList', 'Searching For Songs');
-
- Setlength(Song, 50);
-
- BrowsePos := 0;
- // browse directories
- BrowseDir(SongPath);
-
- //Set Correct SongArray Length
- SetLength(Song, BrowsePos);
-
- if assigned( CatSongs ) then
- CatSongs.Refresh;
-
- if assigned( CatCovers ) then
- CatCovers.Load;
-
- if assigned( Covers ) then
- Covers.Load;
-
- if assigned(ScreenSong) then
- begin
- ScreenSong.GenerateThumbnails();
- ScreenSong.OnShow; // refresh ScreenSong
- end;
-
-
- finally
- Log.LogError('SongList', 'Search Complete');
-
- fParseSongDirectory := false;
- fProcessing := false;
- end;
-end;
-
-
-procedure TSongs.LoadSongList;
-begin
- fParseSongDirectory := true;
- 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;
- {$ENDIF}
-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 ADirent<>Nil then
- begin
- With ADirent^ do
- begin
-
- if ( d_name[0] <> '.') then
- BrowseDir( Dir + d_name + pathdelim );
-
- end;
- end;
- Until ADirent=Nil;
- end;
-
-
-
- TheDir := FPOpenDir( Dir ); // JB_Unicode - linux
- if TheDir <> nil then
- begin
- repeat
- ADirent := FPReadDir(TheDir);
-
- if ( ADirent <> Nil ) AND
- ( pos( '.txt', ADirent^.d_name ) > -1 ) then
- begin
- 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^.d_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}
-
-// Log.LogStatus('Parsing directory: ' + Dir + SR.Name, 'LoadSongList');
-
-
-end;
-
-procedure TSongs.Sort(Order: integer);
-var
- S: integer;
- S2: integer;
- TempSong: TSong;
-begin
- case Order of
- sEdition: // by edition
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Edition, Song[S-1].Edition) < 0 then begin
- // zamiana miejscami
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
- end;
- sGenre: // by genre
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Genre, Song[S-1].Genre) < 0 then begin
- // zamiana miejscami
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
- end;
- sTitle: // by title
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Title, Song[S-1].Title) < 0 then begin
- // zamiana miejscami
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
-
- end;
- sArtist: // by artist
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Artist, Song[S-1].Artist) < 0 then begin
- // zamiana miejscami
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
- end;
- sFolder: // by folder
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Folder, Song[S-1].Folder) < 0 then begin
- // zamiana miejscami
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
- end;
- sTitle2: // by title2
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Title, Song[S-1].Title) < 0 then begin
- // zamiana miejscami
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
-
- end;
- sArtist2: // by artist2
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Artist, Song[S-1].Artist) < 0 then begin
- // zamiana miejscami
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
- end;
- sLanguage: // by Language
- begin
- for S2 := 0 to Length(Song)-1 do
- for S := 1 to Length(Song)-1 do
- if CompareText(Song[S].Language, Song[S-1].Language) < 0 then begin
- TempSong := Song[S-1];
- Song[S-1] := Song[S];
- Song[S] := TempSong;
- end;
- end;
-
- end; // case
-end;
-
-function TSongs.FindSongFile(Dir, Mask: widestring): widestring;
-var
- SR: TSearchRec; // for parsing song directory
-begin
- Result := '';
- if FindFirst(Dir + Mask, faDirectory, SR) = 0 then begin
- Result := SR.Name;
- end; // if
- FindClose(SR);
-end;
-
-procedure TCatSongs.Refresh;
-var
- S: integer; // temporary song index
- CatLen: integer; // length of CatSongs.Song
- Letter: char; // current letter for sorting using letter
- SS: string; // current edition for sorting using edition, genre etc.
- Order: integer; // number used for ordernum
- Letter2: char; //
- CatNumber:integer; // Number of Song in Category
-begin
- CatNumShow := -1;
-// Songs.Sort(0); // by title
-
-case Ini.Sorting of
- sEdition: begin
- Songs.Sort(sArtist);
- Songs.Sort(sEdition);
- end;
- sGenre: begin
- Songs.Sort(sArtist);
- Songs.Sort(sGenre);
- end;
- sLanguage: begin
- Songs.Sort(sArtist);
- Songs.Sort(sLanguage);
- end;
- sFolder: begin
- Songs.Sort(sArtist);
- Songs.Sort(sFolder);
- end;
- sTitle: Songs.Sort(sTitle);
- sArtist: Songs.Sort(sArtist);
- sTitle2: Songs.Sort(sTitle2); // by title2
- sArtist2: Songs.Sort(sArtist2); // by artist2
-
- end; // case
-
-
- Letter := ' ';
- SS := '';
- Order := 0;
- CatNumber := 0;
-
- //Songs leeren
- SetLength (Song, 0);
-
- for S := Low(Songs.Song) to High(Songs.Song) do begin
- if (Ini.Tabs = 1) then
- if (Ini.Sorting = sEdition) and (CompareText(SS, Songs.Song[S].Edition) <> 0) then begin
- // add Category Button
- Inc(Order);
- SS := Songs.Song[S].Edition;
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := '[' + SS + ']';
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
- CatSongs.Song[CatLen].OrderNum := Order;
-
-
-
- // 0.4.3
- // if SS = 'Singstar' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
- // if SS = 'Singstar Part 2' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
- // if SS = 'Singstar German' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
- // if SS = 'Singstar Spanish' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
- // if SS = 'Singstar Italian' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
- // if SS = 'Singstar French' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
- // if SS = 'Singstar Party' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Party.jpg';
- // if SS = 'Singstar Popworld' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Popworld.jpg';
- // if SS = 'Singstar 80s' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar 80s.jpg';
- // if SS = 'Singstar 80s Polish' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar 80s.jpg';
- // if SS = 'Singstar Rocks' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Rocks.jpg';
- // if SS = 'Singstar Anthems' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Anthems.jpg';
-
- {// cover-patch
- if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';//}
-
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
-
- //CatNumber Patch
- if (SS <> '') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end
-
- else if (Ini.Sorting = sGenre) and (CompareText(SS, Songs.Song[S].Genre) <> 0) then begin
- // add Genre Button
- Inc(Order);
- SS := Songs.Song[S].Genre;
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := SS;
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
- CatSongs.Song[CatLen].OrderNum := Order;
-
- {// cover-patch
- if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
-
- //CatNumber Patch
- if (SS <> '') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end
-
- else if (Ini.Sorting = sLanguage) and (CompareText(SS, Songs.Song[S].Language) <> 0) then begin
- // add Language Button
- Inc(Order);
- SS := Songs.Song[S].Language;
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := SS;
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
- CatSongs.Song[CatLen].OrderNum := Order;
-
- {// cover-patch
- if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
-
- //CatNumber Patch
- if (SS <> '') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end
-
- else if (Ini.Sorting = sTitle) and
- (Length(Songs.Song[S].Title)>=1) and
- (Letter <> UpperCase(Songs.Song[S].Title)[1]) then begin
- // add a letter Category Button
- Inc(Order);
- Letter := Uppercase(Songs.Song[S].Title)[1];
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
-// Order := ord(Letter);
- CatSongs.Song[CatLen].OrderNum := Order;
-
-
- {// cover-patch
- if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
-
- //CatNumber Patch
- if (Letter <> ' ') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end
-
- else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> UpperCase(Songs.Song[S].Artist)[1]) then begin
- // add a letter Category Button
- Inc(Order);
- Letter := UpperCase(Songs.Song[S].Artist)[1];
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
-// Order := ord(Letter);
- CatSongs.Song[CatLen].OrderNum := Order;
-
- {// cover-patch
- if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
-
- //CatNumber Patch
- if (Letter <> ' ') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end
-
- else if (Ini.Sorting = sFolder) and (CompareText(SS, Songs.Song[S].Folder) <> 0) then begin
- // 0.5.0: add folder tab
- Inc(Order);
- SS := Songs.Song[S].Folder;
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := SS;
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
- CatSongs.Song[CatLen].OrderNum := Order;
-
- {// cover-patch
- if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
-
- //CatNumber Patch
- if (SS <> '') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end
-
- else if (Ini.Sorting = sTitle2) AND (Length(Songs.Song[S].Title)>=1) then begin
- if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Title)[1];
- if (Letter <> Letter2) then begin
- // add a letter Category Button
- Inc(Order);
- Letter := Letter2;
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
-// Order := ord(Letter);
- CatSongs.Song[CatLen].OrderNum := Order;
-
- {// cover-patch
- if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
-
- //CatNumber Patch
- if (Letter <> ' ') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end;
- end
-
- else if (Ini.Sorting = sArtist2) AND (Length(Songs.Song[S].Artist)>=1) then begin
- if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Artist)[1];
- if (Letter <> Letter2) then begin
- // add a letter Category Button
- Inc(Order);
- Letter := Letter2;
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
- CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
- CatSongs.Song[CatLen].Main := true;
- CatSongs.Song[CatLen].OrderTyp := 0;
-// Order := ord(Letter);
- CatSongs.Song[CatLen].OrderNum := Order;
-
- {// cover-patch
- if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg'
- else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
- CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
-
- //CatNumber Patch
- if (Letter <> ' ') then
- begin
- Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
- CatNumber := 0;
- end;
-
- CatSongs.Song[CatLen].Visible := true;
- end;
- end;
-
-
- CatLen := Length(CatSongs.Song);
- SetLength(CatSongs.Song, CatLen+1);
-
- Inc (CatNumber); //Increase Number in Cat
-
- CatSongs.Song[CatLen] := Songs.Song[S];
- CatSongs.Song[CatLen].OrderNum := Order; // assigns category
- CatSongs.Song[CatLen].CatNumber := CatNumber;
-
- if (Ini.Tabs = 0) then CatSongs.Song[CatLen].Visible := true
- else if (Ini.Tabs = 1) then CatSongs.Song[CatLen].Visible := false;
-// if (Ini.Tabs = 1) and (Order = 1) then CatSongs.Song[CatLen].Visible := true; // open first tab
-//CatSongs.Song[CatLen].Visible := true;
-
- end;
-//CatNumber Patch - Set CatNumber of Last Category
-if (ini.Tabs_at_startup = 1) And (high(Song) >=1) then
- Song[CatLen - CatNumber].CatNumber := CatNumber;//Set CatNumber of Categroy
-//CatCount Patch
-CatCount := Order;
-end;
-
-procedure TCatSongs.ShowCategory(Index: integer);
-var
- S: integer; // song
-begin
- CatNumShow := Index;
- for S := 0 to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[S].OrderNum = Index) AND (Not CatSongs.Song[S].Main) then
- CatSongs.Song[S].Visible := true
- else
- CatSongs.Song[S].Visible := false;
- end;
-end;
-
-procedure TCatSongs.HideCategory(Index: integer); // hides all songs in category
-var
- S: integer; // song
-begin
- for S := 0 to high(CatSongs.Song) do begin
- if not CatSongs.Song[S].Main then
- CatSongs.Song[S].Visible := false // hides all at now
- end;
-end;
-
-procedure TCatSongs.ClickCategoryButton(Index: integer);
-var
- Num, S: integer;
-begin
- Num := CatSongs.Song[Index].OrderNum;
- if Num <> CatNumShow then
- begin
- ShowCategory(Num);
- end
- else begin
- ShowCategoryList;
- end;
-end;
-
-//Hide Categorys when in Category Hack
-procedure TCatSongs.ShowCategoryList;
-var
- Num, S: integer;
-begin
- //Hide All Songs Show All Cats
- for S := 0 to high(CatSongs.Song) do begin
- if CatSongs.Song[S].Main then
- CatSongs.Song[S].Visible := true
- else
- CatSongs.Song[S].Visible := false
- end;
- CatSongs.Selected := CatNumShow; //Show last shown Category
- CatNumShow := -1;
-end;
-//Hide Categorys when in Category Hack End
-
-//Wrong song selected when tabs on bug
-function TCatSongs.FindNextVisible(SearchFrom:integer): integer;//Find next Visible Song
-var
- I: Integer;
- begin
- Result := -1;
- I := SearchFrom + 1;
- while not CatSongs.Song[I].Visible do
- begin
- Inc (I);
- if (I>high(CatSongs.Song)) then
- I := low(CatSongs.Song);
- if (I = SearchFrom) then //Make One Round and no song found->quit
- break;
- end;
- end;
-//Wrong song selected when tabs on bug End
-
-function TCatSongs.VisibleSongs: integer;
-var
- S: integer; // song
-begin
- Result := 0;
- for S := 0 to high(CatSongs.Song) do
- if CatSongs.Song[S].Visible = true then Inc(Result);
-end;
-
-function TCatSongs.VisibleIndex(Index: integer): integer;
-var
- S: integer; // song
-begin
- Result := 0;
- for S := 0 to Index-1 do
- if CatSongs.Song[S].Visible = true then Inc(Result);
-end;
-
-function TCatSongs.SetFilter(FilterStr: String; const fType: Byte): Cardinal;
-var
- I, J: Integer;
- cString: String;
- SearchStr: Array of String;
-begin
- {fType: 0: All
- 1: Title
- 2: Artist}
- FilterStr := Trim(FilterStr);
- if FilterStr<>'' then begin
- Result := 0;
- //Create Search Array
- SetLength(SearchStr, 1);
- I := Pos (' ', FilterStr);
- While (I <> 0) do
- begin
- SetLength (SearchStr, Length(SearchStr) + 1);
- cString := Copy(FilterStr, 1, I-1);
- if (cString <> ' ') AND (cString <> '') then
- SearchStr[High(SearchStr)-1] := cString;
- Delete (FilterStr, 1, I);
-
- I := Pos (' ', FilterStr);
- end;
- //Copy last Word
- if (FilterStr <> ' ') AND (FilterStr <> '') then
- SearchStr[High(SearchStr)] := FilterStr;
-
- for I:=0 to High(Song) do begin
- if not Song[i].Main then
- begin
- case fType of
- 0: cString := Song[I].Artist + ' ' + Song[i].Title + ' ' + Song[i].Folder;
- 1: cString := Song[I].Title;
- 2: cString := Song[I].Artist;
- end;
- Song[i].Visible:=True;
- //Look for every Searched Word
- For J := 0 to High(SearchStr) do
- begin
- Song[i].Visible := Song[i].Visible AND AnsiContainsText(cString, SearchStr[J])
- end;
- if Song[i].Visible then
- Inc(Result);
- end
- else
- Song[i].Visible:=False;
- end;
- CatNumShow := -2;
- end
- else begin
- for i:=0 to High(Song) do begin
- Song[i].Visible:=(Ini.Tabs=1)=Song[i].Main;
- CatNumShow := -1;
- end;
- Result := 0;
- end;
-end;
-
-end.
+unit USongs;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ {$IFDEF MSWINDOWS}
+ Windows,
+ {$ifdef Delphi}
+ DirWatch,
+ {$endif}
+ {$ELSE}
+ {$IFNDEF DARWIN}
+ oldlinux,
+ syscall,
+ {$ENDIF}
+ baseunix,
+ UnixType,
+ {$ENDIF}
+ SysUtils,
+ Classes,
+ ULog,
+ UTexture,
+ UCommon,
+ {$IFDEF DARWIN}
+ cthreads,
+ {$ENDIF}
+ UCatCovers;
+
+type
+
+ TBPM = record
+ BPM: real;
+ StartBeat: real;
+ end;
+
+ TScore = record
+ Name: widestring;
+ Score: integer;
+ Length: string;
+ end;
+
+ TSong = record
+ Path: widestring;
+ Folder: widestring; // for sorting by folder
+ FileName: widestring;
+
+ // sorting methods
+ Category: array of widestring; // I think I won't need this
+ Genre: widestring;
+ Edition: widestring;
+ Language: widestring; // 0.5.0: new
+
+ Title: widestring;
+ Artist: widestring;
+
+ Text: widestring;
+ Creator: widestring;
+
+ Cover: widestring;
+ CoverTex: TTexture;
+ Mp3: widestring;
+ Background: widestring;
+ Video: widestring;
+ VideoGAP: real;
+ VideoLoaded: boolean; // 0.5.0: true if the video has been loaded
+ NotesGAP: integer;
+ Start: real; // in seconds
+ Finish: integer; // in miliseconds
+ Relative: boolean;
+ Resolution: integer;
+ BPM: array of TBPM;
+ GAP: real; // in miliseconds
+
+ Score: array[0..2] of array of TScore;
+
+ // these are used when sorting is enabled
+ Visible: boolean; // false if hidden, true if visible
+ Main: boolean; // false for songs, true for category buttons
+ OrderNum: integer; // has a number of category for category buttons and songs
+ OrderTyp: integer; // type of sorting for this button (0=name)
+ CatNumber: integer; // Count of Songs in Category for Cats and Number of Song in Category for Songs
+ end;
+
+ TSongs = class( TThread )
+ private
+ BrowsePos : Cardinal; //Actual Pos in Song Array
+ fNotify ,
+ fWatch : longint;
+ fParseSongDirectory : boolean;
+ fProcessing : boolean;
+ {$ifdef Delphi}
+ fDirWatch : TDirectoryWatch;
+ {$endif}
+ procedure int_LoadSongList;
+ procedure DoDirChanged(Sender: TObject);
+ protected
+ procedure Execute; override;
+ public
+ Song : array of TSong; // array of songs
+ Selected : integer; // selected song index
+ constructor create();
+ procedure LoadSongList; // load all songs
+ procedure BrowseDir(Dir: widestring); // should return number of songs in the future
+ procedure Sort(Order: integer);
+ function FindSongFile(Dir, Mask: widestring): widestring;
+ property Processing : boolean read fProcessing;
+ end;
+
+ TCatSongs = class
+ Song: array of TSong; // array of categories with songs
+ Selected: integer; // selected song index
+ Order: integer; // order type (0=title)
+ CatNumShow: integer; // Category Number being seen
+ CatCount: integer; //Number of Categorys
+
+ procedure Refresh; // refreshes arrays by recreating them from Songs array
+// procedure Sort(Order: integer);
+ procedure ShowCategory(Index: integer); // expands all songs in category
+ procedure HideCategory(Index: integer); // hides all songs in category
+ procedure ClickCategoryButton(Index: integer); // uses ShowCategory and HideCategory when needed
+ procedure ShowCategoryList; //Hides all Songs And Show the List of all Categorys
+ function FindNextVisible(SearchFrom:integer): integer; //Find Next visible Song
+ function VisibleSongs: integer; // returns number of visible songs (for tabs)
+ function VisibleIndex(Index: integer): integer; // returns visible song index (skips invisible)
+
+ function SetFilter(FilterStr: String; const fType: Byte): Cardinal;
+ end;
+
+var
+ Songs: TSongs; // all songs
+ CatSongs: TCatSongs; // categorized songs
+ AktSong: TSong; // one song *unknown use)
+
+const
+ IN_ACCESS = $00000001; //* File was accessed */
+ IN_MODIFY = $00000002; //* File was modified */
+ IN_ATTRIB = $00000004; //* Metadata changed */
+ IN_CLOSE_WRITE = $00000008; //* Writtable file was closed */
+ IN_CLOSE_NOWRITE = $00000010; //* Unwrittable file closed */
+ IN_OPEN = $00000020; //* File was opened */
+ IN_MOVED_FROM = $00000040; //* File was moved from X */
+ IN_MOVED_TO = $00000080; //* File was moved to Y */
+ IN_CREATE = $00000100; //* Subfile was created */
+ IN_DELETE = $00000200; //* Subfile was deleted */
+ IN_DELETE_SELF = $00000400; //* Self was deleted */
+
+
+implementation
+
+uses StrUtils,
+ UGraphic,
+ UCovers,
+ UFiles,
+ UMain,
+ UIni;
+
+{$IFDEF DARWIN}
+function AnsiContainsText(const AText, ASubText: string): Boolean;
+begin
+ Result := AnsiPos(AnsiUppercase(ASubText), AnsiUppercase(AText)) > 0;
+end;
+{$ENDIF}
+
+constructor TSongs.create();
+begin
+ inherited create( false );
+ self.freeonterminate := true;
+
+ {$ifdef Delphi}
+ fDirWatch := TDirectoryWatch.create(nil);
+ fDirWatch.OnChange := DoDirChanged;
+ fDirWatch.Directory := SongPath;
+ fDirWatch.WatchSubDirs := true;
+ fDirWatch.active := true;
+ {$ENDIF}
+
+ {$IFDEF linux}
+ (*
+ Thankyou to : http://www.linuxjournal.com/article/8478
+ http://www.tin.org/bin/man.cgi?section=2&topic=inotify_add_watch
+ *)
+(*
+ fNotify := -1;
+ fWatch := -1;
+
+ writeln( 'Calling inotify_init' );
+ fNotify := Do_SysCall( syscall_nr_inotify_init );
+ if ( fNotify < 0 ) then
+ writeln( 'Filesystem change notification - disabled' );
+ writeln( 'Calling inotify_init : '+ inttostr(fNotify) );
+
+ writeln( 'Calling syscall_nr_inotify_init ('+SongPath+')' );
+ fWatch := Do_SysCall( syscall_nr_inotify_init , TSysParam( fNotify ), longint( pchar( SongPath ) ) , IN_MODIFY AND IN_CREATE AND IN_DELETE );
+
+ if (fWatch < 0) then
+ writeln ('inotify_add_watch');
+ writeln( 'Calling syscall_nr_inotify_init : '+ inttostr(fWatch) );
+*)
+ {$endif}
+
+ Setlength(Song, 0);
+end;
+
+procedure TSongs.DoDirChanged(Sender: TObject);
+begin
+ LoadSongList();
+end;
+
+procedure TSongs.Execute();
+var
+ fChangeNotify : THandle;
+begin
+ fParseSongDirectory := true;
+
+ while not self.terminated do
+ begin
+
+ if fParseSongDirectory then
+ begin
+ writeln( 'int_LoadSongList' );
+ int_LoadSongList();
+ end;
+
+ self.suspend;
+ end;
+
+end;
+
+procedure TSongs.int_LoadSongList;
+begin
+ try
+ fProcessing := true;
+ Setlength(Song, 0);
+
+ Log.LogError('SongList', 'Searching For Songs');
+
+ Setlength(Song, 50);
+
+ BrowsePos := 0;
+ // browse directories
+ BrowseDir(SongPath);
+
+ //Set Correct SongArray Length
+ SetLength(Song, BrowsePos);
+
+ if assigned( CatSongs ) then
+ CatSongs.Refresh;
+
+ if assigned( CatCovers ) then
+ CatCovers.Load;
+
+ if assigned( Covers ) then
+ Covers.Load;
+
+ if assigned(ScreenSong) then
+ begin
+ ScreenSong.GenerateThumbnails();
+ ScreenSong.OnShow; // refresh ScreenSong
+ end;
+
+
+ finally
+ Log.LogError('SongList', 'Search Complete');
+
+ fParseSongDirectory := false;
+ fProcessing := false;
+ end;
+end;
+
+
+procedure TSongs.LoadSongList;
+begin
+ fParseSongDirectory := true;
+ 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;
+ {$ENDIF}
+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 ADirent<>Nil then
+ begin
+ With ADirent^ do
+ begin
+
+ if ( d_name[0] <> '.') then
+ BrowseDir( Dir + d_name + pathdelim );
+
+ end;
+ end;
+ Until ADirent=Nil;
+ end;
+
+
+
+ TheDir := FPOpenDir( Dir ); // JB_Unicode - linux
+ if TheDir <> nil then
+ begin
+ repeat
+ ADirent := FPReadDir(TheDir);
+
+ if ( ADirent <> Nil ) AND
+ ( pos( '.txt', ADirent^.d_name ) > -1 ) then
+ begin
+ 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^.d_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}
+
+// Log.LogStatus('Parsing directory: ' + Dir + SR.Name, 'LoadSongList');
+
+
+end;
+
+procedure TSongs.Sort(Order: integer);
+var
+ S: integer;
+ S2: integer;
+ TempSong: TSong;
+begin
+ case Order of
+ sEdition: // by edition
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Edition, Song[S-1].Edition) < 0 then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sGenre: // by genre
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Genre, Song[S-1].Genre) < 0 then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sTitle: // by title
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Title, Song[S-1].Title) < 0 then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+
+ end;
+ sArtist: // by artist
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Artist, Song[S-1].Artist) < 0 then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sFolder: // by folder
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Folder, Song[S-1].Folder) < 0 then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sTitle2: // by title2
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Title, Song[S-1].Title) < 0 then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+
+ end;
+ sArtist2: // by artist2
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Artist, Song[S-1].Artist) < 0 then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sLanguage: // by Language
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if CompareText(Song[S].Language, Song[S-1].Language) < 0 then begin
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+
+ end; // case
+end;
+
+function TSongs.FindSongFile(Dir, Mask: widestring): widestring;
+var
+ SR: TSearchRec; // for parsing song directory
+begin
+ Result := '';
+ if FindFirst(Dir + Mask, faDirectory, SR) = 0 then begin
+ Result := SR.Name;
+ end; // if
+ FindClose(SR);
+end;
+
+procedure TCatSongs.Refresh;
+var
+ S: integer; // temporary song index
+ CatLen: integer; // length of CatSongs.Song
+ Letter: char; // current letter for sorting using letter
+ SS: string; // current edition for sorting using edition, genre etc.
+ Order: integer; // number used for ordernum
+ Letter2: char; //
+ CatNumber:integer; // Number of Song in Category
+begin
+ CatNumShow := -1;
+// Songs.Sort(0); // by title
+
+case Ini.Sorting of
+ sEdition: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sEdition);
+ end;
+ sGenre: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sGenre);
+ end;
+ sLanguage: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sLanguage);
+ end;
+ sFolder: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sFolder);
+ end;
+ sTitle: Songs.Sort(sTitle);
+ sArtist: Songs.Sort(sArtist);
+ sTitle2: Songs.Sort(sTitle2); // by title2
+ sArtist2: Songs.Sort(sArtist2); // by artist2
+
+ end; // case
+
+
+ Letter := ' ';
+ SS := '';
+ Order := 0;
+ CatNumber := 0;
+
+ //Songs leeren
+ SetLength (Song, 0);
+
+ for S := Low(Songs.Song) to High(Songs.Song) do begin
+ if (Ini.Tabs = 1) then
+ if (Ini.Sorting = sEdition) and (CompareText(SS, Songs.Song[S].Edition) <> 0) then begin
+ // add Category Button
+ Inc(Order);
+ SS := Songs.Song[S].Edition;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + SS + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+
+
+ // 0.4.3
+ // if SS = 'Singstar' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Part 2' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar German' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Spanish' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Italian' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar French' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Party' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Party.jpg';
+ // if SS = 'Singstar Popworld' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Popworld.jpg';
+ // if SS = 'Singstar 80s' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar 80s.jpg';
+ // if SS = 'Singstar 80s Polish' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar 80s.jpg';
+ // if SS = 'Singstar Rocks' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Rocks.jpg';
+ // if SS = 'Singstar Anthems' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Anthems.jpg';
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';//}
+
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sGenre) and (CompareText(SS, Songs.Song[S].Genre) <> 0) then begin
+ // add Genre Button
+ Inc(Order);
+ SS := Songs.Song[S].Genre;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := SS;
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sLanguage) and (CompareText(SS, Songs.Song[S].Language) <> 0) then begin
+ // add Language Button
+ Inc(Order);
+ SS := Songs.Song[S].Language;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := SS;
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sTitle) and
+ (Length(Songs.Song[S].Title)>=1) and
+ (Letter <> UpperCase(Songs.Song[S].Title)[1]) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := Uppercase(Songs.Song[S].Title)[1];
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> UpperCase(Songs.Song[S].Artist)[1]) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := UpperCase(Songs.Song[S].Artist)[1];
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sFolder) and (CompareText(SS, Songs.Song[S].Folder) <> 0) then begin
+ // 0.5.0: add folder tab
+ Inc(Order);
+ SS := Songs.Song[S].Folder;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := SS;
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sTitle2) AND (Length(Songs.Song[S].Title)>=1) then begin
+ if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Title)[1];
+ if (Letter <> Letter2) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := Letter2;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end;
+ end
+
+ else if (Ini.Sorting = sArtist2) AND (Length(Songs.Song[S].Artist)>=1) then begin
+ if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Artist)[1];
+ if (Letter <> Letter2) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := Letter2;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end;
+ end;
+
+
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+
+ Inc (CatNumber); //Increase Number in Cat
+
+ CatSongs.Song[CatLen] := Songs.Song[S];
+ CatSongs.Song[CatLen].OrderNum := Order; // assigns category
+ CatSongs.Song[CatLen].CatNumber := CatNumber;
+
+ if (Ini.Tabs = 0) then CatSongs.Song[CatLen].Visible := true
+ else if (Ini.Tabs = 1) then CatSongs.Song[CatLen].Visible := false;
+// if (Ini.Tabs = 1) and (Order = 1) then CatSongs.Song[CatLen].Visible := true; // open first tab
+//CatSongs.Song[CatLen].Visible := true;
+
+ end;
+//CatNumber Patch - Set CatNumber of Last Category
+if (ini.Tabs_at_startup = 1) And (high(Song) >=1) then
+ Song[CatLen - CatNumber].CatNumber := CatNumber;//Set CatNumber of Categroy
+//CatCount Patch
+CatCount := Order;
+end;
+
+procedure TCatSongs.ShowCategory(Index: integer);
+var
+ S: integer; // song
+begin
+ CatNumShow := Index;
+ for S := 0 to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[S].OrderNum = Index) AND (Not CatSongs.Song[S].Main) then
+ CatSongs.Song[S].Visible := true
+ else
+ CatSongs.Song[S].Visible := false;
+ end;
+end;
+
+procedure TCatSongs.HideCategory(Index: integer); // hides all songs in category
+var
+ S: integer; // song
+begin
+ for S := 0 to high(CatSongs.Song) do begin
+ if not CatSongs.Song[S].Main then
+ CatSongs.Song[S].Visible := false // hides all at now
+ end;
+end;
+
+procedure TCatSongs.ClickCategoryButton(Index: integer);
+var
+ Num, S: integer;
+begin
+ Num := CatSongs.Song[Index].OrderNum;
+ if Num <> CatNumShow then
+ begin
+ ShowCategory(Num);
+ end
+ else begin
+ ShowCategoryList;
+ end;
+end;
+
+//Hide Categorys when in Category Hack
+procedure TCatSongs.ShowCategoryList;
+var
+ Num, S: integer;
+begin
+ //Hide All Songs Show All Cats
+ for S := 0 to high(CatSongs.Song) do begin
+ if CatSongs.Song[S].Main then
+ CatSongs.Song[S].Visible := true
+ else
+ CatSongs.Song[S].Visible := false
+ end;
+ CatSongs.Selected := CatNumShow; //Show last shown Category
+ CatNumShow := -1;
+end;
+//Hide Categorys when in Category Hack End
+
+//Wrong song selected when tabs on bug
+function TCatSongs.FindNextVisible(SearchFrom:integer): integer;//Find next Visible Song
+var
+ I: Integer;
+ begin
+ Result := -1;
+ I := SearchFrom + 1;
+ while not CatSongs.Song[I].Visible do
+ begin
+ Inc (I);
+ if (I>high(CatSongs.Song)) then
+ I := low(CatSongs.Song);
+ if (I = SearchFrom) then //Make One Round and no song found->quit
+ break;
+ end;
+ end;
+//Wrong song selected when tabs on bug End
+
+function TCatSongs.VisibleSongs: integer;
+var
+ S: integer; // song
+begin
+ Result := 0;
+ for S := 0 to high(CatSongs.Song) do
+ if CatSongs.Song[S].Visible = true then Inc(Result);
+end;
+
+function TCatSongs.VisibleIndex(Index: integer): integer;
+var
+ S: integer; // song
+begin
+ Result := 0;
+ for S := 0 to Index-1 do
+ if CatSongs.Song[S].Visible = true then Inc(Result);
+end;
+
+function TCatSongs.SetFilter(FilterStr: String; const fType: Byte): Cardinal;
+var
+ I, J: Integer;
+ cString: String;
+ SearchStr: Array of String;
+begin
+ {fType: 0: All
+ 1: Title
+ 2: Artist}
+ FilterStr := Trim(FilterStr);
+ if FilterStr<>'' then begin
+ Result := 0;
+ //Create Search Array
+ SetLength(SearchStr, 1);
+ I := Pos (' ', FilterStr);
+ While (I <> 0) do
+ begin
+ SetLength (SearchStr, Length(SearchStr) + 1);
+ cString := Copy(FilterStr, 1, I-1);
+ if (cString <> ' ') AND (cString <> '') then
+ SearchStr[High(SearchStr)-1] := cString;
+ Delete (FilterStr, 1, I);
+
+ I := Pos (' ', FilterStr);
+ end;
+ //Copy last Word
+ if (FilterStr <> ' ') AND (FilterStr <> '') then
+ SearchStr[High(SearchStr)] := FilterStr;
+
+ for I:=0 to High(Song) do begin
+ if not Song[i].Main then
+ begin
+ case fType of
+ 0: cString := Song[I].Artist + ' ' + Song[i].Title + ' ' + Song[i].Folder;
+ 1: cString := Song[I].Title;
+ 2: cString := Song[I].Artist;
+ end;
+ Song[i].Visible:=True;
+ //Look for every Searched Word
+ For J := 0 to High(SearchStr) do
+ begin
+ Song[i].Visible := Song[i].Visible AND AnsiContainsText(cString, SearchStr[J])
+ end;
+ if Song[i].Visible then
+ Inc(Result);
+ end
+ else
+ Song[i].Visible:=False;
+ end;
+ CatNumShow := -2;
+ end
+ else begin
+ for i:=0 to High(Song) do begin
+ Song[i].Visible:=(Ini.Tabs=1)=Song[i].Main;
+ CatNumShow := -1;
+ end;
+ Result := 0;
+ end;
+end;
+
+end.
diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1 b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
index b8f1379d..3dd9e158 100644
--- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
+++ b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1
@@ -190,6 +190,46 @@
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
+ <string>2C0C2C180CDC7312004A651F</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>USongs.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C0C2C190CDC7312004A651F</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>USongs.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CD3B28C0CDC76B6001F1030</string>
+ <key>history</key>
+ <array>
+ <string>2CD3B2550CDC7564001F1030</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {797, 748}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>84 171 797 789 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
<string>2CF552990CDA426600627463</string>
<key>PBXProjectModuleLabel</key>
<string>UMain.pas</string>
@@ -204,10 +244,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2BB0CDBB0F2002CC3B0</string>
+ <string>2CD3B28D0CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2C4FA2B10CDBB0CF002CC3B0</string>
+ <string>2C0C2C430CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -244,10 +284,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2BC0CDBB0F2002CC3B0</string>
+ <string>2CD3B28E0CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2CDC71AC0CDBA6300018F966</string>
+ <string>2C0C2C450CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -284,10 +324,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2BD0CDBB0F2002CC3B0</string>
+ <string>2CD3B28F0CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2CDC71AE0CDBA6300018F966</string>
+ <string>2C0C2C460CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -324,10 +364,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2BE0CDBB0F2002CC3B0</string>
+ <string>2CD3B2900CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2CDC71AF0CDBA6300018F966</string>
+ <string>2C0C2C470CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -364,10 +404,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2BF0CDBB0F2002CC3B0</string>
+ <string>2CD3B2910CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2CDC71B00CDBA6300018F966</string>
+ <string>2C0C2C480CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -404,10 +444,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2C00CDBB0F2002CC3B0</string>
+ <string>2CD3B2920CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2CDC71B10CDBA6300018F966</string>
+ <string>2C0C2C490CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -444,10 +484,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2C10CDBB0F2002CC3B0</string>
+ <string>2CD3B2930CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2CDC71B20CDBA6300018F966</string>
+ <string>2C0C2C4A0CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -484,10 +524,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2C4FA2C20CDBB0F2002CC3B0</string>
+ <string>2CD3B2940CDC76B6001F1030</string>
<key>history</key>
<array>
- <string>2CDC71B30CDBA6300018F966</string>
+ <string>2C0C2C4B0CDC73BE004A651F</string>
</array>
</dict>
<key>SplitCount</key>
@@ -691,9 +731,9 @@
</array>
<key>TableOfContents</key>
<array>
- <string>2C4FA2940CDBAB21002CC3B0</string>
+ <string>2CD3B23F0CDC7545001F1030</string>
<string>1CE0B1FE06471DED0097A5F4</string>
- <string>2C4FA2950CDBAB21002CC3B0</string>
+ <string>2CD3B2400CDC7545001F1030</string>
<string>1CE0B20306471E060097A5F4</string>
<string>1CE0B20506471E060097A5F4</string>
</array>
@@ -827,8 +867,11 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
+ <string>2CD3B2610CDC7564001F1030</string>
+ <string>2CD3B2620CDC7564001F1030</string>
+ <string>2CDD4BFC0CB948FC00549FAC</string>
<string>2CDD4B730CB935C700549FAC</string>
- <string>2C4FA2A50CDBAB21002CC3B0</string>
+ <string>2CD3B2500CDC7545001F1030</string>
<string>2CF5528D0CDA426600627463</string>
<string>2CF553750CDA575B00627463</string>
<string>2CF553720CDA575B00627463</string>
@@ -836,9 +879,11 @@
<string>2CF552930CDA426600627463</string>
<string>2CF552960CDA426600627463</string>
<string>2CF5536C0CDA575B00627463</string>
- <string>1CD10A99069EF8BA00B06720</string>
<string>2CF552990CDA426600627463</string>
+ <string>1C0AD2B3069F1EA900FABCE6</string>
<string>/Users/eddie/Projekte/UltraStarDX/trunk/Game/Code/MacOSX/UltraStarDX.xcodeproj</string>
+ <string>2C0C2C180CDC7312004A651F</string>
+ <string>1CD10A99069EF8BA00B06720</string>
</array>
<key>WindowString</key>
<string>772 270 817 753 0 0 1680 1028 </string>
@@ -869,14 +914,14 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{0, 0}, {1318, 344}}</string>
+ <string>{{0, 0}, {1346, 566}}</string>
<key>RubberWindowFrame</key>
- <string>312 244 1318 626 0 0 1680 1028 </string>
+ <string>106 169 1346 848 0 0 1680 1028 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
- <string>344pt</string>
+ <string>566pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
@@ -893,9 +938,9 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{0, 349}, {1318, 236}}</string>
+ <string>{{0, 571}, {1346, 236}}</string>
<key>RubberWindowFrame</key>
- <string>312 244 1318 626 0 0 1680 1028 </string>
+ <string>106 169 1346 848 0 0 1680 1028 </string>
</dict>
<key>Module</key>
<string>PBXBuildResultsModule</string>
@@ -904,7 +949,7 @@
</dict>
</array>
<key>Proportion</key>
- <string>585pt</string>
+ <string>807pt</string>
</dict>
</array>
<key>Name</key>
@@ -918,14 +963,14 @@
<key>TableOfContents</key>
<array>
<string>2CDD4B730CB935C700549FAC</string>
- <string>2C4FA2BA0CDBB0CF002CC3B0</string>
+ <string>2CD3B25F0CDC7564001F1030</string>
<string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.build</string>
<key>WindowString</key>
- <string>312 244 1318 626 0 0 1680 1028 </string>
+ <string>106 169 1346 848 0 0 1680 1028 </string>
<key>WindowToolGUID</key>
<string>2CDD4B730CB935C700549FAC</string>
<key>WindowToolIsVisible</key>
@@ -960,8 +1005,8 @@
<string>yes</string>
<key>sizes</key>
<array>
- <string>{{0, 0}, {354, 414}}</string>
- <string>{{354, 0}, {610, 414}}</string>
+ <string>{{0, 0}, {347, 414}}</string>
+ <string>{{347, 0}, {617, 414}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
@@ -1024,14 +1069,14 @@
<key>TableOfContents</key>
<array>
<string>1CD10A99069EF8BA00B06720</string>
- <string>2C4FA29F0CDBAB21002CC3B0</string>
+ <string>2CD3B24A0CDC7545001F1030</string>
<string>1C162984064C10D400B95A72</string>
- <string>2C4FA2A00CDBAB21002CC3B0</string>
- <string>2C4FA2A10CDBAB21002CC3B0</string>
- <string>2C4FA2A20CDBAB21002CC3B0</string>
- <string>2C4FA2A30CDBAB21002CC3B0</string>
- <string>2C4FA2A40CDBAB21002CC3B0</string>
- <string>2C4FA2A50CDBAB21002CC3B0</string>
+ <string>2CD3B24B0CDC7545001F1030</string>
+ <string>2CD3B24C0CDC7545001F1030</string>
+ <string>2CD3B24D0CDC7545001F1030</string>
+ <string>2CD3B24E0CDC7545001F1030</string>
+ <string>2CD3B24F0CDC7545001F1030</string>
+ <string>2CD3B2500CDC7545001F1030</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debug</string>
@@ -1185,7 +1230,7 @@
<key>TableOfContents</key>
<array>
<string>2CDD4BFC0CB948FC00549FAC</string>
- <string>2CDC71900CDB9D2D0018F966</string>
+ <string>2CD3B2600CDC7564001F1030</string>
<string>1C78EAAC065D492600B07095</string>
</array>
<key>WindowString</key>
@@ -1280,9 +1325,9 @@
<key>TableOfContents</key>
<array>
<string>1C0AD2B3069F1EA900FABCE6</string>
- <string>2C6FEC9A0CC8021800D0C913</string>
+ <string>2CD3B2510CDC7545001F1030</string>
<string>1CD0528B0623707200166675</string>
- <string>2C6FEC9B0CC8021800D0C913</string>
+ <string>2CD3B2520CDC7545001F1030</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.run</string>
@@ -1291,7 +1336,7 @@
<key>WindowToolGUID</key>
<string>1C0AD2B3069F1EA900FABCE6</string>
<key>WindowToolIsVisible</key>
- <false/>
+ <true/>
</dict>
<dict>
<key>FirstTimeWindowDisplayed</key>
diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
index 3bb5dffc..af8b639d 100644
--- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
+++ b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser
@@ -1,5 +1,85 @@
// !$*UTF8*$!
{
+ 2C0C2C430CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */;
+ name = "UMain.pas: 15";
+ rLen = 0;
+ rLoc = 198;
+ rType = 0;
+ vrLen = 637;
+ vrLoc = 0;
+ };
+ 2C0C2C450CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */;
+ name = "UltraStarDX.pas: 6";
+ rLen = 0;
+ rLoc = 117;
+ rType = 0;
+ vrLen = 131;
+ vrLoc = 0;
+ };
+ 2C0C2C460CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2C4D9C640CC9EC8C0031092D /* UAudio_FFMpeg.pas */;
+ name = "UAudio_FFMpeg.pas: 952";
+ rLen = 0;
+ rLoc = 22697;
+ rType = 0;
+ vrLen = 1224;
+ vrLoc = 21473;
+ };
+ 2C0C2C470CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2C4D9C630CC9EC8C0031092D /* UAudio_bass.pas */;
+ name = "nux ... is t";
+ rLen = 12;
+ rLoc = 3202;
+ rType = 0;
+ vrLen = 1266;
+ vrLoc = 15619;
+ };
+ 2C0C2C480CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */;
+ name = "sdl_image.pas: 130";
+ rLen = 0;
+ rLoc = 8020;
+ rType = 0;
+ vrLen = 832;
+ vrLoc = 7978;
+ };
+ 2C0C2C490CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 98B8BE5C0B1F974F00162019 /* sdl.pas */;
+ name = "sdl.pas: 250";
+ rLen = 0;
+ rLoc = 16506;
+ rType = 0;
+ vrLen = 886;
+ vrLoc = 16376;
+ };
+ 2C0C2C4A0CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */;
+ name = "ScaledTexture(TexSur";
+ rLen = 20;
+ rLoc = 11816;
+ rType = 0;
+ vrLen = 1220;
+ vrLoc = 11189;
+ };
+ 2C0C2C4B0CDC73BE004A651F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2C4D9E090CC9EF840031092D /* Windows.pas */;
+ name = "Windows.pas: 114";
+ rLen = 0;
+ rLoc = 2832;
+ rType = 0;
+ vrLen = 1182;
+ vrLoc = 2090;
+ };
2C4D9C620CC9EC8C0031092D /* TextGL.pas */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {758, 7742}}";
@@ -26,9 +106,9 @@
};
2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {764, 2128}}";
- sepNavSelRange = "{352, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavIntBoundsRect = "{{0, 0}, {923, 2128}}";
+ sepNavSelRange = "{1154, 0}";
+ sepNavVisRect = "{{0, 354}, {923, 342}}";
sepNavWindowFrame = "{{61, 136}, {797, 845}}";
};
};
@@ -50,9 +130,9 @@
};
2C4D9C680CC9EC8C0031092D /* UCore.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1136, 6888}}";
- sepNavSelRange = "{13272, 0}";
- sepNavVisRect = "{{0, 6145}, {758, 716}}";
+ sepNavIntBoundsRect = "{{0, 0}, {1305, 7028}}";
+ sepNavSelRange = "{12989, 64}";
+ sepNavVisRect = "{{0, 6320}, {1305, 534}}";
sepNavWindowFrame = "{{107, 94}, {797, 845}}";
};
};
@@ -74,9 +154,9 @@
};
2C4D9C6B0CC9EC8C0031092D /* UDataBase.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {4058, 5026}}";
- sepNavSelRange = "{60, 19}";
- sepNavVisRect = "{{0, 0}, {1277, 312}}";
+ sepNavIntBoundsRect = "{{0, 0}, {4058, 5082}}";
+ sepNavSelRange = "{1600, 0}";
+ sepNavVisRect = "{{0, 1250}, {923, 342}}";
sepNavWindowFrame = "{{153, 52}, {797, 845}}";
};
};
@@ -106,9 +186,9 @@
};
2C4D9C6F0CC9EC8C0031092D /* UGraphic.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 9800}}";
- sepNavSelRange = "{872, 16}";
- sepNavVisRect = "{{0, 391}, {758, 716}}";
+ sepNavIntBoundsRect = "{{0, 0}, {923, 10444}}";
+ sepNavSelRange = "{15582, 0}";
+ sepNavVisRect = "{{0, 6612}, {923, 342}}";
sepNavWindowFrame = "{{38, 157}, {797, 845}}";
};
};
@@ -146,9 +226,9 @@
};
2C4D9C740CC9EC8C0031092D /* ULanguage.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {758, 3290}}";
- sepNavSelRange = "{46, 0}";
- sepNavVisRect = "{{0, 0}, {758, 716}}";
+ sepNavIntBoundsRect = "{{0, 0}, {923, 3346}}";
+ sepNavSelRange = "{1257, 0}";
+ sepNavVisRect = "{{0, 914}, {923, 342}}";
sepNavWindowFrame = "{{153, 52}, {797, 845}}";
};
};
@@ -194,9 +274,9 @@
};
2C4D9C7B0CC9EC8C0031092D /* UMain.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1013, 15078}}";
- sepNavSelRange = "{3441, 0}";
- sepNavVisRect = "{{0, 1682}, {1013, 614}}";
+ sepNavIntBoundsRect = "{{0, 0}, {1013, 15456}}";
+ sepNavSelRange = "{198, 0}";
+ sepNavVisRect = "{{0, 0}, {1013, 614}}";
sepNavWindowFrame = "{{222, 91}, {1052, 743}}";
};
};
@@ -298,9 +378,9 @@
};
2C4D9C890CC9EC8C0031092D /* USongs.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {950, 14616}}";
- sepNavSelRange = "{7664, 0}";
- sepNavVisRect = "{{0, 3738}, {758, 716}}";
+ sepNavIntBoundsRect = "{{0, 0}, {950, 14686}}";
+ sepNavSelRange = "{503, 0}";
+ sepNavVisRect = "{{0, 2095}, {758, 716}}";
sepNavWindowFrame = "{{84, 115}, {797, 845}}";
};
};
@@ -314,9 +394,9 @@
};
2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {1730, 16016}}";
- sepNavSelRange = "{11823, 20}";
- sepNavVisRect = "{{0, 5156}, {577, 612}}";
+ sepNavIntBoundsRect = "{{0, 0}, {1730, 15960}}";
+ sepNavSelRange = "{11816, 20}";
+ sepNavVisRect = "{{0, 4988}, {577, 612}}";
sepNavWindowFrame = "{{15, 282}, {616, 741}}";
};
};
@@ -503,27 +583,37 @@
sepNavWindowFrame = "{{15, 282}, {616, 741}}";
};
};
- 2C4FA2B10CDBB0CF002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B2550CDC7564001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
- fRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */;
- name = "UMain.pas: 148";
+ fRef = 2C4D9C890CC9EC8C0031092D /* USongs.pas */;
+ name = "USongs.pas: 39";
rLen = 0;
- rLoc = 3441;
+ rLoc = 503;
rType = 0;
- vrLen = 1295;
- vrLoc = 2495;
+ vrLen = 753;
+ vrLoc = 0;
};
- 2C4FA2BB0CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B28C0CDC76B6001F1030 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2C4D9C890CC9EC8C0031092D /* USongs.pas */;
+ name = "USongs.pas: 39";
+ rLen = 0;
+ rLoc = 503;
+ rType = 0;
+ vrLen = 1403;
+ vrLoc = 4615;
+ };
+ 2CD3B28D0CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */;
- name = "UMain.pas: 148";
+ name = "UMain.pas: 15";
rLen = 0;
- rLoc = 3441;
+ rLoc = 198;
rType = 0;
- vrLen = 1295;
- vrLoc = 2495;
+ vrLen = 637;
+ vrLoc = 0;
};
- 2C4FA2BC0CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B28E0CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */;
name = "UltraStarDX.pas: 6";
@@ -533,7 +623,7 @@
vrLen = 131;
vrLoc = 0;
};
- 2C4FA2BD0CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B28F0CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 2C4D9C640CC9EC8C0031092D /* UAudio_FFMpeg.pas */;
name = "UAudio_FFMpeg.pas: 952";
@@ -543,7 +633,7 @@
vrLen = 1224;
vrLoc = 21473;
};
- 2C4FA2BE0CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B2900CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 2C4D9C630CC9EC8C0031092D /* UAudio_bass.pas */;
name = "nux ... is t";
@@ -553,7 +643,7 @@
vrLen = 1266;
vrLoc = 15619;
};
- 2C4FA2BF0CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B2910CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */;
name = "sdl_image.pas: 130";
@@ -563,7 +653,7 @@
vrLen = 832;
vrLoc = 7978;
};
- 2C4FA2C00CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B2920CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 98B8BE5C0B1F974F00162019 /* sdl.pas */;
name = "sdl.pas: 250";
@@ -573,17 +663,17 @@
vrLen = 886;
vrLoc = 16376;
};
- 2C4FA2C10CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B2930CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */;
- name = "TempSurface:=TexSur";
+ name = "ScaledTexture(TexSur";
rLen = 20;
- rLoc = 11823;
+ rLoc = 11816;
rType = 0;
vrLen = 1220;
- vrLoc = 11066;
+ vrLoc = 11189;
};
- 2C4FA2C20CDBB0F2002CC3B0 /* PBXTextBookmark */ = {
+ 2CD3B2940CDC76B6001F1030 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 2C4D9E090CC9EF840031092D /* Windows.pas */;
name = "Windows.pas: 114";
@@ -601,90 +691,6 @@
sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
};
};
- 2CDC71950CDB9D430018F966 /* UMain.pas:156 */ = {
- isa = PBXFileBreakpoint;
- actions = (
- );
- breakpointStyle = 0;
- continueAfterActions = 0;
- delayBeforeContinue = 0;
- fileReference = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */;
- hitCount = 1;
- lineNumber = 156;
- location = UltraStarDX;
- modificationTime = 215719249.543694;
- state = 1;
- };
- 2CDC71AC0CDBA6300018F966 /* PBXTextBookmark */ = {
- isa = PBXTextBookmark;
- fRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */;
- name = "UltraStarDX.pas: 6";
- rLen = 0;
- rLoc = 117;
- rType = 0;
- vrLen = 131;
- vrLoc = 0;
- };
- 2CDC71AE0CDBA6300018F966 /* PBXTextBookmark */ = {
- isa = PBXTextBookmark;
- fRef = 2C4D9C640CC9EC8C0031092D /* UAudio_FFMpeg.pas */;
- name = "UAudio_FFMpeg.pas: 952";
- rLen = 0;
- rLoc = 22697;
- rType = 0;
- vrLen = 1224;
- vrLoc = 21473;
- };
- 2CDC71AF0CDBA6300018F966 /* PBXTextBookmark */ = {
- isa = PBXTextBookmark;
- fRef = 2C4D9C630CC9EC8C0031092D /* UAudio_bass.pas */;
- name = "nux ... is t";
- rLen = 12;
- rLoc = 3202;
- rType = 0;
- vrLen = 1266;
- vrLoc = 15619;
- };
- 2CDC71B00CDBA6300018F966 /* PBXTextBookmark */ = {
- isa = PBXTextBookmark;
- fRef = 2C4D9DEC0CC9EF0A0031092D /* sdl_image.pas */;
- name = "sdl_image.pas: 130";
- rLen = 0;
- rLoc = 8020;
- rType = 0;
- vrLen = 832;
- vrLoc = 7978;
- };
- 2CDC71B10CDBA6300018F966 /* PBXTextBookmark */ = {
- isa = PBXTextBookmark;
- fRef = 98B8BE5C0B1F974F00162019 /* sdl.pas */;
- name = "sdl.pas: 250";
- rLen = 0;
- rLoc = 16506;
- rType = 0;
- vrLen = 886;
- vrLoc = 16376;
- };
- 2CDC71B20CDBA6300018F966 /* PBXTextBookmark */ = {
- isa = PBXTextBookmark;
- fRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */;
- name = "TempSurface:=TexSur";
- rLen = 20;
- rLoc = 11823;
- rType = 0;
- vrLen = 1220;
- vrLoc = 11066;
- };
- 2CDC71B30CDBA6300018F966 /* PBXTextBookmark */ = {
- isa = PBXTextBookmark;
- fRef = 2C4D9E090CC9EF840031092D /* Windows.pas */;
- name = "Windows.pas: 114";
- rLen = 0;
- rLoc = 2832;
- rType = 0;
- vrLen = 1182;
- vrLoc = 2090;
- };
2CDD439C0CBBE92D00F364DE /* UMain.pas */ = {
isa = PBXFileReference;
fileEncoding = 30;
@@ -738,8 +744,6 @@
name = "Project Breakpoints";
objects = (
2CDEA8080CBD7D920096994C /* UMain.pas:293 */,
- 2CF553A20CDA59BB00627463 /* UltraStarDX.pas:6 */,
- 2CDC71950CDB9D430018F966 /* UMain.pas:156 */,
);
};
2CDEA8080CBD7D920096994C /* UMain.pas:293 */ = {
@@ -753,7 +757,7 @@
hitCount = 1;
lineNumber = 293;
location = UltraStarDX;
- modificationTime = 215719244.976517;
+ modificationTime = 215774704.034014;
state = 1;
};
2CF54F430CDA1B2B00627463 /* UScreenCredits.pas */ = {
@@ -1116,20 +1120,6 @@
sepNavWindowFrame = "{{38, 259}, {1052, 743}}";
};
};
- 2CF553A20CDA59BB00627463 /* UltraStarDX.pas:6 */ = {
- isa = PBXFileBreakpoint;
- actions = (
- );
- breakpointStyle = 0;
- continueAfterActions = 0;
- delayBeforeContinue = 0;
- fileReference = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */;
- hitCount = 1;
- lineNumber = 6;
- location = UltraStarDX;
- modificationTime = 215719246.5172511;
- state = 1;
- };
9845B6590B1F9B9E0084DD62 /* SDL.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {948, 1330}}";
@@ -1149,8 +1139,8 @@
98B8BE750B1F97F800162019 /* SDLMain.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {948, 5390}}";
- sepNavSelRange = "{558, 0}";
- sepNavVisRect = "{{0, 21}, {948, 730}}";
+ sepNavSelRange = "{6150, 21}";
+ sepNavVisRect = "{{0, 2650}, {948, 730}}";
sepNavWindowFrame = "{{15, 164}, {987, 859}}";
};
};
@@ -1166,8 +1156,6 @@
);
breakpoints = (
2CDEA8080CBD7D920096994C /* UMain.pas:293 */,
- 2CF553A20CDA59BB00627463 /* UltraStarDX.pas:6 */,
- 2CDC71950CDB9D430018F966 /* UMain.pas:156 */,
);
breakpointsGroup = 2CDD4B7F0CB9394600549FAC /* XCBreakpointsBucket */;
codeSenseManager = 2CDD4B6A0CB9357000549FAC /* Code sense */;
@@ -1273,26 +1261,28 @@
PBXFileDataSource_Warnings_ColumnID,
);
};
- PBXPerProjectTemplateStateSaveDate = 215722768;
- PBXWorkspaceStateSaveDate = 215722768;
+ PBXPerProjectTemplateStateSaveDate = 215774521;
+ PBXWorkspaceStateSaveDate = 215774521;
};
perUserProjectItems = {
- 2C4FA2B10CDBB0CF002CC3B0 /* PBXTextBookmark */ = 2C4FA2B10CDBB0CF002CC3B0 /* PBXTextBookmark */;
- 2C4FA2BB0CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2BB0CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2C4FA2BC0CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2BC0CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2C4FA2BD0CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2BD0CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2C4FA2BE0CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2BE0CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2C4FA2BF0CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2BF0CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2C4FA2C00CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2C00CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2C4FA2C10CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2C10CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2C4FA2C20CDBB0F2002CC3B0 /* PBXTextBookmark */ = 2C4FA2C20CDBB0F2002CC3B0 /* PBXTextBookmark */;
- 2CDC71AC0CDBA6300018F966 /* PBXTextBookmark */ = 2CDC71AC0CDBA6300018F966 /* PBXTextBookmark */;
- 2CDC71AE0CDBA6300018F966 /* PBXTextBookmark */ = 2CDC71AE0CDBA6300018F966 /* PBXTextBookmark */;
- 2CDC71AF0CDBA6300018F966 /* PBXTextBookmark */ = 2CDC71AF0CDBA6300018F966 /* PBXTextBookmark */;
- 2CDC71B00CDBA6300018F966 /* PBXTextBookmark */ = 2CDC71B00CDBA6300018F966 /* PBXTextBookmark */;
- 2CDC71B10CDBA6300018F966 /* PBXTextBookmark */ = 2CDC71B10CDBA6300018F966 /* PBXTextBookmark */;
- 2CDC71B20CDBA6300018F966 /* PBXTextBookmark */ = 2CDC71B20CDBA6300018F966 /* PBXTextBookmark */;
- 2CDC71B30CDBA6300018F966 /* PBXTextBookmark */ = 2CDC71B30CDBA6300018F966 /* PBXTextBookmark */;
+ 2C0C2C430CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C430CDC73BE004A651F /* PBXTextBookmark */;
+ 2C0C2C450CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C450CDC73BE004A651F /* PBXTextBookmark */;
+ 2C0C2C460CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C460CDC73BE004A651F /* PBXTextBookmark */;
+ 2C0C2C470CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C470CDC73BE004A651F /* PBXTextBookmark */;
+ 2C0C2C480CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C480CDC73BE004A651F /* PBXTextBookmark */;
+ 2C0C2C490CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C490CDC73BE004A651F /* PBXTextBookmark */;
+ 2C0C2C4A0CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C4A0CDC73BE004A651F /* PBXTextBookmark */;
+ 2C0C2C4B0CDC73BE004A651F /* PBXTextBookmark */ = 2C0C2C4B0CDC73BE004A651F /* PBXTextBookmark */;
+ 2CD3B2550CDC7564001F1030 /* PBXTextBookmark */ = 2CD3B2550CDC7564001F1030 /* PBXTextBookmark */;
+ 2CD3B28C0CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B28C0CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B28D0CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B28D0CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B28E0CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B28E0CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B28F0CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B28F0CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B2900CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B2900CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B2910CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B2910CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B2920CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B2920CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B2930CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B2930CDC76B6001F1030 /* PBXTextBookmark */;
+ 2CD3B2940CDC76B6001F1030 /* PBXTextBookmark */ = 2CD3B2940CDC76B6001F1030 /* PBXTextBookmark */;
};
sourceControlManager = 2CDD4B690CB9357000549FAC /* Source Control */;
userBuildSettings = {