From 5ed6620bad808381fce94f2cd67ee911b4d45bff Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Wed, 21 Mar 2007 19:19:04 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 326 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 Game/Code/Classes/UFiles.pas (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas new file mode 100644 index 00000000..61fdab03 --- /dev/null +++ b/Game/Code/Classes/UFiles.pas @@ -0,0 +1,326 @@ +unit UFiles; + +interface + +uses USongs, SysUtils, ULog, UMusic; + +//procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs +function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header +function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header +procedure ClearSong(var Song: TSong); //Clears Song Header values + +//procedure CzyscNuty; +//function WczytajCzesci(Name: string): boolean; +//function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; +//function SaveSongDebug(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; + +var + {//Absolute Paths + GamePath: string; + SoundPath: string; + SongPath: string; + LogPath: string; + ThemePath: string; + ScreenshotsPath: string; + CoversPath: string; + LanguagesPath: string; //} + + SongFile: TextFile; // all procedures in this unit operates on this file + FileLineNo: integer; //Line which is readed at Last, for error reporting + + {// variables available for all procedures + Base: array[0..1] of integer; + Rel: array[0..1] of integer;//} + Mult: integer = 1; + MultBPM: integer = 4; + +implementation +uses TextGL, UIni, UMain, UPliki; + + //Function sets All Absolute Paths eg. for Songs +{procedure InitializePaths; +begin + GamePath := ExtractFilePath(ParamStr(0)); + SoundPath := GamePath + 'Sounds\'; + SongPath := GamePath + 'Songs\'; + LogPath := GamePath; + ThemePath := GamePath + 'Themes\'; + ScreenshotsPath := GamePath + 'Screenshots\'; + CoversPath := GamePath + 'Covers\'; + LanguagesPath := GamePath + 'Languages\'; + + DecimalSeparator := ','; +end;} + + //Clears Song Header values +procedure ClearSong(var Song: TSong); +begin + //Main Information + Song.Title := ''; + Song.Artist := ''; + + //Sortings: + Song.Genre := 'Unknown'; + Song.Edition := 'Unknown'; + Song.Language := 'Unknown'; //Language Patch + + //Required Information + Song.Mp3 := ''; + Song.BPM := 0; + Song.GAP := 0; + Song.Start := 0; + Song.Finish := 0; + + //Additional Information + Song.Background := ''; + Song.Video := ''; + Song.VideoGAP := 0; + Song.NotesGAP := 0; + Song.Resolution := 4; + Song.Creator := ''; +end; + + //Reads Standard TXT Header +function ReadTXTHeader(var Song: TSong): boolean; +var +Line, Identifier, Value: String; +Temp: word; +Done: byte; +begin + Result := true; + + //Read first Line + ReadLn (SongFile, Line); + + if (Length(Line)<=0) then + begin + Log.LogError('File Starts with Empty Line: ' + Song.FileName); + Result := False; + Exit; + end; + + //Read Lines while Line starts with # + While (Line[1] = '#') do + begin + //Increase Line Number + Inc (FileLineNo); + Temp := Pos(':', Line); + + //Line has a Seperator-> Headerline + if (Temp <> 0) then + begin + //Read Identifier and Value + Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks + Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp)); + + //Check the Identifier (If Value is given) + if (Length(Value) <> 0) then + begin + + //----------- + //Required Attributes + //----------- + + //Title + if (Identifier = 'TITLE') then + begin + Song.Title := Value; + + //Add Title Flag to Done + Done := Done or 1; + end + + //Artist + else if (Identifier = 'ARTIST') then + begin + Song.Artist := Value; + + //Add Artist Flag to Done + Done := Done or 2; + end + + //MP3 File //Test if Exists + else if (Identifier = 'MP3') AND (FileExists(Song.Path + Value)) then + begin + Song.Mp3 := Value; + + //Add Mp3 Flag to Done + Done := Done or 4; + end + + //Beats per Minute + else if (Identifier = 'BPM') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + SetLength(Song.BPM, 1); + Song.BPM[0].StartBeat := 0; + + Song.BPM[0].BPM := StrtoFloatDef(Value, 0) * Mult * MultBPM; + + if Song.BPM[0].BPM <> 0 then + begin + //Add BPM Flag to Done + Done := Done or 8; + end; + end + + //--------- + //Additional Header Information + //--------- + + //Cover Picture + else if (Identifier = 'COVER') then + begin + Song.Cover := Value; + end + + //Background Picture + else if (Identifier = 'BACKGROUND') then + begin + Song.Background := Value; + end + + // Video File + else if (Identifier = 'VIDEO') then + begin + Song.Video := Value; + end + + // Video Gap + else if (Identifier = 'VIDEOGAP') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + Song.VideoGAP := StrtoFloatDef (Value, 0); + end + + //Genre Sorting + else if (Identifier = 'GENRE') then + begin + Song.Genre := Value; + end + + //Edition Sorting + else if (Identifier = 'EDITION') then + begin + Song.Edition := Value; + end + + //Creator Tag + else if (Identifier = 'CREATOR') then + begin + Song.Creator := Value; + end + + //Language Sorting + else if (Identifier = 'LANGUAGE') then + begin + Song.Language := Value; + end + + // Song Start + else if (Identifier = 'START') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + Song.Start := StrtoFloatDef(Value, 0); + end + + // Song Ending + else if (Identifier = 'END') then + begin + TryStrtoInt(Value, Song.Finish); + end + + // Resolution + else if (Identifier = 'RESOLUTION') then + begin + TryStrtoInt(Value, Song.Resolution); + end + + // Notes Gap + else if (Identifier = 'NOTESGAP') then + begin + TryStrtoInt(Value, Song.NotesGAP); + end + + // Relative Notes + else if (Identifier = 'RELATIVE') AND (uppercase(Value) = 'YES') then + begin + Song.Relative := True; + end; + + end; + end; + + if not EOf(SongFile) then + ReadLn (SongFile, Line) + else + begin + Result := False; + Log.LogError('File Incomplete or not Ultrastar TxT: ' + Song.FileName); + break; + end; + + //End on first empty Line + if (Length(Line) = 0) then + break; + end; + + //Check if all Required Values are given + if (Done <> 15) then + begin + Result := False; + if (Done and 8) = 0 then //No BMP Flag + Log.LogError('BMP Tag Missing: ' + Song.FileName) + else if (Done and 4) = 0 then //No MP3 Flag + Log.LogError('MP3 Tag/File Missing: ' + Song.FileName) + else if (Done and 2) = 0 then //No Artist Flag + Log.LogError('Artist Tag Missing: ' + Song.FileName) + else if (Done and 1) = 0 then //No Title Flag + Log.LogError('Title Tag Missing: ' + Song.FileName) + else //unknown Error + Log.LogError('File Incomplete or not Ultrastar TxT: ' + Song.FileName); + end; + +end; + + //Analyse Song File and Read Header +function AnalyseFile(var Song: TSong): boolean; +begin +Result := False; +{try } + //Reset LineNo + FileLineNo := 0; + + //Open File and set File Pointer to the beginning + AssignFile(SongFile, Song.Path + Song.FileName); + Reset(SongFile); + + //Clear old Song Header + ClearSong(Song); + + //Read Header + Result := ReadTxTHeader(Song); + + //And Close File + CloseFile(SongFile); +{except + CloseFile(SongFile); + + Result := False; + //Error Reporting + Log.LogError('An Error occured reading Line ' + inttostr(FileLineNo) + ' from SongHeader: ' + Song.FileName); +end;} +end; + + + +end. \ No newline at end of file -- cgit v1.2.3 From 95dc3d90b3eb11080fdcd5edae37cbd35c4ffb57 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Fri, 23 Mar 2007 17:40:06 +0000 Subject: Some Changes on Database System and Header Reader Fixed Bug: Scores with 0 are added to DB Made a Class instead of many Functions Fixed a Bug in UFiles, not reading Gap from Header correctly git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@20 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 61fdab03..fed9b7f1 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -171,6 +171,16 @@ begin //Additional Header Information //--------- + // Video Gap + else if (Identifier = 'GAP') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + Song.GAP := StrtoFloatDef (Value, 0); + end + //Cover Picture else if (Identifier = 'COVER') then begin -- cgit v1.2.3 From 4a731514163a14bd3a9222d99707880b56772663 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Wed, 16 May 2007 19:19:35 +0000 Subject: all SongFile Loading and Saving procedures moved to UFiles. Added Some Tolerance in Song File Loading and Song Header Loading. Fix: Programm doesn't Crash anymore when a coruppted Song is loaded for Singing or Editing. Now Jump back to SongScreen and show an Error Message. Also Party Mode is not Interupted, a new Song will be selected automatically. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@197 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 494 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 470 insertions(+), 24 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index fed9b7f1..912a476d 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -4,43 +4,54 @@ interface uses USongs, SysUtils, ULog, UMusic; -//procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs +procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header procedure ClearSong(var Song: TSong); //Clears Song Header values -//procedure CzyscNuty; -//function WczytajCzesci(Name: string): boolean; -//function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; -//function SaveSongDebug(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; +//Methodes Loading and Saving Songfiles +procedure ResetSingTemp; +procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); +procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); +function LoadSong(Name: string): boolean; +function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; + + var - {//Absolute Paths - GamePath: string; - SoundPath: string; - SongPath: string; - LogPath: string; - ThemePath: string; + //Absolute Paths + GamePath: string; + SoundPath: string; + SongPath: string; + LogPath: string; + ThemePath: string; ScreenshotsPath: string; CoversPath: string; - LanguagesPath: string; //} + LanguagesPath: string; + PluginPath: string; + PlayListPath: string; SongFile: TextFile; // all procedures in this unit operates on this file FileLineNo: integer; //Line which is readed at Last, for error reporting - {// variables available for all procedures + // variables available for all procedures Base: array[0..1] of integer; - Rel: array[0..1] of integer;//} + Rel: array[0..1] of integer; Mult: integer = 1; MultBPM: integer = 4; implementation -uses TextGL, UIni, UMain, UPliki; +uses TextGL, UIni, UMain; - //Function sets All Absolute Paths eg. for Songs -{procedure InitializePaths; +//-------------------- +// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist +//-------------------- +procedure InitializePaths; +var + Writeable: Boolean; begin GamePath := ExtractFilePath(ParamStr(0)); + SoundPath := GamePath + 'Sounds\'; SongPath := GamePath + 'Songs\'; LogPath := GamePath; @@ -48,11 +59,43 @@ begin ScreenshotsPath := GamePath + 'Screenshots\'; CoversPath := GamePath + 'Covers\'; LanguagesPath := GamePath + 'Languages\'; + PluginPath := GamePath + 'Plugins\'; + PlaylistPath := GamePath + 'Playlists\'; + + //After Setting Paths, make sure that Paths exist + If not DirectoryExists(SoundPath) then + Writeable := ForceDirectories(SoundPath); + + If Writeable And (not DirectoryExists(SongPath)) then + Writeable := ForceDirectories(SongPath); + + If Writeable And (not DirectoryExists(ThemePath)) then + Writeable := ForceDirectories(ThemePath); + + If Writeable And (not DirectoryExists(ScreenshotsPath)) then + Writeable := ForceDirectories(ScreenshotsPath); + + If Writeable And (not DirectoryExists(CoversPath)) then + Writeable := ForceDirectories(CoversPath); + + If Writeable And (not DirectoryExists(LanguagesPath)) then + Writeable := ForceDirectories(LanguagesPath); + + If Writeable And (not DirectoryExists(PluginPath)) then + Writeable := ForceDirectories(PluginPath); + + If Writeable And (not DirectoryExists(PlaylistPath)) then + Writeable := ForceDirectories(PlaylistPath); + + if not Writeable then + Log.LogError('Error: Dir is Readonly'); DecimalSeparator := ','; -end;} +end; - //Clears Song Header values +//-------------------- +// Clears Song Header values +//-------------------- procedure ClearSong(var Song: TSong); begin //Main Information @@ -80,7 +123,9 @@ begin Song.Creator := ''; end; - //Reads Standard TXT Header +//-------------------- +// Reads Standard TXT Header +//-------------------- function ReadTXTHeader(var Song: TSong): boolean; var Line, Identifier, Value: String; @@ -100,7 +145,7 @@ begin end; //Read Lines while Line starts with # - While (Line[1] = '#') do + While (Length(Line) = 0) OR (Line[1] = '#') do begin //Increase Line Number Inc (FileLineNo); @@ -279,9 +324,9 @@ begin break; end; - //End on first empty Line + {//End on first empty Line if (Length(Line) = 0) then - break; + break;} end; //Check if all Required Values are given @@ -302,7 +347,9 @@ begin end; - //Analyse Song File and Read Header +//-------------------- +// Analyse Song File and Read Header +//-------------------- function AnalyseFile(var Song: TSong): boolean; begin Result := False; @@ -331,6 +378,405 @@ Result := False; end;} end; +//-------------------- +// Resets the temporary Sentence Arrays for each Player and some other Variables +//-------------------- +procedure ResetSingTemp; +var + Pet: integer; +begin + SetLength(Czesci, Length(Player)); + SetLength(AktSong.BPM, 0); + for Pet := 0 to High(Player) do begin + SetLength(Czesci[Pet].Czesc, 1); + SetLength(Czesci[Pet].Czesc[0].Nuta, 0); + Czesci[Pet].Czesc[0].Lyric := ''; + Czesci[Pet].Czesc[0].LyricWidth := 0; + Player[pet].Score := 0; + Player[pet].IlNut := 0; + Player[pet].HighNut := -1; + end; + //Reset Path and Filename Values to Prevent Errors in Editor + AktSong.Path := ''; + AktSong.FileName := ''; +end; + +//-------------------- +// Parses Note Infos and save them to Array +//-------------------- +procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); +var + Space: boolean; +begin + case Ini.Solmization of + 1: // european + begin + case (NoteP mod 12) of + 0..1: LyricS := ' do '; + 2..3: LyricS := ' re '; + 4: LyricS := ' mi '; + 5..6: LyricS := ' fa '; + 7..8: LyricS := ' sol '; + 9..10: LyricS := ' la '; + 11: LyricS := ' si '; + end; + end; + 2: // japanese + begin + case (NoteP mod 12) of + 0..1: LyricS := ' do '; + 2..3: LyricS := ' re '; + 4: LyricS := ' mi '; + 5..6: LyricS := ' fa '; + 7..8: LyricS := ' so '; + 9..10: LyricS := ' la '; + 11: LyricS := ' shi '; + end; + end; + 3: // american + begin + case (NoteP mod 12) of + 0..1: LyricS := ' do '; + 2..3: LyricS := ' re '; + 4: LyricS := ' mi '; + 5..6: LyricS := ' fa '; + 7..8: LyricS := ' sol '; + 9..10: LyricS := ' la '; + 11: LyricS := ' ti '; + end; + end; + end; // case + + with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do begin + SetLength(Nuta, Length(Nuta) + 1); + IlNut := IlNut + 1; + HighNut := HighNut + 1; + Muzyka.IlNut := Muzyka.IlNut + 1; + + Nuta[HighNut].Start := StartP; + if IlNut = 1 then begin + StartNote := Nuta[HighNut].Start; + if Czesci[NrCzesci].Ilosc = 1 then + Start := -100; +// Start := Nuta[HighNut].Start; + end; + + Nuta[HighNut].Dlugosc := DurationP; + Muzyka.DlugoscNut := Muzyka.DlugoscNut + Nuta[HighNut].Dlugosc; + + // back to the normal system with normal, golden and now freestyle notes + case TypeP of + 'F': Nuta[HighNut].Wartosc := 0; + ':': Nuta[HighNut].Wartosc := 1; + '*': Nuta[HighNut].Wartosc := 2; + end; + + Czesci[NrCzesci].Wartosc := Czesci[NrCzesci].Wartosc + Nuta[HighNut].Dlugosc * Nuta[HighNut].Wartosc; + + Nuta[HighNut].Ton := NoteP; + if Nuta[HighNut].Ton < Base[NrCzesci] then Base[NrCzesci] := Nuta[HighNut].Ton; + Nuta[HighNut].TonGamy := Nuta[HighNut].TonGamy mod 12; + + Nuta[HighNut].Tekst := Copy(LyricS, 2, 100); + Lyric := Lyric + Nuta[HighNut].Tekst; + + if TypeP = 'F' then + Nuta[HighNut].FreeStyle := true; + + Koniec := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc; + end; // with +end; + +//-------------------- +// Called when a new Sentence is found in the TXT File +//-------------------- +procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); +var +I: Integer; +begin + + // stara czesc //Alter Satz //Update Old Part + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].BaseNote := Base[NrCzesciP]; + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].LyricWidth := glTextWidth(PChar(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Lyric)); + + //Total Notes Patch + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := 0; + for I := low(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) to high(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) do + begin + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Dlugosc * Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Wartosc; + end; + //Total Notes Patch End + + + // nowa czesc //Neuer Satz //Update New Part + SetLength(Czesci[NrCzesciP].Czesc, Czesci[NrCzesciP].Ilosc + 1); + Czesci[NrCzesciP].High := Czesci[NrCzesciP].High + 1; + Czesci[NrCzesciP].Ilosc := Czesci[NrCzesciP].Ilosc + 1; + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].HighNut := -1; + + if not AktSong.Relative then + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; + + if AktSong.Relative then begin + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; + Rel[NrCzesciP] := Rel[NrCzesciP] + Param2; + end; + + Base[NrCzesciP] := 100; // high number +end; +//-------------------- +// Load a Song +//-------------------- +function LoadSong(Name: string): boolean; +var + TempC: char; + Tekst: string; + CP: integer; // Current Player (0 or 1) + Pet: integer; + Both: boolean; + Param1: integer; + Param2: integer; + Param3: integer; + ParamS: string; + I: Integer; +begin + Result := false; + + if not FileExists(Name) then begin + Log.LogError('File not found: "' + Name + '"', 'WczytajCzesci'); + exit; + end; + + try + MultBPM := 4; // 4 - mnoznik dla czasu nut + Mult := 1; // 4 - dokladnosc pomiaru nut + Base[0] := 100; // high number +// Base[1] := 100; // high number + Czesci[0].Wartosc := 0; +// Czesci[1].Wartosc := 0; // here was the error in 0.3.2 + AktSong.Relative := false; + + Rel[0] := 0; +// Rel[1] := 0; + CP := 0; + Both := false; + if Length(Player) = 2 then Both := true; + + FileMode := fmOpenRead; + AssignFile(SongFile, Name); + Reset(SongFile); + + //Clear old Song Header + ClearSong(AktSong); + + if (AktSong.Path = '') then + AktSong.Path := ExtractFilePath(Name); + + if (AktSong.FileName = '') then + AktSong.Filename := ExtractFileName(Name); + //Read Header + Result := ReadTxTHeader(AktSong); + if not Result then + begin + Log.LogError('Error Loading SongHeader, abort Song Loading'); + Exit; + end; + + Result := False; + + Reset(SongFile); + FileLineNo := 0; + //Search for Note Begining + repeat + ReadLn(SongFile, Tekst); + Inc(FileLineNo); + + if (EoF(SongFile)) then + begin //Song File Corrupted - No Notes + Log.LogError('Could not load txt File, no Notes found: ' + Name); + Result := False; + Exit; + end; + Read(SongFile, TempC); + until ((TempC = ':') or (TempC = 'F') or (TempC = '*')); + + SetLength(Czesci, 2); + for Pet := 0 to High(Czesci) do begin + SetLength(Czesci[Pet].Czesc, 1); + Czesci[Pet].High := 0; + Czesci[Pet].Ilosc := 1; + Czesci[Pet].Akt := 0; + Czesci[Pet].Resolution := AktSong.Resolution; + Czesci[Pet].NotesGAP := AktSong.NotesGAP; + Czesci[Pet].Czesc[0].IlNut := 0; + Czesci[Pet].Czesc[0].HighNut := -1; + end; + +// TempC := ':'; +// TempC := Tekst[1]; // read from backup variable, don't use default ':' value + + while (TempC <> 'E') AND (not EOF(SongFile)) do begin + Inc(FileLineNo); + if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin + // wczytuje nute + Read(SongFile, Param1); + Read(SongFile, Param2); + Read(SongFile, Param3); + Read(SongFile, ParamS); + + // dodaje nute + if not Both then + // P1 + ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS) + else begin + // P1 + P2 + ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS); + ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS); + end; + end; // if + if TempC = '-' then begin + // reads sentence + Read(SongFile, Param1); + if AktSong.Relative then Read(SongFile, Param2); // read one more data for relative system + + // new sentence + if not Both then + // P1 + NewSentence(0, (Param1 + Rel[0]) * Mult, Param2) + else begin + // P1 + P2 + NewSentence(0, (Param1 + Rel[0]) * Mult, Param2); + NewSentence(1, (Param1 + Rel[1]) * Mult, Param2); + end; + + end; // if + + if TempC = 'B' then begin + SetLength(AktSong.BPM, Length(AktSong.BPM) + 1); + Read(SongFile, AktSong.BPM[High(AktSong.BPM)].StartBeat); + AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0]; + + Read(SongFile, Tekst); + AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst); + AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM; + end; + + + if not Both then begin + Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP]; + Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric)); + //Total Notes Patch + Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0; + for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do + begin + Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc; + end; + //Total Notes Patch End + end else begin + for Pet := 0 to High(Czesci) do begin + Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet]; + Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric)); + //Total Notes Patch + Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0; + for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do + begin + Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc; + end; + //Total Notes Patch End + end; + end; + + Read(SongFile, TempC); + end; // while} + + CloseFile(SongFile); + except + Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(FileLineNo)); + exit; + end; + + Result := true; +end; + +//-------------------- +// Saves a Song +//-------------------- +function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; +var + C: integer; + N: integer; + S: string; + B: integer; + RelativeSubTime: integer; + NoteState: String; + +begin +// Relative := true; // override (idea - use shift+S to save with relative) + AssignFile(SongFile, Name); + Rewrite(SongFile); + + WriteLn(SongFile, '#TITLE:' + Song.Title + ''); + WriteLn(SongFile, '#ARTIST:' + Song.Artist); + + if Song.Creator <> '' then WriteLn(SongFile, '#CREATOR:' + Song.Creator); + if Song.Edition <> 'Unknown' then WriteLn(SongFile, '#EDITION:' + Song.Edition); + if Song.Genre <> 'Unknown' then WriteLn(SongFile, '#GENRE:' + Song.Genre); + if Song.Language <> 'Unknown' then WriteLn(SongFile, '#LANGUAGE:' + Song.Language); + if Song.Cover <> '' then WriteLn(SongFile, '#COVER:' + Song.Cover); + + WriteLn(SongFile, '#MP3:' + Song.Mp3); + + if Song.Background <> '' then WriteLn(SongFile, '#BACKGROUND:' + Song.Background); + if Song.Video <> '' then WriteLn(SongFile, '#VIDEO:' + Song.Video); + if Song.VideoGAP <> 0 then WriteLn(SongFile, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP)); + if Song.Resolution <> 4 then WriteLn(SongFile, '#RESOLUTION:' + IntToStr(Song.Resolution)); + if Song.NotesGAP <> 0 then WriteLn(SongFile, '#NOTESGAP:' + IntToStr(Song.NotesGAP)); + if Song.Start <> 0 then WriteLn(SongFile, '#START:' + FloatToStr(Song.Start)); + if Song.Finish <> 0 then WriteLn(SongFile, '#END:' + IntToStr(Song.Finish)); + if Relative then WriteLn(SongFile, '#RELATIVE:yes'); + + WriteLn(SongFile, '#BPM:' + FloatToStr(Song.BPM[0].BPM / 4)); + WriteLn(SongFile, '#GAP:' + FloatToStr(Song.GAP)); + + RelativeSubTime := 0; + for B := 1 to High(AktSong.BPM) do + WriteLn(SongFile, 'B ' + FloatToStr(AktSong.BPM[B].StartBeat) + ' ' + FloatToStr(AktSong.BPM[B].BPM/4)); + + for C := 0 to Czesc.High do begin + for N := 0 to Czesc.Czesc[C].HighNut do begin + with Czesc.Czesc[C].Nuta[N] do begin + + + //Golden + Freestyle Note Patch + case Czesc.Czesc[C].Nuta[N].Wartosc of + 0: NoteState := 'F '; + 1: NoteState := ': '; + 2: NoteState := '* '; + end; // case + S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Dlugosc) + ' ' + IntToStr(Ton) + ' ' + Tekst; + + + WriteLn(SongFile, S); + end; // with + end; // N + + if C < Czesc.High then begin // don't write end of last sentence + if not Relative then + S := '- ' + IntToStr(Czesc.Czesc[C+1].Start) + else begin + S := '- ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime) + + ' ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime); + RelativeSubTime := Czesc.Czesc[C+1].Start; + end; + WriteLn(SongFile, S); + end; + + end; // C + + + WriteLn(SongFile, 'E'); + CloseFile(SongFile); +end; end. \ No newline at end of file -- cgit v1.2.3 From 1858dadeadf071bbc3eb16ae835fc9bd95440eab Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Thu, 17 May 2007 14:23:38 +0000 Subject: Video Tag will now only be read when the VideoFile exists. -> Better usability of VideoIcon git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@214 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 912a476d..aa336233 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -239,7 +239,7 @@ begin end // Video File - else if (Identifier = 'VIDEO') then + else if (Identifier = 'VIDEO') AND (FileExists(Song.Path + Value)) then begin Song.Video := Value; end -- cgit v1.2.3 From 0df43e29d3d12f93fd4ace638cfb60b65dd32262 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Wed, 23 May 2007 17:00:52 +0000 Subject: Fixed a Bug that can cause the application crashes, when Song Data is missing. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@226 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index aa336233..ee1935cd 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -239,9 +239,12 @@ begin end // Video File - else if (Identifier = 'VIDEO') AND (FileExists(Song.Path + Value)) then + else if (Identifier = 'VIDEO') then begin - Song.Video := Value; + if (FileExists(Song.Path + Value)) then + Song.Video := Value + else + Log.LogError('Can''t find Video File in Song: ' + Song.Path + Song.FileName); end // Video Gap @@ -579,6 +582,7 @@ begin Result := ReadTxTHeader(AktSong); if not Result then begin + CloseFile(SongFile); Log.LogError('Error Loading SongHeader, abort Song Loading'); Exit; end; @@ -594,6 +598,7 @@ begin if (EoF(SongFile)) then begin //Song File Corrupted - No Notes + CloseFile(SongFile); Log.LogError('Could not load txt File, no Notes found: ' + Name); Result := False; Exit; @@ -617,7 +622,6 @@ begin // TempC := Tekst[1]; // read from backup variable, don't use default ':' value while (TempC <> 'E') AND (not EOF(SongFile)) do begin - Inc(FileLineNo); if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin // wczytuje nute Read(SongFile, Param1); @@ -688,10 +692,17 @@ begin end; Read(SongFile, TempC); + Inc(FileLineNo); end; // while} CloseFile(SongFile); except + try + CloseFile(SongFile); + except + + end; + Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(FileLineNo)); exit; end; -- cgit v1.2.3 From 3789f80943f7a237ecbcadeee5803a1fa4a982a2 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Mon, 28 May 2007 19:57:46 +0000 Subject: Fixed some Pronounciation in Error Messages git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@235 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index ee1935cd..5214a9b3 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -336,8 +336,8 @@ begin if (Done <> 15) then begin Result := False; - if (Done and 8) = 0 then //No BMP Flag - Log.LogError('BMP Tag Missing: ' + Song.FileName) + if (Done and 8) = 0 then //No BPM Flag + Log.LogError('BPM Tag Missing: ' + Song.FileName) else if (Done and 4) = 0 then //No MP3 Flag Log.LogError('MP3 Tag/File Missing: ' + Song.FileName) else if (Done and 2) = 0 then //No Artist Flag -- cgit v1.2.3 From 139918027ecdd4a1b149722eea7b578579b993f1 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Mon, 25 Jun 2007 16:44:07 +0000 Subject: Fixed a Bug in Editor. When a Song with Cover was edited and after a song without was loaded and saved, the cover from the first song was written to the second song git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@269 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 5214a9b3..e6982a1a 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -116,6 +116,7 @@ begin //Additional Information Song.Background := ''; + Song.Cover := ''; Song.Video := ''; Song.VideoGAP := 0; Song.NotesGAP := 0; @@ -734,10 +735,10 @@ begin if Song.Edition <> 'Unknown' then WriteLn(SongFile, '#EDITION:' + Song.Edition); if Song.Genre <> 'Unknown' then WriteLn(SongFile, '#GENRE:' + Song.Genre); if Song.Language <> 'Unknown' then WriteLn(SongFile, '#LANGUAGE:' + Song.Language); - if Song.Cover <> '' then WriteLn(SongFile, '#COVER:' + Song.Cover); WriteLn(SongFile, '#MP3:' + Song.Mp3); + if Song.Cover <> '' then WriteLn(SongFile, '#COVER:' + Song.Cover); if Song.Background <> '' then WriteLn(SongFile, '#BACKGROUND:' + Song.Background); if Song.Video <> '' then WriteLn(SongFile, '#VIDEO:' + Song.Video); if Song.VideoGAP <> 0 then WriteLn(SongFile, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP)); -- cgit v1.2.3 From 6e7b96ca3a7d47b0441bed904a9b8bb25c3223de Mon Sep 17 00:00:00 2001 From: jaybinks Date: Wed, 12 Sep 2007 12:43:38 +0000 Subject: * added missed dependency PNGImage. * moved FUNCTION InitializePaths(), from uFiles to uMain as this is a more sane location for it. * updated files that used UFiles to point to UMain, and removed uFiles where its not needed. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@385 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 113 +++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 57 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index e6982a1a..008061a4 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -2,9 +2,12 @@ unit UFiles; interface -uses USongs, SysUtils, ULog, UMusic; +uses SysUtils, + ULog, + UMusic, + USongs; -procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs +//procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header procedure ClearSong(var Song: TSong); //Clears Song Header values @@ -13,12 +16,13 @@ procedure ClearSong(var Song: TSong); //Clears Song Header values procedure ResetSingTemp; procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); -function LoadSong(Name: string): boolean; -function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; +function LoadSong(Name: string): boolean; +function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; var +{* //Absolute Paths GamePath: string; SoundPath: string; @@ -30,6 +34,7 @@ var LanguagesPath: string; PluginPath: string; PlayListPath: string; +*} SongFile: TextFile; // all procedures in this unit operates on this file FileLineNo: integer; //Line which is readed at Last, for error reporting @@ -41,57 +46,51 @@ var MultBPM: integer = 4; implementation -uses TextGL, UIni, UMain; +uses TextGL, + UIni, + UMain; +{* //-------------------- // Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist //-------------------- procedure InitializePaths; -var - Writeable: Boolean; -begin - GamePath := ExtractFilePath(ParamStr(0)); - - SoundPath := GamePath + 'Sounds\'; - SongPath := GamePath + 'Songs\'; - LogPath := GamePath; - ThemePath := GamePath + 'Themes\'; - ScreenshotsPath := GamePath + 'Screenshots\'; - CoversPath := GamePath + 'Covers\'; - LanguagesPath := GamePath + 'Languages\'; - PluginPath := GamePath + 'Plugins\'; - PlaylistPath := GamePath + 'Playlists\'; - - //After Setting Paths, make sure that Paths exist - If not DirectoryExists(SoundPath) then - Writeable := ForceDirectories(SoundPath); - - If Writeable And (not DirectoryExists(SongPath)) then - Writeable := ForceDirectories(SongPath); - - If Writeable And (not DirectoryExists(ThemePath)) then - Writeable := ForceDirectories(ThemePath); - If Writeable And (not DirectoryExists(ScreenshotsPath)) then - Writeable := ForceDirectories(ScreenshotsPath); - - If Writeable And (not DirectoryExists(CoversPath)) then - Writeable := ForceDirectories(CoversPath); - - If Writeable And (not DirectoryExists(LanguagesPath)) then - Writeable := ForceDirectories(LanguagesPath); - - If Writeable And (not DirectoryExists(PluginPath)) then - Writeable := ForceDirectories(PluginPath); + // Initialize a Path Variable + // After Setting Paths, make sure that Paths exist + function initialize_path( out aPathVar : String; const aLocation : String ): boolean; + var + lWriteable: Boolean; + begin + aPathVar := aLocation; + + If DirectoryExists(aPathVar) then + lWriteable := ForceDirectories(aPathVar) + else + lWriteable := false; - If Writeable And (not DirectoryExists(PlaylistPath)) then - Writeable := ForceDirectories(PlaylistPath); + if not Writeable then + Log.LogError('Error: Dir ('+ aLocation +') is Readonly'); + + result := lWriteable; + end; - if not Writeable then - Log.LogError('Error: Dir is Readonly'); +begin + GamePath := ExtractFilePath(ParamStr(0)); + + initialize_path( LogPath , GamePath ); + initialize_path( SoundPath , GamePath + 'Sounds\' ); + initialize_path( SongPath , GamePath + 'Songs\' ); + initialize_path( ThemePath , GamePath + 'Themes\' ); + initialize_path( ScreenshotsPath , GamePath + 'Screenshots\'); + initialize_path( CoversPath , GamePath + 'Covers\' ); + initialize_path( LanguagesPath , GamePath + 'Languages\' ); + initialize_path( PluginPath , GamePath + 'Plugins\' ); + initialize_path( PlaylistPath , GamePath + 'Playlists\' ); DecimalSeparator := ','; end; +*} //-------------------- // Clears Song Header values @@ -99,29 +98,29 @@ end; procedure ClearSong(var Song: TSong); begin //Main Information - Song.Title := ''; + Song.Title := ''; Song.Artist := ''; //Sortings: - Song.Genre := 'Unknown'; - Song.Edition := 'Unknown'; + Song.Genre := 'Unknown'; + Song.Edition := 'Unknown'; Song.Language := 'Unknown'; //Language Patch //Required Information - Song.Mp3 := ''; - Song.BPM := 0; - Song.GAP := 0; - Song.Start := 0; + Song.Mp3 := ''; + Song.BPM := 0; + Song.GAP := 0; + Song.Start := 0; Song.Finish := 0; //Additional Information Song.Background := ''; - Song.Cover := ''; - Song.Video := ''; - Song.VideoGAP := 0; - Song.NotesGAP := 0; + Song.Cover := ''; + Song.Video := ''; + Song.VideoGAP := 0; + Song.NotesGAP := 0; Song.Resolution := 4; - Song.Creator := ''; + Song.Creator := ''; end; //-------------------- @@ -791,4 +790,4 @@ begin CloseFile(SongFile); end; -end. \ No newline at end of file +end. -- cgit v1.2.3 From 62c82114318ed04ce42617fa9ce2e179834dbda4 Mon Sep 17 00:00:00 2001 From: jaybinks Date: Wed, 19 Sep 2007 11:44:10 +0000 Subject: added UCommon ( in classes ) for lazarus... common functions needed for lazarus ( and others ) can be put in here. also this now compiles on lazarus.. ( dosnt link yet... but I dont get any critical compiler errors ) tested to compile in my delphi, and basic functionality is fine. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@395 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 008061a4..bbb22136 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -2,6 +2,10 @@ unit UFiles; interface +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + uses SysUtils, ULog, UMusic, @@ -108,7 +112,12 @@ begin //Required Information Song.Mp3 := ''; + {$IFDEF FPC} + Song.BPM := NULL; + {$ELSE} Song.BPM := 0; + {$ENDIF} + Song.GAP := 0; Song.Start := 0; Song.Finish := 0; -- cgit v1.2.3 From 84beb7412eaca48cbf5c9915b83e5f8c79c9a0e7 Mon Sep 17 00:00:00 2001 From: jaybinks Date: Wed, 19 Sep 2007 13:13:37 +0000 Subject: fixes to get working in lazarus.. compiling, linking, starting to run.. just fixing stuff :) git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@397 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index bbb22136..34342e26 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -113,7 +113,7 @@ begin //Required Information Song.Mp3 := ''; {$IFDEF FPC} - Song.BPM := NULL; + setlength( Song.BPM, 0 ); {$ELSE} Song.BPM := 0; {$ENDIF} -- cgit v1.2.3 From 739ad9a6dee57375f05dcd20dc59ba2d619f11fa Mon Sep 17 00:00:00 2001 From: jaybinks Date: Mon, 24 Sep 2007 13:31:43 +0000 Subject: fixed song loading in Lazarus.. cant assume variables are initialized as 0 :) in UFile "Done: byte;" was no initialized on lazarus compiler. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@431 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 34342e26..565c5ee3 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -137,11 +137,12 @@ end; //-------------------- function ReadTXTHeader(var Song: TSong): boolean; var -Line, Identifier, Value: String; -Temp: word; -Done: byte; + Line, Identifier, Value: String; + Temp: word; + Done: byte; begin Result := true; + Done := 0; //Read first Line ReadLn (SongFile, Line); @@ -167,6 +168,8 @@ begin Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp)); + Log.LogError('Identifier: '+Identifier+' - '+ Value ); + //Check the Identifier (If Value is given) if (Length(Value) <> 0) then begin @@ -332,7 +335,7 @@ begin else begin Result := False; - Log.LogError('File Incomplete or not Ultrastar TxT: ' + Song.FileName); + Log.LogError('File Incomplete or not Ultrastar TxT (A): ' + Song.FileName); break; end; @@ -354,7 +357,7 @@ begin else if (Done and 1) = 0 then //No Title Flag Log.LogError('Title Tag Missing: ' + Song.FileName) else //unknown Error - Log.LogError('File Incomplete or not Ultrastar TxT: ' + Song.FileName); + Log.LogError('File Incomplete or not Ultrastar TxT (B - '+ inttostr(Done) +'): ' + Song.FileName); end; end; -- cgit v1.2.3 From fac1634f48835f46249ec25d2758c81addd09d52 Mon Sep 17 00:00:00 2001 From: jaybinks Date: Sun, 30 Sep 2007 05:56:29 +0000 Subject: some minor bug fixes.. added Installer script.. for NSIS install compiler. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@451 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 41 ----------------------------------------- 1 file changed, 41 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 565c5ee3..9cd3bdc1 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -54,47 +54,6 @@ implementation uses TextGL, UIni, UMain; -{* -//-------------------- -// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist -//-------------------- -procedure InitializePaths; - - // Initialize a Path Variable - // After Setting Paths, make sure that Paths exist - function initialize_path( out aPathVar : String; const aLocation : String ): boolean; - var - lWriteable: Boolean; - begin - aPathVar := aLocation; - - If DirectoryExists(aPathVar) then - lWriteable := ForceDirectories(aPathVar) - else - lWriteable := false; - - if not Writeable then - Log.LogError('Error: Dir ('+ aLocation +') is Readonly'); - - result := lWriteable; - end; - -begin - GamePath := ExtractFilePath(ParamStr(0)); - - initialize_path( LogPath , GamePath ); - initialize_path( SoundPath , GamePath + 'Sounds\' ); - initialize_path( SongPath , GamePath + 'Songs\' ); - initialize_path( ThemePath , GamePath + 'Themes\' ); - initialize_path( ScreenshotsPath , GamePath + 'Screenshots\'); - initialize_path( CoversPath , GamePath + 'Covers\' ); - initialize_path( LanguagesPath , GamePath + 'Languages\' ); - initialize_path( PluginPath , GamePath + 'Plugins\' ); - initialize_path( PlaylistPath , GamePath + 'Playlists\' ); - - DecimalSeparator := ','; -end; -*} //-------------------- // Clears Song Header values -- cgit v1.2.3 From 015dfecd8b6e4e1463509822ca4179ee88add976 Mon Sep 17 00:00:00 2001 From: jaybinks Date: Thu, 25 Oct 2007 11:33:44 +0000 Subject: first effort to work towards jira#USDX-60 song directory enumeration is now unicode compliant on linux. still needs doing for windows, with wfindfile ( I think thats the right name ) this still relies on sdl_ttf and lots of other changes, but I had a few min and wanted to play with this :) git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@527 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 1528 +++++++++++++++++++++--------------------- 1 file changed, 764 insertions(+), 764 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 9cd3bdc1..7e23b42f 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -1,764 +1,764 @@ -unit UFiles; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -uses SysUtils, - ULog, - UMusic, - USongs; - -//procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs -function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header -function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header -procedure ClearSong(var Song: TSong); //Clears Song Header values - -//Methodes Loading and Saving Songfiles -procedure ResetSingTemp; -procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); -procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); -function LoadSong(Name: string): boolean; -function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; - - - -var -{* - //Absolute Paths - GamePath: string; - SoundPath: string; - SongPath: string; - LogPath: string; - ThemePath: string; - ScreenshotsPath: string; - CoversPath: string; - LanguagesPath: string; - PluginPath: string; - PlayListPath: string; -*} - - SongFile: TextFile; // all procedures in this unit operates on this file - FileLineNo: integer; //Line which is readed at Last, for error reporting - - // variables available for all procedures - Base: array[0..1] of integer; - Rel: array[0..1] of integer; - Mult: integer = 1; - MultBPM: integer = 4; - -implementation - -uses TextGL, - UIni, - UMain; - -//-------------------- -// Clears Song Header values -//-------------------- -procedure ClearSong(var Song: TSong); -begin - //Main Information - Song.Title := ''; - Song.Artist := ''; - - //Sortings: - Song.Genre := 'Unknown'; - Song.Edition := 'Unknown'; - Song.Language := 'Unknown'; //Language Patch - - //Required Information - Song.Mp3 := ''; - {$IFDEF FPC} - setlength( Song.BPM, 0 ); - {$ELSE} - Song.BPM := 0; - {$ENDIF} - - Song.GAP := 0; - Song.Start := 0; - Song.Finish := 0; - - //Additional Information - Song.Background := ''; - Song.Cover := ''; - Song.Video := ''; - Song.VideoGAP := 0; - Song.NotesGAP := 0; - Song.Resolution := 4; - Song.Creator := ''; -end; - -//-------------------- -// Reads Standard TXT Header -//-------------------- -function ReadTXTHeader(var Song: TSong): boolean; -var - Line, Identifier, Value: String; - Temp: word; - Done: byte; -begin - Result := true; - Done := 0; - - //Read first Line - ReadLn (SongFile, Line); - - if (Length(Line)<=0) then - begin - Log.LogError('File Starts with Empty Line: ' + Song.FileName); - Result := False; - Exit; - end; - - //Read Lines while Line starts with # - While (Length(Line) = 0) OR (Line[1] = '#') do - begin - //Increase Line Number - Inc (FileLineNo); - Temp := Pos(':', Line); - - //Line has a Seperator-> Headerline - if (Temp <> 0) then - begin - //Read Identifier and Value - Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks - Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp)); - - Log.LogError('Identifier: '+Identifier+' - '+ Value ); - - //Check the Identifier (If Value is given) - if (Length(Value) <> 0) then - begin - - //----------- - //Required Attributes - //----------- - - //Title - if (Identifier = 'TITLE') then - begin - Song.Title := Value; - - //Add Title Flag to Done - Done := Done or 1; - end - - //Artist - else if (Identifier = 'ARTIST') then - begin - Song.Artist := Value; - - //Add Artist Flag to Done - Done := Done or 2; - end - - //MP3 File //Test if Exists - else if (Identifier = 'MP3') AND (FileExists(Song.Path + Value)) then - begin - Song.Mp3 := Value; - - //Add Mp3 Flag to Done - Done := Done or 4; - end - - //Beats per Minute - else if (Identifier = 'BPM') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - SetLength(Song.BPM, 1); - Song.BPM[0].StartBeat := 0; - - Song.BPM[0].BPM := StrtoFloatDef(Value, 0) * Mult * MultBPM; - - if Song.BPM[0].BPM <> 0 then - begin - //Add BPM Flag to Done - Done := Done or 8; - end; - end - - //--------- - //Additional Header Information - //--------- - - // Video Gap - else if (Identifier = 'GAP') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - Song.GAP := StrtoFloatDef (Value, 0); - end - - //Cover Picture - else if (Identifier = 'COVER') then - begin - Song.Cover := Value; - end - - //Background Picture - else if (Identifier = 'BACKGROUND') then - begin - Song.Background := Value; - end - - // Video File - else if (Identifier = 'VIDEO') then - begin - if (FileExists(Song.Path + Value)) then - Song.Video := Value - else - Log.LogError('Can''t find Video File in Song: ' + Song.Path + Song.FileName); - end - - // Video Gap - else if (Identifier = 'VIDEOGAP') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - Song.VideoGAP := StrtoFloatDef (Value, 0); - end - - //Genre Sorting - else if (Identifier = 'GENRE') then - begin - Song.Genre := Value; - end - - //Edition Sorting - else if (Identifier = 'EDITION') then - begin - Song.Edition := Value; - end - - //Creator Tag - else if (Identifier = 'CREATOR') then - begin - Song.Creator := Value; - end - - //Language Sorting - else if (Identifier = 'LANGUAGE') then - begin - Song.Language := Value; - end - - // Song Start - else if (Identifier = 'START') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - Song.Start := StrtoFloatDef(Value, 0); - end - - // Song Ending - else if (Identifier = 'END') then - begin - TryStrtoInt(Value, Song.Finish); - end - - // Resolution - else if (Identifier = 'RESOLUTION') then - begin - TryStrtoInt(Value, Song.Resolution); - end - - // Notes Gap - else if (Identifier = 'NOTESGAP') then - begin - TryStrtoInt(Value, Song.NotesGAP); - end - - // Relative Notes - else if (Identifier = 'RELATIVE') AND (uppercase(Value) = 'YES') then - begin - Song.Relative := True; - end; - - end; - end; - - if not EOf(SongFile) then - ReadLn (SongFile, Line) - else - begin - Result := False; - Log.LogError('File Incomplete or not Ultrastar TxT (A): ' + Song.FileName); - break; - end; - - {//End on first empty Line - if (Length(Line) = 0) then - break;} - end; - - //Check if all Required Values are given - if (Done <> 15) then - begin - Result := False; - if (Done and 8) = 0 then //No BPM Flag - Log.LogError('BPM Tag Missing: ' + Song.FileName) - else if (Done and 4) = 0 then //No MP3 Flag - Log.LogError('MP3 Tag/File Missing: ' + Song.FileName) - else if (Done and 2) = 0 then //No Artist Flag - Log.LogError('Artist Tag Missing: ' + Song.FileName) - else if (Done and 1) = 0 then //No Title Flag - Log.LogError('Title Tag Missing: ' + Song.FileName) - else //unknown Error - Log.LogError('File Incomplete or not Ultrastar TxT (B - '+ inttostr(Done) +'): ' + Song.FileName); - end; - -end; - -//-------------------- -// Analyse Song File and Read Header -//-------------------- -function AnalyseFile(var Song: TSong): boolean; -begin -Result := False; -{try } - //Reset LineNo - FileLineNo := 0; - - //Open File and set File Pointer to the beginning - AssignFile(SongFile, Song.Path + Song.FileName); - Reset(SongFile); - - //Clear old Song Header - ClearSong(Song); - - //Read Header - Result := ReadTxTHeader(Song); - - //And Close File - CloseFile(SongFile); -{except - CloseFile(SongFile); - - Result := False; - //Error Reporting - Log.LogError('An Error occured reading Line ' + inttostr(FileLineNo) + ' from SongHeader: ' + Song.FileName); -end;} -end; - -//-------------------- -// Resets the temporary Sentence Arrays for each Player and some other Variables -//-------------------- -procedure ResetSingTemp; -var - Pet: integer; -begin - SetLength(Czesci, Length(Player)); - SetLength(AktSong.BPM, 0); - for Pet := 0 to High(Player) do begin - SetLength(Czesci[Pet].Czesc, 1); - SetLength(Czesci[Pet].Czesc[0].Nuta, 0); - Czesci[Pet].Czesc[0].Lyric := ''; - Czesci[Pet].Czesc[0].LyricWidth := 0; - Player[pet].Score := 0; - Player[pet].IlNut := 0; - Player[pet].HighNut := -1; - end; - //Reset Path and Filename Values to Prevent Errors in Editor - AktSong.Path := ''; - AktSong.FileName := ''; -end; - -//-------------------- -// Parses Note Infos and save them to Array -//-------------------- -procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); -var - Space: boolean; -begin - case Ini.Solmization of - 1: // european - begin - case (NoteP mod 12) of - 0..1: LyricS := ' do '; - 2..3: LyricS := ' re '; - 4: LyricS := ' mi '; - 5..6: LyricS := ' fa '; - 7..8: LyricS := ' sol '; - 9..10: LyricS := ' la '; - 11: LyricS := ' si '; - end; - end; - 2: // japanese - begin - case (NoteP mod 12) of - 0..1: LyricS := ' do '; - 2..3: LyricS := ' re '; - 4: LyricS := ' mi '; - 5..6: LyricS := ' fa '; - 7..8: LyricS := ' so '; - 9..10: LyricS := ' la '; - 11: LyricS := ' shi '; - end; - end; - 3: // american - begin - case (NoteP mod 12) of - 0..1: LyricS := ' do '; - 2..3: LyricS := ' re '; - 4: LyricS := ' mi '; - 5..6: LyricS := ' fa '; - 7..8: LyricS := ' sol '; - 9..10: LyricS := ' la '; - 11: LyricS := ' ti '; - end; - end; - end; // case - - with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do begin - SetLength(Nuta, Length(Nuta) + 1); - IlNut := IlNut + 1; - HighNut := HighNut + 1; - Muzyka.IlNut := Muzyka.IlNut + 1; - - Nuta[HighNut].Start := StartP; - if IlNut = 1 then begin - StartNote := Nuta[HighNut].Start; - if Czesci[NrCzesci].Ilosc = 1 then - Start := -100; -// Start := Nuta[HighNut].Start; - end; - - Nuta[HighNut].Dlugosc := DurationP; - Muzyka.DlugoscNut := Muzyka.DlugoscNut + Nuta[HighNut].Dlugosc; - - // back to the normal system with normal, golden and now freestyle notes - case TypeP of - 'F': Nuta[HighNut].Wartosc := 0; - ':': Nuta[HighNut].Wartosc := 1; - '*': Nuta[HighNut].Wartosc := 2; - end; - - Czesci[NrCzesci].Wartosc := Czesci[NrCzesci].Wartosc + Nuta[HighNut].Dlugosc * Nuta[HighNut].Wartosc; - - Nuta[HighNut].Ton := NoteP; - if Nuta[HighNut].Ton < Base[NrCzesci] then Base[NrCzesci] := Nuta[HighNut].Ton; - Nuta[HighNut].TonGamy := Nuta[HighNut].TonGamy mod 12; - - Nuta[HighNut].Tekst := Copy(LyricS, 2, 100); - Lyric := Lyric + Nuta[HighNut].Tekst; - - if TypeP = 'F' then - Nuta[HighNut].FreeStyle := true; - - Koniec := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc; - end; // with -end; - -//-------------------- -// Called when a new Sentence is found in the TXT File -//-------------------- -procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); -var -I: Integer; -begin - - // stara czesc //Alter Satz //Update Old Part - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].BaseNote := Base[NrCzesciP]; - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].LyricWidth := glTextWidth(PChar(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Lyric)); - - //Total Notes Patch - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := 0; - for I := low(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) to high(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) do - begin - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Dlugosc * Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Wartosc; - end; - //Total Notes Patch End - - - // nowa czesc //Neuer Satz //Update New Part - SetLength(Czesci[NrCzesciP].Czesc, Czesci[NrCzesciP].Ilosc + 1); - Czesci[NrCzesciP].High := Czesci[NrCzesciP].High + 1; - Czesci[NrCzesciP].Ilosc := Czesci[NrCzesciP].Ilosc + 1; - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].HighNut := -1; - - if not AktSong.Relative then - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; - - if AktSong.Relative then begin - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; - Rel[NrCzesciP] := Rel[NrCzesciP] + Param2; - end; - - Base[NrCzesciP] := 100; // high number -end; - -//-------------------- -// Load a Song -//-------------------- -function LoadSong(Name: string): boolean; -var - TempC: char; - Tekst: string; - CP: integer; // Current Player (0 or 1) - Pet: integer; - Both: boolean; - Param1: integer; - Param2: integer; - Param3: integer; - ParamS: string; - I: Integer; -begin - Result := false; - - if not FileExists(Name) then begin - Log.LogError('File not found: "' + Name + '"', 'WczytajCzesci'); - exit; - end; - - try - MultBPM := 4; // 4 - mnoznik dla czasu nut - Mult := 1; // 4 - dokladnosc pomiaru nut - Base[0] := 100; // high number -// Base[1] := 100; // high number - Czesci[0].Wartosc := 0; -// Czesci[1].Wartosc := 0; // here was the error in 0.3.2 - AktSong.Relative := false; - - Rel[0] := 0; -// Rel[1] := 0; - CP := 0; - Both := false; - if Length(Player) = 2 then Both := true; - - FileMode := fmOpenRead; - AssignFile(SongFile, Name); - Reset(SongFile); - - //Clear old Song Header - ClearSong(AktSong); - - if (AktSong.Path = '') then - AktSong.Path := ExtractFilePath(Name); - - if (AktSong.FileName = '') then - AktSong.Filename := ExtractFileName(Name); - //Read Header - Result := ReadTxTHeader(AktSong); - if not Result then - begin - CloseFile(SongFile); - Log.LogError('Error Loading SongHeader, abort Song Loading'); - Exit; - end; - - Result := False; - - Reset(SongFile); - FileLineNo := 0; - //Search for Note Begining - repeat - ReadLn(SongFile, Tekst); - Inc(FileLineNo); - - if (EoF(SongFile)) then - begin //Song File Corrupted - No Notes - CloseFile(SongFile); - Log.LogError('Could not load txt File, no Notes found: ' + Name); - Result := False; - Exit; - end; - Read(SongFile, TempC); - until ((TempC = ':') or (TempC = 'F') or (TempC = '*')); - - SetLength(Czesci, 2); - for Pet := 0 to High(Czesci) do begin - SetLength(Czesci[Pet].Czesc, 1); - Czesci[Pet].High := 0; - Czesci[Pet].Ilosc := 1; - Czesci[Pet].Akt := 0; - Czesci[Pet].Resolution := AktSong.Resolution; - Czesci[Pet].NotesGAP := AktSong.NotesGAP; - Czesci[Pet].Czesc[0].IlNut := 0; - Czesci[Pet].Czesc[0].HighNut := -1; - end; - -// TempC := ':'; -// TempC := Tekst[1]; // read from backup variable, don't use default ':' value - - while (TempC <> 'E') AND (not EOF(SongFile)) do begin - if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin - // wczytuje nute - Read(SongFile, Param1); - Read(SongFile, Param2); - Read(SongFile, Param3); - Read(SongFile, ParamS); - - // dodaje nute - if not Both then - // P1 - ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS) - else begin - // P1 + P2 - ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS); - ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS); - end; - end; // if - if TempC = '-' then begin - // reads sentence - Read(SongFile, Param1); - if AktSong.Relative then Read(SongFile, Param2); // read one more data for relative system - - // new sentence - if not Both then - // P1 - NewSentence(0, (Param1 + Rel[0]) * Mult, Param2) - else begin - // P1 + P2 - NewSentence(0, (Param1 + Rel[0]) * Mult, Param2); - NewSentence(1, (Param1 + Rel[1]) * Mult, Param2); - end; - - end; // if - - if TempC = 'B' then begin - SetLength(AktSong.BPM, Length(AktSong.BPM) + 1); - Read(SongFile, AktSong.BPM[High(AktSong.BPM)].StartBeat); - AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0]; - - Read(SongFile, Tekst); - AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst); - AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM; - end; - - - if not Both then begin - Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP]; - Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric)); - //Total Notes Patch - Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0; - for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do - begin - Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc; - end; - //Total Notes Patch End - end else begin - for Pet := 0 to High(Czesci) do begin - Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet]; - Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric)); - //Total Notes Patch - Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0; - for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do - begin - Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc; - end; - //Total Notes Patch End - end; - end; - - Read(SongFile, TempC); - Inc(FileLineNo); - end; // while} - - CloseFile(SongFile); - except - try - CloseFile(SongFile); - except - - end; - - Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(FileLineNo)); - exit; - end; - - Result := true; -end; - -//-------------------- -// Saves a Song -//-------------------- -function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; -var - C: integer; - N: integer; - S: string; - B: integer; - RelativeSubTime: integer; - NoteState: String; - -begin -// Relative := true; // override (idea - use shift+S to save with relative) - AssignFile(SongFile, Name); - Rewrite(SongFile); - - WriteLn(SongFile, '#TITLE:' + Song.Title + ''); - WriteLn(SongFile, '#ARTIST:' + Song.Artist); - - if Song.Creator <> '' then WriteLn(SongFile, '#CREATOR:' + Song.Creator); - if Song.Edition <> 'Unknown' then WriteLn(SongFile, '#EDITION:' + Song.Edition); - if Song.Genre <> 'Unknown' then WriteLn(SongFile, '#GENRE:' + Song.Genre); - if Song.Language <> 'Unknown' then WriteLn(SongFile, '#LANGUAGE:' + Song.Language); - - WriteLn(SongFile, '#MP3:' + Song.Mp3); - - if Song.Cover <> '' then WriteLn(SongFile, '#COVER:' + Song.Cover); - if Song.Background <> '' then WriteLn(SongFile, '#BACKGROUND:' + Song.Background); - if Song.Video <> '' then WriteLn(SongFile, '#VIDEO:' + Song.Video); - if Song.VideoGAP <> 0 then WriteLn(SongFile, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP)); - if Song.Resolution <> 4 then WriteLn(SongFile, '#RESOLUTION:' + IntToStr(Song.Resolution)); - if Song.NotesGAP <> 0 then WriteLn(SongFile, '#NOTESGAP:' + IntToStr(Song.NotesGAP)); - if Song.Start <> 0 then WriteLn(SongFile, '#START:' + FloatToStr(Song.Start)); - if Song.Finish <> 0 then WriteLn(SongFile, '#END:' + IntToStr(Song.Finish)); - if Relative then WriteLn(SongFile, '#RELATIVE:yes'); - - WriteLn(SongFile, '#BPM:' + FloatToStr(Song.BPM[0].BPM / 4)); - WriteLn(SongFile, '#GAP:' + FloatToStr(Song.GAP)); - - RelativeSubTime := 0; - for B := 1 to High(AktSong.BPM) do - WriteLn(SongFile, 'B ' + FloatToStr(AktSong.BPM[B].StartBeat) + ' ' + FloatToStr(AktSong.BPM[B].BPM/4)); - - for C := 0 to Czesc.High do begin - for N := 0 to Czesc.Czesc[C].HighNut do begin - with Czesc.Czesc[C].Nuta[N] do begin - - - //Golden + Freestyle Note Patch - case Czesc.Czesc[C].Nuta[N].Wartosc of - 0: NoteState := 'F '; - 1: NoteState := ': '; - 2: NoteState := '* '; - end; // case - S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Dlugosc) + ' ' + IntToStr(Ton) + ' ' + Tekst; - - - WriteLn(SongFile, S); - end; // with - end; // N - - if C < Czesc.High then begin // don't write end of last sentence - if not Relative then - S := '- ' + IntToStr(Czesc.Czesc[C+1].Start) - else begin - S := '- ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime) + - ' ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime); - RelativeSubTime := Czesc.Czesc[C+1].Start; - end; - WriteLn(SongFile, S); - end; - - end; // C - - - WriteLn(SongFile, 'E'); - CloseFile(SongFile); -end; - -end. +unit UFiles; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +uses SysUtils, + ULog, + UMusic, + USongs; + +//procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs +function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header +function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header +procedure ClearSong(var Song: TSong); //Clears Song Header values + +//Methodes Loading and Saving Songfiles +procedure ResetSingTemp; +procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); +procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); +function LoadSong(Name: string): boolean; +function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; + + + +var +{* + //Absolute Paths + GamePath: string; + SoundPath: string; + SongPath: string; + LogPath: string; + ThemePath: string; + ScreenshotsPath: string; + CoversPath: string; + LanguagesPath: string; + PluginPath: string; + PlayListPath: string; +*} + + SongFile: TextFile; // all procedures in this unit operates on this file + FileLineNo: integer; //Line which is readed at Last, for error reporting + + // variables available for all procedures + Base: array[0..1] of integer; + Rel: array[0..1] of integer; + Mult: integer = 1; + MultBPM: integer = 4; + +implementation + +uses TextGL, + UIni, + UMain; + +//-------------------- +// Clears Song Header values +//-------------------- +procedure ClearSong(var Song: TSong); +begin + //Main Information + Song.Title := ''; + Song.Artist := ''; + + //Sortings: + Song.Genre := 'Unknown'; + Song.Edition := 'Unknown'; + Song.Language := 'Unknown'; //Language Patch + + //Required Information + Song.Mp3 := ''; + {$IFDEF FPC} + setlength( Song.BPM, 0 ); + {$ELSE} + Song.BPM := 0; + {$ENDIF} + + Song.GAP := 0; + Song.Start := 0; + Song.Finish := 0; + + //Additional Information + Song.Background := ''; + Song.Cover := ''; + Song.Video := ''; + Song.VideoGAP := 0; + Song.NotesGAP := 0; + Song.Resolution := 4; + Song.Creator := ''; +end; + +//-------------------- +// Reads Standard TXT Header +//-------------------- +function ReadTXTHeader(var Song: TSong): boolean; +var + Line, Identifier, Value: String; + Temp: word; + Done: byte; +begin + Result := true; + Done := 0; + + //Read first Line + ReadLn (SongFile, Line); + + if (Length(Line)<=0) then + begin + Log.LogError('File Starts with Empty Line: ' + Song.FileName); + Result := False; + Exit; + end; + + //Read Lines while Line starts with # + While (Length(Line) = 0) OR (Line[1] = '#') do + begin + //Increase Line Number + Inc (FileLineNo); + Temp := Pos(':', Line); + + //Line has a Seperator-> Headerline + if (Temp <> 0) then + begin + //Read Identifier and Value + Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks + Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp)); + + Log.LogError('Identifier: '+Identifier+' - '+ Value ); + + //Check the Identifier (If Value is given) + if (Length(Value) <> 0) then + begin + + //----------- + //Required Attributes + //----------- + + //Title + if (Identifier = 'TITLE') then + begin + Song.Title := Value; + + //Add Title Flag to Done + Done := Done or 1; + end + + //Artist + else if (Identifier = 'ARTIST') then + begin + Song.Artist := Value; + + //Add Artist Flag to Done + Done := Done or 2; + end + + //MP3 File //Test if Exists + else if (Identifier = 'MP3') AND (FileExists(Song.Path + Value)) then + begin + Song.Mp3 := Value; + + //Add Mp3 Flag to Done + Done := Done or 4; + end + + //Beats per Minute + else if (Identifier = 'BPM') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + SetLength(Song.BPM, 1); + Song.BPM[0].StartBeat := 0; + + Song.BPM[0].BPM := StrtoFloatDef(Value, 0) * Mult * MultBPM; + + if Song.BPM[0].BPM <> 0 then + begin + //Add BPM Flag to Done + Done := Done or 8; + end; + end + + //--------- + //Additional Header Information + //--------- + + // Video Gap + else if (Identifier = 'GAP') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + Song.GAP := StrtoFloatDef (Value, 0); + end + + //Cover Picture + else if (Identifier = 'COVER') then + begin + Song.Cover := Value; + end + + //Background Picture + else if (Identifier = 'BACKGROUND') then + begin + Song.Background := Value; + end + + // Video File + else if (Identifier = 'VIDEO') then + begin + if (FileExists(Song.Path + Value)) then + Song.Video := Value + else + Log.LogError('Can''t find Video File in Song: ' + Song.Path + Song.FileName); + end + + // Video Gap + else if (Identifier = 'VIDEOGAP') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + Song.VideoGAP := StrtoFloatDef (Value, 0); + end + + //Genre Sorting + else if (Identifier = 'GENRE') then + begin + Song.Genre := Value; + end + + //Edition Sorting + else if (Identifier = 'EDITION') then + begin + Song.Edition := Value; + end + + //Creator Tag + else if (Identifier = 'CREATOR') then + begin + Song.Creator := Value; + end + + //Language Sorting + else if (Identifier = 'LANGUAGE') then + begin + Song.Language := Value; + end + + // Song Start + else if (Identifier = 'START') then + begin + // Replace . with , + if (Pos('.', Value) <> 0) then + Value[Pos('.', Value)] := ','; + + Song.Start := StrtoFloatDef(Value, 0); + end + + // Song Ending + else if (Identifier = 'END') then + begin + TryStrtoInt(Value, Song.Finish); + end + + // Resolution + else if (Identifier = 'RESOLUTION') then + begin + TryStrtoInt(Value, Song.Resolution); + end + + // Notes Gap + else if (Identifier = 'NOTESGAP') then + begin + TryStrtoInt(Value, Song.NotesGAP); + end + + // Relative Notes + else if (Identifier = 'RELATIVE') AND (uppercase(Value) = 'YES') then + begin + Song.Relative := True; + end; + + end; + end; + + if not EOf(SongFile) then + ReadLn (SongFile, Line) + else + begin + Result := False; + Log.LogError('File Incomplete or not Ultrastar TxT (A): ' + Song.FileName); + break; + end; + + {//End on first empty Line + if (Length(Line) = 0) then + break;} + end; + + //Check if all Required Values are given + if (Done <> 15) then + begin + Result := False; + if (Done and 8) = 0 then //No BPM Flag + Log.LogError('BPM Tag Missing: ' + Song.FileName) + else if (Done and 4) = 0 then //No MP3 Flag + Log.LogError('MP3 Tag/File Missing: ' + Song.FileName) + else if (Done and 2) = 0 then //No Artist Flag + Log.LogError('Artist Tag Missing: ' + Song.FileName) + else if (Done and 1) = 0 then //No Title Flag + Log.LogError('Title Tag Missing: ' + Song.FileName) + else //unknown Error + Log.LogError('File Incomplete or not Ultrastar TxT (B - '+ inttostr(Done) +'): ' + Song.FileName); + end; + +end; + +//-------------------- +// Analyse Song File and Read Header +//-------------------- +function AnalyseFile(var Song: TSong): boolean; +begin +Result := False; +{try } + //Reset LineNo + FileLineNo := 0; + + //Open File and set File Pointer to the beginning + AssignFile(SongFile, Song.Path + Song.FileName); + Reset(SongFile); + + //Clear old Song Header + ClearSong(Song); + + //Read Header + Result := ReadTxTHeader(Song); + + //And Close File + CloseFile(SongFile); +{except + CloseFile(SongFile); + + Result := False; + //Error Reporting + Log.LogError('An Error occured reading Line ' + inttostr(FileLineNo) + ' from SongHeader: ' + Song.FileName); +end;} +end; + +//-------------------- +// Resets the temporary Sentence Arrays for each Player and some other Variables +//-------------------- +procedure ResetSingTemp; +var + Pet: integer; +begin + SetLength(Czesci, Length(Player)); + SetLength(AktSong.BPM, 0); + for Pet := 0 to High(Player) do begin + SetLength(Czesci[Pet].Czesc, 1); + SetLength(Czesci[Pet].Czesc[0].Nuta, 0); + Czesci[Pet].Czesc[0].Lyric := ''; + Czesci[Pet].Czesc[0].LyricWidth := 0; + Player[pet].Score := 0; + Player[pet].IlNut := 0; + Player[pet].HighNut := -1; + end; + //Reset Path and Filename Values to Prevent Errors in Editor + AktSong.Path := ''; + AktSong.FileName := ''; +end; + +//-------------------- +// Parses Note Infos and save them to Array +//-------------------- +procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); +var + Space: boolean; +begin + case Ini.Solmization of + 1: // european + begin + case (NoteP mod 12) of + 0..1: LyricS := ' do '; + 2..3: LyricS := ' re '; + 4: LyricS := ' mi '; + 5..6: LyricS := ' fa '; + 7..8: LyricS := ' sol '; + 9..10: LyricS := ' la '; + 11: LyricS := ' si '; + end; + end; + 2: // japanese + begin + case (NoteP mod 12) of + 0..1: LyricS := ' do '; + 2..3: LyricS := ' re '; + 4: LyricS := ' mi '; + 5..6: LyricS := ' fa '; + 7..8: LyricS := ' so '; + 9..10: LyricS := ' la '; + 11: LyricS := ' shi '; + end; + end; + 3: // american + begin + case (NoteP mod 12) of + 0..1: LyricS := ' do '; + 2..3: LyricS := ' re '; + 4: LyricS := ' mi '; + 5..6: LyricS := ' fa '; + 7..8: LyricS := ' sol '; + 9..10: LyricS := ' la '; + 11: LyricS := ' ti '; + end; + end; + end; // case + + with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do begin + SetLength(Nuta, Length(Nuta) + 1); + IlNut := IlNut + 1; + HighNut := HighNut + 1; + Muzyka.IlNut := Muzyka.IlNut + 1; + + Nuta[HighNut].Start := StartP; + if IlNut = 1 then begin + StartNote := Nuta[HighNut].Start; + if Czesci[NrCzesci].Ilosc = 1 then + Start := -100; +// Start := Nuta[HighNut].Start; + end; + + Nuta[HighNut].Dlugosc := DurationP; + Muzyka.DlugoscNut := Muzyka.DlugoscNut + Nuta[HighNut].Dlugosc; + + // back to the normal system with normal, golden and now freestyle notes + case TypeP of + 'F': Nuta[HighNut].Wartosc := 0; + ':': Nuta[HighNut].Wartosc := 1; + '*': Nuta[HighNut].Wartosc := 2; + end; + + Czesci[NrCzesci].Wartosc := Czesci[NrCzesci].Wartosc + Nuta[HighNut].Dlugosc * Nuta[HighNut].Wartosc; + + Nuta[HighNut].Ton := NoteP; + if Nuta[HighNut].Ton < Base[NrCzesci] then Base[NrCzesci] := Nuta[HighNut].Ton; + Nuta[HighNut].TonGamy := Nuta[HighNut].TonGamy mod 12; + + Nuta[HighNut].Tekst := Copy(LyricS, 2, 100); + Lyric := Lyric + Nuta[HighNut].Tekst; + + if TypeP = 'F' then + Nuta[HighNut].FreeStyle := true; + + Koniec := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc; + end; // with +end; + +//-------------------- +// Called when a new Sentence is found in the TXT File +//-------------------- +procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); +var +I: Integer; +begin + + // stara czesc //Alter Satz //Update Old Part + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].BaseNote := Base[NrCzesciP]; + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].LyricWidth := glTextWidth(PChar(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Lyric)); + + //Total Notes Patch + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := 0; + for I := low(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) to high(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) do + begin + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Dlugosc * Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Wartosc; + end; + //Total Notes Patch End + + + // nowa czesc //Neuer Satz //Update New Part + SetLength(Czesci[NrCzesciP].Czesc, Czesci[NrCzesciP].Ilosc + 1); + Czesci[NrCzesciP].High := Czesci[NrCzesciP].High + 1; + Czesci[NrCzesciP].Ilosc := Czesci[NrCzesciP].Ilosc + 1; + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].HighNut := -1; + + if not AktSong.Relative then + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; + + if AktSong.Relative then begin + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; + Rel[NrCzesciP] := Rel[NrCzesciP] + Param2; + end; + + Base[NrCzesciP] := 100; // high number +end; + +//-------------------- +// Load a Song +//-------------------- +function LoadSong(Name: string): boolean; +var + TempC: char; + Tekst: string; + CP: integer; // Current Player (0 or 1) + Pet: integer; + Both: boolean; + Param1: integer; + Param2: integer; + Param3: integer; + ParamS: string; + I: Integer; +begin + Result := false; + + if not FileExists(Name) then begin + Log.LogError('File not found: "' + Name + '"', 'WczytajCzesci'); + exit; + end; + + try + MultBPM := 4; // 4 - mnoznik dla czasu nut + Mult := 1; // 4 - dokladnosc pomiaru nut + Base[0] := 100; // high number +// Base[1] := 100; // high number + Czesci[0].Wartosc := 0; +// Czesci[1].Wartosc := 0; // here was the error in 0.3.2 + AktSong.Relative := false; + + Rel[0] := 0; +// Rel[1] := 0; + CP := 0; + Both := false; + if Length(Player) = 2 then Both := true; + + FileMode := fmOpenRead; + AssignFile(SongFile, Name); + Reset(SongFile); + + //Clear old Song Header + ClearSong(AktSong); + + if (AktSong.Path = '') then + AktSong.Path := ExtractFilePath(Name); + + if (AktSong.FileName = '') then + AktSong.Filename := ExtractFileName(Name); + //Read Header + Result := ReadTxTHeader(AktSong); + if not Result then + begin + CloseFile(SongFile); + Log.LogError('Error Loading SongHeader, abort Song Loading'); + Exit; + end; + + Result := False; + + Reset(SongFile); + FileLineNo := 0; + //Search for Note Begining + repeat + ReadLn(SongFile, Tekst); + Inc(FileLineNo); + + if (EoF(SongFile)) then + begin //Song File Corrupted - No Notes + CloseFile(SongFile); + Log.LogError('Could not load txt File, no Notes found: ' + Name); + Result := False; + Exit; + end; + Read(SongFile, TempC); + until ((TempC = ':') or (TempC = 'F') or (TempC = '*')); + + SetLength(Czesci, 2); + for Pet := 0 to High(Czesci) do begin + SetLength(Czesci[Pet].Czesc, 1); + Czesci[Pet].High := 0; + Czesci[Pet].Ilosc := 1; + Czesci[Pet].Akt := 0; + Czesci[Pet].Resolution := AktSong.Resolution; + Czesci[Pet].NotesGAP := AktSong.NotesGAP; + Czesci[Pet].Czesc[0].IlNut := 0; + Czesci[Pet].Czesc[0].HighNut := -1; + end; + +// TempC := ':'; +// TempC := Tekst[1]; // read from backup variable, don't use default ':' value + + while (TempC <> 'E') AND (not EOF(SongFile)) do begin + if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin + // wczytuje nute + Read(SongFile, Param1); + Read(SongFile, Param2); + Read(SongFile, Param3); + Read(SongFile, ParamS); + + // dodaje nute + if not Both then + // P1 + ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS) + else begin + // P1 + P2 + ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS); + ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS); + end; + end; // if + if TempC = '-' then begin + // reads sentence + Read(SongFile, Param1); + if AktSong.Relative then Read(SongFile, Param2); // read one more data for relative system + + // new sentence + if not Both then + // P1 + NewSentence(0, (Param1 + Rel[0]) * Mult, Param2) + else begin + // P1 + P2 + NewSentence(0, (Param1 + Rel[0]) * Mult, Param2); + NewSentence(1, (Param1 + Rel[1]) * Mult, Param2); + end; + + end; // if + + if TempC = 'B' then begin + SetLength(AktSong.BPM, Length(AktSong.BPM) + 1); + Read(SongFile, AktSong.BPM[High(AktSong.BPM)].StartBeat); + AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0]; + + Read(SongFile, Tekst); + AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst); + AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM; + end; + + + if not Both then begin + Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP]; + Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric)); + //Total Notes Patch + Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0; + for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do + begin + Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc; + end; + //Total Notes Patch End + end else begin + for Pet := 0 to High(Czesci) do begin + Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet]; + Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric)); + //Total Notes Patch + Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0; + for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do + begin + Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc; + end; + //Total Notes Patch End + end; + end; + + Read(SongFile, TempC); + Inc(FileLineNo); + end; // while} + + CloseFile(SongFile); + except + try + CloseFile(SongFile); + except + + end; + + Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(FileLineNo)); + exit; + end; + + Result := true; +end; + +//-------------------- +// Saves a Song +//-------------------- +function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; +var + C: integer; + N: integer; + S: string; + B: integer; + RelativeSubTime: integer; + NoteState: String; + +begin +// Relative := true; // override (idea - use shift+S to save with relative) + AssignFile(SongFile, Name); + Rewrite(SongFile); + + WriteLn(SongFile, '#TITLE:' + Song.Title + ''); + WriteLn(SongFile, '#ARTIST:' + Song.Artist); + + if Song.Creator <> '' then WriteLn(SongFile, '#CREATOR:' + Song.Creator); + if Song.Edition <> 'Unknown' then WriteLn(SongFile, '#EDITION:' + Song.Edition); + if Song.Genre <> 'Unknown' then WriteLn(SongFile, '#GENRE:' + Song.Genre); + if Song.Language <> 'Unknown' then WriteLn(SongFile, '#LANGUAGE:' + Song.Language); + + WriteLn(SongFile, '#MP3:' + Song.Mp3); + + if Song.Cover <> '' then WriteLn(SongFile, '#COVER:' + Song.Cover); + if Song.Background <> '' then WriteLn(SongFile, '#BACKGROUND:' + Song.Background); + if Song.Video <> '' then WriteLn(SongFile, '#VIDEO:' + Song.Video); + if Song.VideoGAP <> 0 then WriteLn(SongFile, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP)); + if Song.Resolution <> 4 then WriteLn(SongFile, '#RESOLUTION:' + IntToStr(Song.Resolution)); + if Song.NotesGAP <> 0 then WriteLn(SongFile, '#NOTESGAP:' + IntToStr(Song.NotesGAP)); + if Song.Start <> 0 then WriteLn(SongFile, '#START:' + FloatToStr(Song.Start)); + if Song.Finish <> 0 then WriteLn(SongFile, '#END:' + IntToStr(Song.Finish)); + if Relative then WriteLn(SongFile, '#RELATIVE:yes'); + + WriteLn(SongFile, '#BPM:' + FloatToStr(Song.BPM[0].BPM / 4)); + WriteLn(SongFile, '#GAP:' + FloatToStr(Song.GAP)); + + RelativeSubTime := 0; + for B := 1 to High(AktSong.BPM) do + WriteLn(SongFile, 'B ' + FloatToStr(AktSong.BPM[B].StartBeat) + ' ' + FloatToStr(AktSong.BPM[B].BPM/4)); + + for C := 0 to Czesc.High do begin + for N := 0 to Czesc.Czesc[C].HighNut do begin + with Czesc.Czesc[C].Nuta[N] do begin + + + //Golden + Freestyle Note Patch + case Czesc.Czesc[C].Nuta[N].Wartosc of + 0: NoteState := 'F '; + 1: NoteState := ': '; + 2: NoteState := '* '; + end; // case + S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Dlugosc) + ' ' + IntToStr(Ton) + ' ' + Tekst; + + + WriteLn(SongFile, S); + end; // with + end; // N + + if C < Czesc.High then begin // don't write end of last sentence + if not Relative then + S := '- ' + IntToStr(Czesc.Czesc[C+1].Start) + else begin + S := '- ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime) + + ' ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime); + RelativeSubTime := Czesc.Czesc[C+1].Start; + end; + WriteLn(SongFile, S); + end; + + end; // C + + + WriteLn(SongFile, 'E'); + CloseFile(SongFile); +end; + +end. -- cgit v1.2.3 From 8cca9e3e6f591c35d35d132a9d3f93ffc7cdfee8 Mon Sep 17 00:00:00 2001 From: jaybinks Date: Sat, 27 Oct 2007 06:31:04 +0000 Subject: made some major progress with ffmpeg audio playback !!! YAY !!! still a little choppy, so I suspect incorrect buffer sizes or something like that. also made some mods to support Unicode song file iteration on windows, this is no worse than what we had before, but is not complete.. oh this code only supports win 2000 and up .. no Win 98... git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@533 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 7e23b42f..717d20e2 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -333,16 +333,22 @@ Result := False; //Open File and set File Pointer to the beginning AssignFile(SongFile, Song.Path + Song.FileName); - Reset(SongFile); +// if assinged( SongFile ) then + begin + try + Reset(SongFile); - //Clear old Song Header - ClearSong(Song); + //Clear old Song Header + ClearSong(Song); - //Read Header - Result := ReadTxTHeader(Song); + //Read Header + Result := ReadTxTHeader(Song); - //And Close File - CloseFile(SongFile); + //And Close File + finally + CloseFile(SongFile); + end; + end; {except CloseFile(SongFile); -- cgit v1.2.3 From 391d30716d48dc709f6444b19c008e82311623b9 Mon Sep 17 00:00:00 2001 From: eddie-0815 Date: Thu, 1 Nov 2007 19:34:40 +0000 Subject: Mac OS X version compiles and links. I hope I didn't break too many files on windows/linux. Added switches.inc to all files. Changed many IFDEFs. For Windows-only code please use MSWINDOWS instead of WIN32 now. WIN32 is also used by the Mac port. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@546 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 717d20e2..5f168ead 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -2,9 +2,7 @@ unit UFiles; interface -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} +{$I switches.inc} uses SysUtils, ULog, -- cgit v1.2.3 From 99955c78f63d1cb0d8bec666bc33953590a74c8a Mon Sep 17 00:00:00 2001 From: jaybinks Date: Thu, 1 Nov 2007 23:22:01 +0000 Subject: fixed failed builds build:USDX-LAZLIN-75 build:USDX-LAZLIN-76 for some reason we can not use {$MODE Delphi} in an included file. ( Probably because of the way the compier scopes this switch to each pas file ) ive had to revert this part of eddies changes. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@548 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 5f168ead..e4f83b7a 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -2,6 +2,9 @@ unit UFiles; interface +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} {$I switches.inc} uses SysUtils, @@ -329,8 +332,11 @@ Result := False; //Reset LineNo FileLineNo := 0; + writeln( 'Assign File : ' + Song.Path + Song.FileName ); + //Open File and set File Pointer to the beginning AssignFile(SongFile, Song.Path + Song.FileName); + // if assinged( SongFile ) then begin try -- cgit v1.2.3 From a00122fe60de966751b637477ac8e0a4fdcfbf4b Mon Sep 17 00:00:00 2001 From: jaybinks Date: Thu, 20 Dec 2007 23:59:59 +0000 Subject: removed a bunch of debugging from usdx startup. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@738 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 4 ---- 1 file changed, 4 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index e4f83b7a..274bf404 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -128,8 +128,6 @@ begin Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp)); - Log.LogError('Identifier: '+Identifier+' - '+ Value ); - //Check the Identifier (If Value is given) if (Length(Value) <> 0) then begin @@ -332,8 +330,6 @@ Result := False; //Reset LineNo FileLineNo := 0; - writeln( 'Assign File : ' + Song.Path + Song.FileName ); - //Open File and set File Pointer to the beginning AssignFile(SongFile, Song.Path + Song.FileName); -- cgit v1.2.3 From 167a453b22fe86c327b0b3cd1948e1fb919c13bb Mon Sep 17 00:00:00 2001 From: eddie-0815 Date: Wed, 9 Jan 2008 22:26:48 +0000 Subject: Added UTF8-Conversion for values read out of the txt file. This must be done only on OS X. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@768 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 274bf404..69beefe9 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -54,6 +54,7 @@ implementation uses TextGL, UIni, + UPlatform, UMain; //-------------------- @@ -131,6 +132,15 @@ begin //Check the Identifier (If Value is given) if (Length(Value) <> 0) then begin + + {$IFDEF DARWIN} + if ((Identifier = 'MP3') or (Identifier = 'COVER') or (Identifier = 'BACKGROUND') or (Identifier = 'VIDEO')) then + begin + // Filenames on OS X must be UTF8: + Value := Utf8Encode(Value); + end; + {$ENDIF} + //----------- //Required Attributes @@ -332,7 +342,7 @@ Result := False; //Open File and set File Pointer to the beginning AssignFile(SongFile, Song.Path + Song.FileName); - + // if assinged( SongFile ) then begin try -- cgit v1.2.3 From e74bd57c12f470257111c1c0530fb38f0fd34414 Mon Sep 17 00:00:00 2001 From: jaybinks Date: Sat, 12 Jan 2008 12:31:43 +0000 Subject: bunch of smaller changes... some changes to song loading... Record global changed to singleton object started implementing mic volume display in Settings-Record hope this dosnt break anything.. :P git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@789 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 360 ++++--------------------------------------- 1 file changed, 26 insertions(+), 334 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 69beefe9..d3e4729b 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -10,45 +10,33 @@ interface uses SysUtils, ULog, UMusic, - USongs; + USongs, + USong; //procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs -function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header -function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header -procedure ClearSong(var Song: TSong); //Clears Song Header values +//function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header +//function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header +//procedure ClearSong(var Song: TSong); //Clears Song Header values //Methodes Loading and Saving Songfiles procedure ResetSingTemp; -procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); -procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); -function LoadSong(Name: string): boolean; +//procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); +//procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); + +//function LoadSong(Name: string): boolean; function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; var -{* - //Absolute Paths - GamePath: string; - SoundPath: string; - SongPath: string; - LogPath: string; - ThemePath: string; - ScreenshotsPath: string; - CoversPath: string; - LanguagesPath: string; - PluginPath: string; - PlayListPath: string; -*} - SongFile: TextFile; // all procedures in this unit operates on this file FileLineNo: integer; //Line which is readed at Last, for error reporting // variables available for all procedures - Base: array[0..1] of integer; - Rel: array[0..1] of integer; - Mult: integer = 1; - MultBPM: integer = 4; + Base : array[0..1] of integer; + Rel : array[0..1] of integer; + Mult : integer = 1; + MultBPM : integer = 4; implementation @@ -57,7 +45,10 @@ uses TextGL, UPlatform, UMain; +(* //-------------------- +<<<<<<< .mine +======= // Clears Song Header values //-------------------- procedure ClearSong(var Song: TSong); @@ -367,7 +358,7 @@ Result := False; Log.LogError('An Error occured reading Line ' + inttostr(FileLineNo) + ' from SongHeader: ' + Song.FileName); end;} end; - + *) //-------------------- // Resets the temporary Sentence Arrays for each Player and some other Variables //-------------------- @@ -376,7 +367,6 @@ var Pet: integer; begin SetLength(Czesci, Length(Player)); - SetLength(AktSong.BPM, 0); for Pet := 0 to High(Player) do begin SetLength(Czesci[Pet].Czesc, 1); SetLength(Czesci[Pet].Czesc[0].Nuta, 0); @@ -386,316 +376,18 @@ begin Player[pet].IlNut := 0; Player[pet].HighNut := -1; end; - //Reset Path and Filename Values to Prevent Errors in Editor - AktSong.Path := ''; - AktSong.FileName := ''; -end; - -//-------------------- -// Parses Note Infos and save them to Array -//-------------------- -procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); -var - Space: boolean; -begin - case Ini.Solmization of - 1: // european - begin - case (NoteP mod 12) of - 0..1: LyricS := ' do '; - 2..3: LyricS := ' re '; - 4: LyricS := ' mi '; - 5..6: LyricS := ' fa '; - 7..8: LyricS := ' sol '; - 9..10: LyricS := ' la '; - 11: LyricS := ' si '; - end; - end; - 2: // japanese - begin - case (NoteP mod 12) of - 0..1: LyricS := ' do '; - 2..3: LyricS := ' re '; - 4: LyricS := ' mi '; - 5..6: LyricS := ' fa '; - 7..8: LyricS := ' so '; - 9..10: LyricS := ' la '; - 11: LyricS := ' shi '; - end; - end; - 3: // american - begin - case (NoteP mod 12) of - 0..1: LyricS := ' do '; - 2..3: LyricS := ' re '; - 4: LyricS := ' mi '; - 5..6: LyricS := ' fa '; - 7..8: LyricS := ' sol '; - 9..10: LyricS := ' la '; - 11: LyricS := ' ti '; - end; - end; - end; // case - - with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do begin - SetLength(Nuta, Length(Nuta) + 1); - IlNut := IlNut + 1; - HighNut := HighNut + 1; - Muzyka.IlNut := Muzyka.IlNut + 1; - - Nuta[HighNut].Start := StartP; - if IlNut = 1 then begin - StartNote := Nuta[HighNut].Start; - if Czesci[NrCzesci].Ilosc = 1 then - Start := -100; -// Start := Nuta[HighNut].Start; - end; - - Nuta[HighNut].Dlugosc := DurationP; - Muzyka.DlugoscNut := Muzyka.DlugoscNut + Nuta[HighNut].Dlugosc; - - // back to the normal system with normal, golden and now freestyle notes - case TypeP of - 'F': Nuta[HighNut].Wartosc := 0; - ':': Nuta[HighNut].Wartosc := 1; - '*': Nuta[HighNut].Wartosc := 2; - end; - - Czesci[NrCzesci].Wartosc := Czesci[NrCzesci].Wartosc + Nuta[HighNut].Dlugosc * Nuta[HighNut].Wartosc; - Nuta[HighNut].Ton := NoteP; - if Nuta[HighNut].Ton < Base[NrCzesci] then Base[NrCzesci] := Nuta[HighNut].Ton; - Nuta[HighNut].TonGamy := Nuta[HighNut].TonGamy mod 12; - - Nuta[HighNut].Tekst := Copy(LyricS, 2, 100); - Lyric := Lyric + Nuta[HighNut].Tekst; - - if TypeP = 'F' then - Nuta[HighNut].FreeStyle := true; - - Koniec := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc; - end; // with -end; - -//-------------------- -// Called when a new Sentence is found in the TXT File -//-------------------- -procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); -var -I: Integer; -begin - - // stara czesc //Alter Satz //Update Old Part - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].BaseNote := Base[NrCzesciP]; - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].LyricWidth := glTextWidth(PChar(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Lyric)); - - //Total Notes Patch - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := 0; - for I := low(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) to high(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) do + //Reset Path and Filename Values to Prevent Errors in Editor + if assigned( CurrentSong ) then begin - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Dlugosc * Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Wartosc; + SetLength(CurrentSong.BPM, 0); + CurrentSong.Path := ''; + CurrentSong.FileName := ''; end; - //Total Notes Patch End - - - // nowa czesc //Neuer Satz //Update New Part - SetLength(Czesci[NrCzesciP].Czesc, Czesci[NrCzesciP].Ilosc + 1); - Czesci[NrCzesciP].High := Czesci[NrCzesciP].High + 1; - Czesci[NrCzesciP].Ilosc := Czesci[NrCzesciP].Ilosc + 1; - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].HighNut := -1; - - if not AktSong.Relative then - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; - - if AktSong.Relative then begin - Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; - Rel[NrCzesciP] := Rel[NrCzesciP] + Param2; - end; - - Base[NrCzesciP] := 100; // high number + +// CurrentSong := nil; end; -//-------------------- -// Load a Song -//-------------------- -function LoadSong(Name: string): boolean; -var - TempC: char; - Tekst: string; - CP: integer; // Current Player (0 or 1) - Pet: integer; - Both: boolean; - Param1: integer; - Param2: integer; - Param3: integer; - ParamS: string; - I: Integer; -begin - Result := false; - - if not FileExists(Name) then begin - Log.LogError('File not found: "' + Name + '"', 'WczytajCzesci'); - exit; - end; - - try - MultBPM := 4; // 4 - mnoznik dla czasu nut - Mult := 1; // 4 - dokladnosc pomiaru nut - Base[0] := 100; // high number -// Base[1] := 100; // high number - Czesci[0].Wartosc := 0; -// Czesci[1].Wartosc := 0; // here was the error in 0.3.2 - AktSong.Relative := false; - - Rel[0] := 0; -// Rel[1] := 0; - CP := 0; - Both := false; - if Length(Player) = 2 then Both := true; - - FileMode := fmOpenRead; - AssignFile(SongFile, Name); - Reset(SongFile); - - //Clear old Song Header - ClearSong(AktSong); - - if (AktSong.Path = '') then - AktSong.Path := ExtractFilePath(Name); - - if (AktSong.FileName = '') then - AktSong.Filename := ExtractFileName(Name); - //Read Header - Result := ReadTxTHeader(AktSong); - if not Result then - begin - CloseFile(SongFile); - Log.LogError('Error Loading SongHeader, abort Song Loading'); - Exit; - end; - - Result := False; - - Reset(SongFile); - FileLineNo := 0; - //Search for Note Begining - repeat - ReadLn(SongFile, Tekst); - Inc(FileLineNo); - - if (EoF(SongFile)) then - begin //Song File Corrupted - No Notes - CloseFile(SongFile); - Log.LogError('Could not load txt File, no Notes found: ' + Name); - Result := False; - Exit; - end; - Read(SongFile, TempC); - until ((TempC = ':') or (TempC = 'F') or (TempC = '*')); - - SetLength(Czesci, 2); - for Pet := 0 to High(Czesci) do begin - SetLength(Czesci[Pet].Czesc, 1); - Czesci[Pet].High := 0; - Czesci[Pet].Ilosc := 1; - Czesci[Pet].Akt := 0; - Czesci[Pet].Resolution := AktSong.Resolution; - Czesci[Pet].NotesGAP := AktSong.NotesGAP; - Czesci[Pet].Czesc[0].IlNut := 0; - Czesci[Pet].Czesc[0].HighNut := -1; - end; - -// TempC := ':'; -// TempC := Tekst[1]; // read from backup variable, don't use default ':' value - - while (TempC <> 'E') AND (not EOF(SongFile)) do begin - if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin - // wczytuje nute - Read(SongFile, Param1); - Read(SongFile, Param2); - Read(SongFile, Param3); - Read(SongFile, ParamS); - - // dodaje nute - if not Both then - // P1 - ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS) - else begin - // P1 + P2 - ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS); - ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS); - end; - end; // if - if TempC = '-' then begin - // reads sentence - Read(SongFile, Param1); - if AktSong.Relative then Read(SongFile, Param2); // read one more data for relative system - - // new sentence - if not Both then - // P1 - NewSentence(0, (Param1 + Rel[0]) * Mult, Param2) - else begin - // P1 + P2 - NewSentence(0, (Param1 + Rel[0]) * Mult, Param2); - NewSentence(1, (Param1 + Rel[1]) * Mult, Param2); - end; - - end; // if - - if TempC = 'B' then begin - SetLength(AktSong.BPM, Length(AktSong.BPM) + 1); - Read(SongFile, AktSong.BPM[High(AktSong.BPM)].StartBeat); - AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0]; - - Read(SongFile, Tekst); - AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst); - AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM; - end; - - - if not Both then begin - Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP]; - Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric)); - //Total Notes Patch - Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0; - for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do - begin - Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc; - end; - //Total Notes Patch End - end else begin - for Pet := 0 to High(Czesci) do begin - Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet]; - Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric)); - //Total Notes Patch - Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0; - for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do - begin - Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc; - end; - //Total Notes Patch End - end; - end; - - Read(SongFile, TempC); - Inc(FileLineNo); - end; // while} - - CloseFile(SongFile); - except - try - CloseFile(SongFile); - except - - end; - - Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(FileLineNo)); - exit; - end; - - Result := true; -end; //-------------------- // Saves a Song @@ -738,8 +430,8 @@ begin WriteLn(SongFile, '#GAP:' + FloatToStr(Song.GAP)); RelativeSubTime := 0; - for B := 1 to High(AktSong.BPM) do - WriteLn(SongFile, 'B ' + FloatToStr(AktSong.BPM[B].StartBeat) + ' ' + FloatToStr(AktSong.BPM[B].BPM/4)); + for B := 1 to High(CurrentSong.BPM) do + WriteLn(SongFile, 'B ' + FloatToStr(CurrentSong.BPM[B].StartBeat) + ' ' + FloatToStr(CurrentSong.BPM[B].BPM/4)); for C := 0 to Czesc.High do begin for N := 0 to Czesc.Czesc[C].HighNut do begin -- cgit v1.2.3 From 19ab8eded9d18e077906fd716ab25992eba1767d Mon Sep 17 00:00:00 2001 From: jaybinks Date: Sat, 12 Jan 2008 12:44:09 +0000 Subject: removed big ugly commented out code.. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@790 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 328 +------------------------------------------ 1 file changed, 1 insertion(+), 327 deletions(-) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index d3e4729b..b65dcbf2 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -13,21 +13,9 @@ uses SysUtils, USongs, USong; -//procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs -//function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header -//function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header -//procedure ClearSong(var Song: TSong); //Clears Song Header values - -//Methodes Loading and Saving Songfiles procedure ResetSingTemp; -//procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); -//procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer); - -//function LoadSong(Name: string): boolean; function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; - - var SongFile: TextFile; // all procedures in this unit operates on this file FileLineNo: integer; //Line which is readed at Last, for error reporting @@ -44,321 +32,7 @@ uses TextGL, UIni, UPlatform, UMain; - -(* -//-------------------- -<<<<<<< .mine -======= -// Clears Song Header values -//-------------------- -procedure ClearSong(var Song: TSong); -begin - //Main Information - Song.Title := ''; - Song.Artist := ''; - - //Sortings: - Song.Genre := 'Unknown'; - Song.Edition := 'Unknown'; - Song.Language := 'Unknown'; //Language Patch - - //Required Information - Song.Mp3 := ''; - {$IFDEF FPC} - setlength( Song.BPM, 0 ); - {$ELSE} - Song.BPM := 0; - {$ENDIF} - - Song.GAP := 0; - Song.Start := 0; - Song.Finish := 0; - - //Additional Information - Song.Background := ''; - Song.Cover := ''; - Song.Video := ''; - Song.VideoGAP := 0; - Song.NotesGAP := 0; - Song.Resolution := 4; - Song.Creator := ''; -end; - -//-------------------- -// Reads Standard TXT Header -//-------------------- -function ReadTXTHeader(var Song: TSong): boolean; -var - Line, Identifier, Value: String; - Temp: word; - Done: byte; -begin - Result := true; - Done := 0; - - //Read first Line - ReadLn (SongFile, Line); - - if (Length(Line)<=0) then - begin - Log.LogError('File Starts with Empty Line: ' + Song.FileName); - Result := False; - Exit; - end; - - //Read Lines while Line starts with # - While (Length(Line) = 0) OR (Line[1] = '#') do - begin - //Increase Line Number - Inc (FileLineNo); - Temp := Pos(':', Line); - - //Line has a Seperator-> Headerline - if (Temp <> 0) then - begin - //Read Identifier and Value - Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks - Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp)); - - //Check the Identifier (If Value is given) - if (Length(Value) <> 0) then - begin - - {$IFDEF DARWIN} - if ((Identifier = 'MP3') or (Identifier = 'COVER') or (Identifier = 'BACKGROUND') or (Identifier = 'VIDEO')) then - begin - // Filenames on OS X must be UTF8: - Value := Utf8Encode(Value); - end; - {$ENDIF} - - - //----------- - //Required Attributes - //----------- - - //Title - if (Identifier = 'TITLE') then - begin - Song.Title := Value; - - //Add Title Flag to Done - Done := Done or 1; - end - - //Artist - else if (Identifier = 'ARTIST') then - begin - Song.Artist := Value; - - //Add Artist Flag to Done - Done := Done or 2; - end - - //MP3 File //Test if Exists - else if (Identifier = 'MP3') AND (FileExists(Song.Path + Value)) then - begin - Song.Mp3 := Value; - - //Add Mp3 Flag to Done - Done := Done or 4; - end - - //Beats per Minute - else if (Identifier = 'BPM') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - SetLength(Song.BPM, 1); - Song.BPM[0].StartBeat := 0; - - Song.BPM[0].BPM := StrtoFloatDef(Value, 0) * Mult * MultBPM; - - if Song.BPM[0].BPM <> 0 then - begin - //Add BPM Flag to Done - Done := Done or 8; - end; - end - - //--------- - //Additional Header Information - //--------- - - // Video Gap - else if (Identifier = 'GAP') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - Song.GAP := StrtoFloatDef (Value, 0); - end - - //Cover Picture - else if (Identifier = 'COVER') then - begin - Song.Cover := Value; - end - - //Background Picture - else if (Identifier = 'BACKGROUND') then - begin - Song.Background := Value; - end - - // Video File - else if (Identifier = 'VIDEO') then - begin - if (FileExists(Song.Path + Value)) then - Song.Video := Value - else - Log.LogError('Can''t find Video File in Song: ' + Song.Path + Song.FileName); - end - - // Video Gap - else if (Identifier = 'VIDEOGAP') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - Song.VideoGAP := StrtoFloatDef (Value, 0); - end - - //Genre Sorting - else if (Identifier = 'GENRE') then - begin - Song.Genre := Value; - end - - //Edition Sorting - else if (Identifier = 'EDITION') then - begin - Song.Edition := Value; - end - - //Creator Tag - else if (Identifier = 'CREATOR') then - begin - Song.Creator := Value; - end - - //Language Sorting - else if (Identifier = 'LANGUAGE') then - begin - Song.Language := Value; - end - - // Song Start - else if (Identifier = 'START') then - begin - // Replace . with , - if (Pos('.', Value) <> 0) then - Value[Pos('.', Value)] := ','; - - Song.Start := StrtoFloatDef(Value, 0); - end - - // Song Ending - else if (Identifier = 'END') then - begin - TryStrtoInt(Value, Song.Finish); - end - - // Resolution - else if (Identifier = 'RESOLUTION') then - begin - TryStrtoInt(Value, Song.Resolution); - end - - // Notes Gap - else if (Identifier = 'NOTESGAP') then - begin - TryStrtoInt(Value, Song.NotesGAP); - end - - // Relative Notes - else if (Identifier = 'RELATIVE') AND (uppercase(Value) = 'YES') then - begin - Song.Relative := True; - end; - - end; - end; - - if not EOf(SongFile) then - ReadLn (SongFile, Line) - else - begin - Result := False; - Log.LogError('File Incomplete or not Ultrastar TxT (A): ' + Song.FileName); - break; - end; - - {//End on first empty Line - if (Length(Line) = 0) then - break;} - end; - - //Check if all Required Values are given - if (Done <> 15) then - begin - Result := False; - if (Done and 8) = 0 then //No BPM Flag - Log.LogError('BPM Tag Missing: ' + Song.FileName) - else if (Done and 4) = 0 then //No MP3 Flag - Log.LogError('MP3 Tag/File Missing: ' + Song.FileName) - else if (Done and 2) = 0 then //No Artist Flag - Log.LogError('Artist Tag Missing: ' + Song.FileName) - else if (Done and 1) = 0 then //No Title Flag - Log.LogError('Title Tag Missing: ' + Song.FileName) - else //unknown Error - Log.LogError('File Incomplete or not Ultrastar TxT (B - '+ inttostr(Done) +'): ' + Song.FileName); - end; - -end; - -//-------------------- -// Analyse Song File and Read Header -//-------------------- -function AnalyseFile(var Song: TSong): boolean; -begin -Result := False; -{try } - //Reset LineNo - FileLineNo := 0; - - //Open File and set File Pointer to the beginning - AssignFile(SongFile, Song.Path + Song.FileName); - -// if assinged( SongFile ) then - begin - try - Reset(SongFile); - - //Clear old Song Header - ClearSong(Song); - - //Read Header - Result := ReadTxTHeader(Song); - - //And Close File - finally - CloseFile(SongFile); - end; - end; -{except - CloseFile(SongFile); - - Result := False; - //Error Reporting - Log.LogError('An Error occured reading Line ' + inttostr(FileLineNo) + ' from SongHeader: ' + Song.FileName); -end;} -end; - *) + //-------------------- // Resets the temporary Sentence Arrays for each Player and some other Variables //-------------------- -- cgit v1.2.3 From 0cff62ed5ea1e4964817bc6efdff523f7b63342e Mon Sep 17 00:00:00 2001 From: tobigun Date: Tue, 5 Feb 2008 21:53:12 +0000 Subject: bugfix: ResetSingTemp prevented a song from being played twice ("File not found" error). The error is due the change of TSong from a record to a class. This is because CurrentSong = CatSongs.Song[index] won't copy the whole data anymore but just a pointer. So the paths of CatSongs.Song[index] will be set to '' too what is not desired. Jay: Please revise this. If i remember correctly you wanted to set CurrentSong to nil instead of setting the paths to an empty string. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@830 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UFiles.pas | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Game/Code/Classes/UFiles.pas') diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index b65dcbf2..495e8a4a 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -51,6 +51,7 @@ begin Player[pet].HighNut := -1; end; + (* FIXME //Reset Path and Filename Values to Prevent Errors in Editor if assigned( CurrentSong ) then begin @@ -58,6 +59,7 @@ begin CurrentSong.Path := ''; CurrentSong.FileName := ''; end; + *) // CurrentSong := nil; end; -- cgit v1.2.3