aboutsummaryrefslogblamecommitdiffstats
path: root/Game/Code/Classes/UFiles.pas
blob: fed9b7f14bf09fb3f3f6c97417bedb56d7a94b08 (plain) (tree)












































































































































































                                                                                                          









                                                
























































































































































                                                                                                                
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
        //---------

        // 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
          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.