From 4a731514163a14bd3a9222d99707880b56772663 Mon Sep 17 00:00:00 2001
From: whiteshark0 <whiteshark0@b956fd51-792f-4845-bead-9b4dfca2ff2c>
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/UCatCovers.pas             |   2 +-
 Game/Code/Classes/UCovers.pas                |   2 +-
 Game/Code/Classes/UDLLManager.pas            |   2 +-
 Game/Code/Classes/UFiles.pas                 | 494 +++++++++++++++++++++++++--
 Game/Code/Classes/UIni.pas                   |   2 +-
 Game/Code/Classes/ULanguage.pas              |   2 +-
 Game/Code/Classes/ULog.pas                   |   2 +-
 Game/Code/Classes/UMusic.pas                 |   2 +-
 Game/Code/Classes/UPlaylist.pas              |   2 +-
 Game/Code/Classes/USongs.pas                 |   2 +-
 Game/Code/Menu/UDisplay.pas                  |   6 +-
 Game/Code/Screens/UScreenCredits.pas         |   2 +-
 Game/Code/Screens/UScreenEditConvert.pas     |   2 +-
 Game/Code/Screens/UScreenEditHeader.pas      |   2 +-
 Game/Code/Screens/UScreenEditSub.pas         |  79 +++--
 Game/Code/Screens/UScreenLevel.pas           |   2 +-
 Game/Code/Screens/UScreenMain.pas            |   2 +-
 Game/Code/Screens/UScreenName.pas            |   2 +-
 Game/Code/Screens/UScreenOpen.pas            |   2 +-
 Game/Code/Screens/UScreenOptions.pas         |   2 +-
 Game/Code/Screens/UScreenOptionsAdvanced.pas |   2 +-
 Game/Code/Screens/UScreenOptionsGame.pas     |   2 +-
 Game/Code/Screens/UScreenOptionsGraphics.pas |   2 +-
 Game/Code/Screens/UScreenOptionsLyrics.pas   |   2 +-
 Game/Code/Screens/UScreenOptionsRecord.pas   |   2 +-
 Game/Code/Screens/UScreenOptionsSound.pas    |   2 +-
 Game/Code/Screens/UScreenOptionsThemes.pas   |   2 +-
 Game/Code/Screens/UScreenPartyNewRound.pas   |   2 +-
 Game/Code/Screens/UScreenPartyOptions.pas    |   2 +-
 Game/Code/Screens/UScreenPartyPlayer.pas     |   2 +-
 Game/Code/Screens/UScreenPopup.pas           |   2 +-
 Game/Code/Screens/UScreenSing.pas            |  26 +-
 Game/Code/Screens/UScreenSingModi.pas        |   2 +-
 Game/Code/Screens/UScreenSong.pas            |   4 +-
 Game/Code/Screens/UScreenSongJumpto.pas      |   2 +-
 Game/Code/Screens/UScreenSongMenu.pas        |   2 +-
 Game/Code/UltraStar.dpr                      |   4 +-
 37 files changed, 577 insertions(+), 98 deletions(-)

(limited to 'Game/Code')

diff --git a/Game/Code/Classes/UCatCovers.pas b/Game/Code/Classes/UCatCovers.pas
index 00a758c8..34742902 100644
--- a/Game/Code/Classes/UCatCovers.pas
+++ b/Game/Code/Classes/UCatCovers.pas
@@ -24,7 +24,7 @@ var
 CatCovers: TCatCovers;
 
 implementation
-uses IniFiles, SysUtils, Classes, UPliki, ULog;
+uses IniFiles, SysUtils, Classes, UFiles, ULog;
 
 constructor TCatCovers.Create;
 begin
diff --git a/Game/Code/Classes/UCovers.pas b/Game/Code/Classes/UCovers.pas
index 55329fd2..5b0a06d4 100644
--- a/Game/Code/Classes/UCovers.pas
+++ b/Game/Code/Classes/UCovers.pas
@@ -34,7 +34,7 @@ var
   Covers:     TCovers;
 
 implementation
-uses UPliki, ULog, DateUtils;
+uses UFiles, ULog, DateUtils;
 
 constructor TCovers.Create;
 begin
diff --git a/Game/Code/Classes/UDLLManager.pas b/Game/Code/Classes/UDLLManager.pas
index 151f0617..59c75d5b 100644
--- a/Game/Code/Classes/UDLLManager.pas
+++ b/Game/Code/Classes/UDLLManager.pas
@@ -1,7 +1,7 @@
 unit UDLLManager;
 
 interface
-uses ModiSDK, UPliki;
+uses ModiSDK, UFiles;
 
 type
   TDLLMan = class
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
diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas
index cafbc912..f12e3832 100644
--- a/Game/Code/Classes/UIni.pas
+++ b/Game/Code/Classes/UIni.pas
@@ -147,7 +147,7 @@ const
   IChannel:       array[0..6] of string = ('0', '1', '2', '3', '4', '5', '6');
 
 implementation
-uses UPliki, SDL, ULanguage, USkins, URecord;
+uses UFiles, SDL, ULanguage, USkins, URecord;
 
 procedure TIni.Load;
 var
diff --git a/Game/Code/Classes/ULanguage.pas b/Game/Code/Classes/ULanguage.pas
index b911b90a..4649c089 100644
--- a/Game/Code/Classes/ULanguage.pas
+++ b/Game/Code/Classes/ULanguage.pas
@@ -36,7 +36,7 @@ var
 
 implementation
 
-uses UPliki, UIni, IniFiles, Classes, SysUtils, Windows, ULog;
+uses UFiles, UIni, IniFiles, Classes, SysUtils, Windows, ULog;
 
 //----------
 //Create - Construct Class then LoadList + Standard Language + Set Standard Implode Glues
diff --git a/Game/Code/Classes/ULog.pas b/Game/Code/Classes/ULog.pas
index 0b492cb3..59e25954 100644
--- a/Game/Code/Classes/ULog.pas
+++ b/Game/Code/Classes/ULog.pas
@@ -47,7 +47,7 @@ var
   Log:    TLog;
 
 implementation
-uses UPliki, SysUtils, DateUtils, URecord, UTime, UIni, Windows;
+uses UFiles, SysUtils, DateUtils, URecord, UTime, UIni, Windows;
 
 destructor TLog.Free;
 begin
diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas
index 0e4e4ddd..6e997c11 100644
--- a/Game/Code/Classes/UMusic.pas
+++ b/Game/Code/Classes/UMusic.pas
@@ -199,7 +199,7 @@ const
   ModeStr:  array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open');
 
 implementation
-uses UGraphic, URecord, UPliki, UIni, UMain, UThemes;
+uses UGraphic, URecord, UFiles, UIni, UMain, UThemes;
 
 procedure InitializeSound;
 begin
diff --git a/Game/Code/Classes/UPlaylist.pas b/Game/Code/Classes/UPlaylist.pas
index 15e17047..67460ed7 100644
--- a/Game/Code/Classes/UPlaylist.pas
+++ b/Game/Code/Classes/UPlaylist.pas
@@ -58,7 +58,7 @@ type
 
 
 implementation
-uses USongs, ULog, UPliki, UGraphic, UThemes, SysUtils;
+uses USongs, ULog, UFiles, UGraphic, UThemes, SysUtils;
 
 //----------
 //Create - Construct Class - Dummy for now
diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas
index 4b49127c..edf5b6df 100644
--- a/Game/Code/Classes/USongs.pas
+++ b/Game/Code/Classes/USongs.pas
@@ -96,7 +96,7 @@ var
 
 implementation
 
-uses UPliki, UIni, UFiles, StrUtils;
+uses UFiles, UIni, StrUtils;
 
 procedure TSongs.LoadSongList;
 begin
diff --git a/Game/Code/Menu/UDisplay.pas b/Game/Code/Menu/UDisplay.pas
index d1d3038d..abaedfa8 100644
--- a/Game/Code/Menu/UDisplay.pas
+++ b/Game/Code/Menu/UDisplay.pas
@@ -42,7 +42,7 @@ var
 
 implementation
 
-uses UGraphic, UTime, Graphics, Jpeg, UPliki, UTexture, UIni;
+uses UGraphic, UTime, Graphics, Jpeg, UFiles, UTexture, UIni;
 
 constructor TDisplay.Create;
 var i: integer;
@@ -137,8 +137,8 @@ begin
         NextScreenWithCheck := NIL;
         CheckOk:=False;
       end
-    else
-      BlackScreen:=True; // end of game - fade to black before exit
+      else
+        BlackScreen:=True; // end of game - fade to black before exit
     //end popup hack
 
 //    ActualScreen.SetAnimationProgress(1);
diff --git a/Game/Code/Screens/UScreenCredits.pas b/Game/Code/Screens/UScreenCredits.pas
index 0411c7b6..98cdc417 100644
--- a/Game/Code/Screens/UScreenCredits.pas
+++ b/Game/Code/Screens/UScreenCredits.pas
@@ -3,7 +3,7 @@ unit UScreenCredits;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes, ULCD, ULight;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes, ULCD, ULight;
 
 type
   TScreenCredits = class(TMenu)
diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas
index 62a50b3e..92e8544c 100644
--- a/Game/Code/Screens/UScreenEditConvert.pas
+++ b/Game/Code/Screens/UScreenEditConvert.pas
@@ -66,7 +66,7 @@ type
   end;
 
 implementation
-uses UGraphic, SysUtils, UDrawTexture, TextGL, UPliki, UMain, UIni, OpenGL, USkins;
+uses UGraphic, SysUtils, UDrawTexture, TextGL, UFiles, UMain, UIni, OpenGL, USkins;
 
 function TScreenEditConvert.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
 var
diff --git a/Game/Code/Screens/UScreenEditHeader.pas b/Game/Code/Screens/UScreenEditHeader.pas
index f3e21fd0..35d7840f 100644
--- a/Game/Code/Screens/UScreenEditHeader.pas
+++ b/Game/Code/Screens/UScreenEditHeader.pas
@@ -44,7 +44,7 @@ type
 
 implementation
 
-uses UGraphic, UMusic, SysUtils, UPliki, USkins;
+uses UGraphic, UMusic, SysUtils, UFiles, USkins;
 
 function TScreenEditHeader.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
 var
diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas
index a665ba1c..a0adef2c 100644
--- a/Game/Code/Screens/UScreenEditSub.pas
+++ b/Game/Code/Screens/UScreenEditSub.pas
@@ -2,12 +2,15 @@ unit UScreenEditSub;
 
 interface
 
-uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
+uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
   ULyrics, Math, OpenGL12, UThemes, MidiOut;
 
 type
   TScreenEditSub = class(TMenu)
     private
+      //Variable is True if no SOng is loaded 
+      Error:        Boolean;
+      
       TextNote:     integer;
       TextSentence: integer;
       TextTitle:    integer;
@@ -71,7 +74,7 @@ type
   end;
 
 implementation
-uses UGraphic, UDraw, UMain, USkins;
+uses UGraphic, UDraw, UMain, USkins, ULanguage;
 
 // Method for input parsing. If False is returned, GetNextWindow
 // should be checked to know the next window to load;
@@ -190,17 +193,15 @@ begin
 
       SDLK_S:
         begin
-          if SDL_ModState = 0 then
-            // Save Song
-            SaveSong(AktSong, Czesci[0], Path + FileName, false);
-
+          // Save Song
           if SDL_ModState = KMOD_LSHIFT then
-            // Save Song
-            SaveSong(AktSong, Czesci[0], Path + FileName, true);
+            SaveSong(AktSong, Czesci[0], Path + FileName, true)
+          else
+            SaveSong(AktSong, Czesci[0], Path + FileName, false);
 
-          if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then
+          {if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then
             // Save Song
-            SaveSongDebug(AktSong, Czesci[0], 'C:\song.asm', false);
+            SaveSongDebug(AktSong, Czesci[0], 'C:\song.asm', false);}
 
         end;
 
@@ -1091,20 +1092,26 @@ procedure TScreenEditSub.onShow;
 begin
   Log.LogStatus('Initializing', 'TEditScreen.onShow');
 
-  MidiOut := TMidiOutput.Create(nil);
-  if Ini.Debug = 1 then
-    MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
-  MidiOut.Open;
-
-  //MidiOut.SetVolume(65535, 65535);
-
-
+  try
+    ResetSingTemp;
+    Error := not LoadSong(Path + FileName);
+  except
+    Error := True;
+  end;
 
-  CzyscNuty;
-  if WczytajCzesci(Path + FileName) = false then
-//  if WczytajCzesci(SongPath + 'Zapis.txt') = false then
-    Text[TextTitle].Text := 'Error loading file'
+  if Error then
+  begin
+    //Error Loading Song -> Go back to Song Screen and Show some Error Message
+    FadeTo(@ScreenSong);
+    ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
+    Exit;
+  end
   else begin
+    MidiOut := TMidiOutput.Create(nil);
+    if Ini.Debug = 1 then
+      MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
+    MidiOut.Open;
+
     Text[TextTitle].Text :=   AktSong.Title;
     Text[TextArtist].Text :=  AktSong.Artist;
     Text[TextMp3].Text :=     AktSong.Mp3;
@@ -1201,7 +1208,7 @@ begin
       end;
     end; // click
   end; // if PlaySentence
-
+  
 
   Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
   Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut);
@@ -1210,23 +1217,31 @@ begin
   Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);
   Text[TextGAP].Text := FloatToStr(AktSong.GAP);
 
-  // Note info
-  Text[TextNStart].Text :=    IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
-  Text[TextNDlugosc].Text :=  IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
-  Text[TextNTon].Text :=      IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' ( ' + GetNoteName(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' )';
-  Text[TextNText].Text :=              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+  //Error reading Variables when no Song is loaded
+  if not Error then
+  begin
+    // Note info
+    Text[TextNStart].Text :=    IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+    Text[TextNDlugosc].Text :=  IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+    Text[TextNTon].Text :=      IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' ( ' + GetNoteName(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' )';
+    Text[TextNText].Text :=              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+  end;
 
   // Text Edit Mode
   if TextEditMode then
-    Text[TextNText].Text := Text[TextNText].Text + '|';
+    Text[TextNText].Text := Text[TextNText].Text + '|'; 
 
   // draw static menu
   inherited Draw;
 
   // draw notes
   SingDrawNoteLines(20, 300, 780, 15);
-  SingDrawBeatDelimeters(40, 300, 760, 0);
-  EditDrawCzesc(40, 405, 760, 0, 15);
+  //Error Drawing when no Song is loaded
+  if not Error then
+  begin
+    SingDrawBeatDelimeters(40, 300, 760, 0);
+    EditDrawCzesc(40, 405, 760, 0, 15);
+  end;
 
   // draw text
   Lyric.Draw;
@@ -1237,7 +1252,7 @@ procedure TScreenEditSub.onHide;
 begin
   MidiOut.Close;
   MidiOut.Free;
-  Music.SetVolume(100);
+  //Music.SetVolume(100);
 end;
 
 function TScreenEditSub.GetNoteName(Note: Integer): String;
diff --git a/Game/Code/Screens/UScreenLevel.pas b/Game/Code/Screens/UScreenLevel.pas
index a1d8fa33..fc343042 100644
--- a/Game/Code/Screens/UScreenLevel.pas
+++ b/Game/Code/Screens/UScreenLevel.pas
@@ -3,7 +3,7 @@ unit UScreenLevel;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenLevel = class(TMenu)
diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas
index 47a79496..085f253d 100644
--- a/Game/Code/Screens/UScreenMain.pas
+++ b/Game/Code/Screens/UScreenMain.pas
@@ -3,7 +3,7 @@ unit UScreenMain;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes, ULCD, ULight;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes, ULCD, ULight;
 
 type
   TScreenMain = class(TMenu)
diff --git a/Game/Code/Screens/UScreenName.pas b/Game/Code/Screens/UScreenName.pas
index 9db7947c..e2a80687 100644
--- a/Game/Code/Screens/UScreenName.pas
+++ b/Game/Code/Screens/UScreenName.pas
@@ -3,7 +3,7 @@ unit UScreenName;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenName = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOpen.pas b/Game/Code/Screens/UScreenOpen.pas
index 3a78b3e2..f5e121f9 100644
--- a/Game/Code/Screens/UScreenOpen.pas
+++ b/Game/Code/Screens/UScreenOpen.pas
@@ -2,7 +2,7 @@ unit UScreenOpen;
 
 interface
 
-uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
+uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
   ULyrics, Math, OpenGL12, UThemes;
 
 type
diff --git a/Game/Code/Screens/UScreenOptions.pas b/Game/Code/Screens/UScreenOptions.pas
index f0229d8c..02d42568 100644
--- a/Game/Code/Screens/UScreenOptions.pas
+++ b/Game/Code/Screens/UScreenOptions.pas
@@ -3,7 +3,7 @@ unit UScreenOptions;
 interface
 
 uses
-  UMenu, SDL, SysUtils, UDisplay, UMusic, UPliki, UIni, UThemes;
+  UMenu, SDL, SysUtils, UDisplay, UMusic, UFiles, UIni, UThemes;
 
 type
   TScreenOptions = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOptionsAdvanced.pas b/Game/Code/Screens/UScreenOptionsAdvanced.pas
index 3e3f2da7..a28945c1 100644
--- a/Game/Code/Screens/UScreenOptionsAdvanced.pas
+++ b/Game/Code/Screens/UScreenOptionsAdvanced.pas
@@ -3,7 +3,7 @@ unit UScreenOptionsAdvanced;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
 
 type
   TScreenOptionsAdvanced = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOptionsGame.pas b/Game/Code/Screens/UScreenOptionsGame.pas
index 540931af..8712decc 100644
--- a/Game/Code/Screens/UScreenOptionsGame.pas
+++ b/Game/Code/Screens/UScreenOptionsGame.pas
@@ -3,7 +3,7 @@ unit UScreenOptionsGame;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes, USongs;
+  UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes, USongs;
 
 type
   TScreenOptionsGame = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOptionsGraphics.pas b/Game/Code/Screens/UScreenOptionsGraphics.pas
index b36bb7d3..c0641fc2 100644
--- a/Game/Code/Screens/UScreenOptionsGraphics.pas
+++ b/Game/Code/Screens/UScreenOptionsGraphics.pas
@@ -3,7 +3,7 @@ unit UScreenOptionsGraphics;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
 
 type
   TScreenOptionsGraphics = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOptionsLyrics.pas b/Game/Code/Screens/UScreenOptionsLyrics.pas
index f60c9765..f4044933 100644
--- a/Game/Code/Screens/UScreenOptionsLyrics.pas
+++ b/Game/Code/Screens/UScreenOptionsLyrics.pas
@@ -3,7 +3,7 @@ unit UScreenOptionsLyrics;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
 
 type
   TScreenOptionsLyrics = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas
index c474bd7f..b005492a 100644
--- a/Game/Code/Screens/UScreenOptionsRecord.pas
+++ b/Game/Code/Screens/UScreenOptionsRecord.pas
@@ -3,7 +3,7 @@ unit UScreenOptionsRecord;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
 
 type
   TScreenOptionsRecord = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOptionsSound.pas b/Game/Code/Screens/UScreenOptionsSound.pas
index d4ab27d2..c99f1ef6 100644
--- a/Game/Code/Screens/UScreenOptionsSound.pas
+++ b/Game/Code/Screens/UScreenOptionsSound.pas
@@ -3,7 +3,7 @@ unit UScreenOptionsSound;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
 
 type
   TScreenOptionsSound = class(TMenu)
diff --git a/Game/Code/Screens/UScreenOptionsThemes.pas b/Game/Code/Screens/UScreenOptionsThemes.pas
index 580f9c4d..b73693c1 100644
--- a/Game/Code/Screens/UScreenOptionsThemes.pas
+++ b/Game/Code/Screens/UScreenOptionsThemes.pas
@@ -3,7 +3,7 @@ unit UScreenOptionsThemes;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
 
 type
   TScreenOptionsThemes = class(TMenu)
diff --git a/Game/Code/Screens/UScreenPartyNewRound.pas b/Game/Code/Screens/UScreenPartyNewRound.pas
index c914ee4b..f084ee10 100644
--- a/Game/Code/Screens/UScreenPartyNewRound.pas
+++ b/Game/Code/Screens/UScreenPartyNewRound.pas
@@ -3,7 +3,7 @@ unit UScreenPartyNewRound;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenPartyNewRound = class(TMenu)
diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas
index 7f3b1209..aa8681d0 100644
--- a/Game/Code/Screens/UScreenPartyOptions.pas
+++ b/Game/Code/Screens/UScreenPartyOptions.pas
@@ -3,7 +3,7 @@ unit UScreenPartyOptions;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenPartyOptions = class(TMenu)
diff --git a/Game/Code/Screens/UScreenPartyPlayer.pas b/Game/Code/Screens/UScreenPartyPlayer.pas
index d6e13d65..f6bcb0b7 100644
--- a/Game/Code/Screens/UScreenPartyPlayer.pas
+++ b/Game/Code/Screens/UScreenPartyPlayer.pas
@@ -3,7 +3,7 @@ unit UScreenPartyPlayer;
 Interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenPartyPlayer = class(TMenu)
diff --git a/Game/Code/Screens/UScreenPopup.pas b/Game/Code/Screens/UScreenPopup.pas
index 9b71eb9a..2a789e42 100644
--- a/Game/Code/Screens/UScreenPopup.pas
+++ b/Game/Code/Screens/UScreenPopup.pas
@@ -3,7 +3,7 @@ unit UScreenPopup;
 interface
 
 uses
-  UMenu, SDL, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenPopupCheck = class(TMenu)
diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas
index b49e0add..cdce5984 100644
--- a/Game/Code/Screens/UScreenSing.pas
+++ b/Game/Code/Screens/UScreenSing.pas
@@ -2,7 +2,7 @@ unit UScreenSing;
 
 interface
 
-uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, ULyrics,
+uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, ULyrics,
   TextGL, OpenGL12, BASS, UThemes, ULCD, UGraphicClasses;
 
 type
@@ -321,11 +321,29 @@ begin
   Text[TextP3RScore].Visible := V3R;
 
   // load notes
-  CzyscNuty;
+  ResetSingTemp;
 //  Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!');
   AktSong := CatSongs.Song[CatSongs.Selected];
-
-  WczytajCzesci(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName);
+  try
+    if not LoadSong(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName) then
+    begin
+      //Error Loading Song -> Go back to Song Screen and Show some Error Message
+      FadeTo(@ScreenSong);
+      //Select New Song in Party Mode
+      if ScreenSong.Mode = 1 then
+        ScreenSong.SelectRandomSong;
+      ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
+      Exit;
+    end;
+  except
+    //Error Loading Song -> Go back to Song Screen and Show some Error Message
+    FadeTo(@ScreenSong);
+    //Select New Song in Party Mode
+      if ScreenSong.Mode = 1 then
+        ScreenSong.SelectRandomSong;
+    ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
+    Exit;
+  end;
   AktSong.Path := CatSongs.Song[CatSongs.Selected].Path;
 //  AktSong.GAP := AktSong.GAP + 40 {4096 = 100ms for buffer} + 20 {microphone} + 60000 / AktSong.BPM[0].BPM / 2; // temporary until UMain will be fixed
 
diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas
index 484d7d56..93ede980 100644
--- a/Game/Code/Screens/UScreenSingModi.pas
+++ b/Game/Code/Screens/UScreenSingModi.pas
@@ -2,7 +2,7 @@ unit UScreenSingModi;
 
 interface
 
-uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, ULyrics,
+uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, ULyrics,
   TextGL, OpenGL12, BASS, UThemes, ULCD, UScreenSing, ModiSDK;
 
 type
diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas
index 2ce6b6df..33a6752d 100644
--- a/Game/Code/Screens/UScreenSong.pas
+++ b/Game/Code/Screens/UScreenSong.pas
@@ -3,7 +3,7 @@ unit UScreenSong;
 interface
 
 uses
-  UMenu, SDL, UMusic, UPliki, UTime, UDisplay, USongs, SysUtils, ULog, UThemes, UTexture, ULanguage,
+  UMenu, SDL, UMusic, UFiles, UTime, UDisplay, USongs, SysUtils, ULog, UThemes, UTexture, ULanguage,
   ULCD, ULight, UIni;
 
 type
@@ -1227,7 +1227,7 @@ end;
 procedure TScreenSong.onHide;
 begin
   //When hide then Stop Music (For Party Mode Popup on Exit)
-  if (Display.NextScreen <> @ScreenSing) and (Display.NextScreen <> @ScreenSingModi) then
+  if (Display.NextScreen <> @ScreenSing) and (Display.NextScreen <> @ScreenSingModi) and (Music <> nil) then
     Music.Stop;
 end;
 
diff --git a/Game/Code/Screens/UScreenSongJumpto.pas b/Game/Code/Screens/UScreenSongJumpto.pas
index 44c12f51..79e851ab 100644
--- a/Game/Code/Screens/UScreenSongJumpto.pas
+++ b/Game/Code/Screens/UScreenSongJumpto.pas
@@ -3,7 +3,7 @@ unit UScreenSongJumpto;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenSongJumpto = class(TMenu)
diff --git a/Game/Code/Screens/UScreenSongMenu.pas b/Game/Code/Screens/UScreenSongMenu.pas
index 537536bb..2469240f 100644
--- a/Game/Code/Screens/UScreenSongMenu.pas
+++ b/Game/Code/Screens/UScreenSongMenu.pas
@@ -3,7 +3,7 @@ unit UScreenSongMenu;
 interface
 
 uses
-  UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+  UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
 
 type
   TScreenSongMenu = class(TMenu)
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
index 5f19c1d4..b9687292 100644
--- a/Game/Code/UltraStar.dpr
+++ b/Game/Code/UltraStar.dpr
@@ -26,7 +26,7 @@ uses
   UGraphic in 'Classes\UGraphic.pas',
   UTexture in 'Classes\UTexture.pas',
   UMusic in 'Classes\UMusic.pas',
-  UPliki in 'Classes\UPliki.pas',
+  //UPliki in 'Classes\UPliki.pas',
   ULanguage in 'Classes\ULanguage.pas',
   UMain in 'Classes\UMain.pas',
   UDraw in 'Classes\UDraw.pas',
@@ -107,7 +107,7 @@ uses
   SysUtils;
 
 const
-  Version = 'UltraStar Deluxe V 0.96 Beta';
+  Version = 'UltraStar Deluxe V 0.98 Beta';
 
 var
   WndTitle: string;
-- 
cgit v1.2.3