diff options
Diffstat (limited to 'Tools')
-rw-r--r-- | Tools/ScoreConverter/ScoreConverter.dpr | 17 | ||||
-rw-r--r-- | Tools/ScoreConverter/ScoreConverter.ico | bin | 0 -> 766 bytes | |||
-rw-r--r-- | Tools/ScoreConverter/ScoreConverter.res | bin | 0 -> 876 bytes | |||
-rw-r--r-- | Tools/ScoreConverter/UScores.pas | 102 | ||||
-rw-r--r-- | Tools/ScoreConverter/USongs.pas | 160 | ||||
-rw-r--r-- | Tools/ScoreConverter/Umainform.dfm | 123 | ||||
-rw-r--r-- | Tools/ScoreConverter/Umainform.pas | 230 |
7 files changed, 632 insertions, 0 deletions
diff --git a/Tools/ScoreConverter/ScoreConverter.dpr b/Tools/ScoreConverter/ScoreConverter.dpr new file mode 100644 index 00000000..2774cde4 --- /dev/null +++ b/Tools/ScoreConverter/ScoreConverter.dpr @@ -0,0 +1,17 @@ +program ScoreConverter; + +uses + Forms, + Umainform in 'Umainform.pas' {mainform}, + UScores in 'UScores.pas', + UDataBase in '..\Game\Code\Classes\UDataBase.pas', + USongs in 'USongs.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.Title := 'Score Converter'; + Application.CreateForm(Tmainform, mainform); + Application.Run; +end. diff --git a/Tools/ScoreConverter/ScoreConverter.ico b/Tools/ScoreConverter/ScoreConverter.ico Binary files differnew file mode 100644 index 00000000..80319014 --- /dev/null +++ b/Tools/ScoreConverter/ScoreConverter.ico diff --git a/Tools/ScoreConverter/ScoreConverter.res b/Tools/ScoreConverter/ScoreConverter.res Binary files differnew file mode 100644 index 00000000..2d3bea87 --- /dev/null +++ b/Tools/ScoreConverter/ScoreConverter.res diff --git a/Tools/ScoreConverter/UScores.pas b/Tools/ScoreConverter/UScores.pas new file mode 100644 index 00000000..801d796e --- /dev/null +++ b/Tools/ScoreConverter/UScores.pas @@ -0,0 +1,102 @@ +unit UScores; + +interface + +uses USongs; + +procedure ReadScore(var Song: TSong); +procedure WriteScore(var Song: TSong); +procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer); + +implementation + +uses IniFiles, SysUtils; + +procedure ReadScore(var Song: TSong); +var + F: TIniFile; + S: string; + P: integer; + Lev: integer; + LevS: string; +begin + F := TIniFile.Create(Song.Path + ChangeFileExt(Song.FileName, '.sco')); + + for Lev := 0 to 2 do begin + case Lev of + 0: LevS := 'Easy'; + 1: LevS := 'Normal'; + 2: LevS := 'Hard'; + end; + + P := 1; + S := F.ReadString(LevS + IntToStr(P), 'Name', ''); + while (S <> '') and (P<=5) do begin + SetLength(Song.Score[Lev], P); + Song.Score[Lev, P-1].Name := S; + Song.Score[Lev, P-1].Score := F.ReadInteger(LevS + IntToStr(P), 'Score', 0); + + Inc(P); + S := F.ReadString(LevS + IntToStr(P), 'Name', ''); + end; + end; +end; + +procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer); +var + S: integer; + S2: integer; +begin + S := 0; + while (S <= High(Song.Score[Level])) and (Score <= Song.Score[Level, S].Score) do + Inc(S); + // S has the number for new score + + + // we create new score + SetLength(Song.Score[Level], Length(Song.Score[Level]) + 1); + + // we move down old scores + for S2 := High(Song.Score[Level])-1 downto S do + Song.Score[Level, S2+1] := Song.Score[Level, S2]; + + // we fill new score + Song.Score[Level, S].Name := Name; + Song.Score[Level, S].Score := Score; + + if Length(Song.Score[Level]) > 5 then begin + SetLength(Song.Score[Level], 5); + end; +end; + +procedure WriteScore(var Song: TSong); +var + F: TIniFile; + S: integer; + Lev: integer; + LevS: string; + FileName: string; +begin + FileName := Song.Path + ChangeFileExt(Song.FileName, '.sco'); + if (not FileExists(FileName)) or (FileExists(FileName) and DeleteFile(FileName)) then begin + // file has been deleted -> creating new file + F := TIniFile.Create(FileName); + + for Lev := 0 to 2 do begin + case Lev of + 0: LevS := 'Easy'; + 1: LevS := 'Normal'; + 2: LevS := 'Hard'; + end; + + for S := 0 to high(Song.Score[Lev]) do begin + F.WriteString(LevS + IntToStr(S+1), 'Name', Song.Score[Lev, S].Name); + F.WriteInteger(LevS + IntToStr(S+1), 'Score', Song.Score[Lev, S].Score); + + end; // for S + end; // for Lev + F.Free; + end; // if +end; + +end. diff --git a/Tools/ScoreConverter/USongs.pas b/Tools/ScoreConverter/USongs.pas new file mode 100644 index 00000000..8f20f44f --- /dev/null +++ b/Tools/ScoreConverter/USongs.pas @@ -0,0 +1,160 @@ +unit USongs; + +interface + +type + TScore = record + Name: string; + Score: integer; + Length: string; + end; + + TSong = record + Path: string; + FileName: string; + + Title: string; + Artist: string; + + Score: array[0..2] of array of TScore; + end; + + TSongs = class + LastCount: Integer; + Song: array of TSong; // array of songs + + function ReadHeader(var rSong: TSong): boolean; + procedure BrowseDir(Dir: string); // Browse a dir + subdirs for songfiles + end; + + var Songs: TSongs; + +implementation +uses Sysutils, UMainForm, Dialogs; + +function TSongs.ReadHeader(var rSong: TSong): boolean; +var + Line, Identifier, Value: String; + Temp: word; + Done: byte; + SongFile: Textfile; +begin + Result := False; + + + //Open File and set File Pointer to the beginning + AssignFile(SongFile, rSong.Path + rSong.FileName); + Reset(SongFile); + + //Read Header + Result := true; + + //Read first Line + ReadLn (SongFile, Line); + + if (Length(Line)<=0) then + begin + Result := False; + Exit; + end; + Done := 0; + //Read Lines while Line starts with # + While (Line[1] = '#') do + begin + 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 + rSong.Title := Value; + + //Add Title Flag to Done + Done := Done or 1; + end + + //Artist + else if (Identifier = 'ARTIST') then + begin + rSong.Artist := Value; + + //Add Artist Flag to Done + Done := Done or 2; + end; + + end; + end; + + if not EOf(SongFile) then + ReadLn (SongFile, Line) + else + begin + Result := False; + break; + end; + + //End on first empty Line + if (Length(Line) = 0) then + break; + end; + + //Check if all Required Values are given + if (Done <> 3) then + begin + Result := False; + end; + + //And Close File + CloseFile(SongFile); +end; + +procedure TSongs.BrowseDir(Dir: string); +var + SR: TSearchRec; // for parsing Songs Directory + SLen: integer; +begin + if FindFirst(Dir + '*', faDirectory, SR) = 0 then begin + repeat + if (SR.Name <> '.') and (SR.Name <> '..') then + BrowseDir(Dir + Sr.Name + '\'); + until FindNext(SR) <> 0; + end; + FindClose(SR); + + if FindFirst(Dir + '*.txt', 0, SR) = 0 then begin + repeat + SLen := Length(Song); + SetLength(Song, SLen + 1); + + Song[SLen].Path := Dir; + Song[SLen].FileName := SR.Name; + + if (ReadHeader(Song[SLen]) = false) then SetLength(Song, SLen); + + //update Songs Label + if LastCount <> SLen div 30 then + begin + LastCount := SLen div 30; + MainForm.UpdateLoadedSongs(Dir, SLen); + end; + + until FindNext(SR) <> 0; + end; // if FindFirst + FindClose(SR); +end; + +end. diff --git a/Tools/ScoreConverter/Umainform.dfm b/Tools/ScoreConverter/Umainform.dfm new file mode 100644 index 00000000..a4291e7b --- /dev/null +++ b/Tools/ScoreConverter/Umainform.dfm @@ -0,0 +1,123 @@ +object mainform: Tmainform
+ Left = 328
+ Top = 228
+ HorzScrollBar.Visible = False
+ VertScrollBar.Visible = False
+ BorderIcons = [biSystemMenu, biMinimize]
+ BorderStyle = bsSingle
+ Caption = 'Ultrastar Deluxe Score Converter'
+ ClientHeight = 159
+ ClientWidth = 449
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ Position = poDesktopCenter
+ OnCreate = FormCreate
+ PixelsPerInch = 96
+ TextHeight = 13
+ object Label1: TLabel
+ Left = 8
+ Top = 8
+ Width = 60
+ Height = 13
+ Caption = 'SongFolder: '
+ end
+ object lFolder: TLabel
+ Left = 8
+ Top = 24
+ Width = 29
+ Height = 13
+ Caption = 'Folder'
+ end
+ object Label2: TLabel
+ Left = 8
+ Top = 48
+ Width = 49
+ Height = 13
+ Caption = 'Database:'
+ end
+ object lDatabase: TLabel
+ Left = 8
+ Top = 64
+ Width = 46
+ Height = 13
+ Caption = 'Database'
+ end
+ object lDatabase2: TLabel
+ Left = 72
+ Top = 48
+ Width = 54
+ Height = 13
+ Caption = 'lDatabase2'
+ end
+ object lFolder2: TLabel
+ Left = 72
+ Top = 8
+ Width = 37
+ Height = 13
+ Caption = 'lFolder2'
+ end
+ object lStatus: TLabel
+ Left = 0
+ Top = 96
+ Width = 449
+ Height = 13
+ Alignment = taCenter
+ AutoSize = False
+ Caption = 'lStatus'
+ end
+ object bFLoad: TButton
+ Left = 176
+ Top = 8
+ Width = 57
+ Height = 17
+ Caption = 'Load'
+ TabOrder = 0
+ OnClick = bFLoadClick
+ end
+ object bDLoad: TButton
+ Left = 176
+ Top = 48
+ Width = 57
+ Height = 17
+ Caption = 'Load'
+ TabOrder = 1
+ OnClick = bDLoadClick
+ end
+ object bToDB: TButton
+ Left = 16
+ Top = 112
+ Width = 153
+ Height = 17
+ Caption = 'Convert *.SCO to Database'
+ Enabled = False
+ TabOrder = 2
+ OnClick = bToDBClick
+ end
+ object bFromDB: TButton
+ Left = 288
+ Top = 112
+ Width = 145
+ Height = 17
+ Caption = 'Convert Database to *.SCO'
+ Enabled = False
+ TabOrder = 3
+ OnClick = bFromDBClick
+ end
+ object pProgress: TProgressBar
+ Left = 8
+ Top = 136
+ Width = 433
+ Height = 17
+ TabOrder = 4
+ end
+ object oDatabase: TOpenDialog
+ Filter = 'Ultrastar Deluxe Database|ultrastar.db'
+ Left = 136
+ Top = 48
+ end
+end
diff --git a/Tools/ScoreConverter/Umainform.pas b/Tools/ScoreConverter/Umainform.pas new file mode 100644 index 00000000..647cf3a4 --- /dev/null +++ b/Tools/ScoreConverter/Umainform.pas @@ -0,0 +1,230 @@ +unit Umainform; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, ComCtrls, UDataBase, ShellAPI, ShlObj, USongs; + +type + Tmainform = class(TForm) + Label1: TLabel; + lFolder: TLabel; + bFLoad: TButton; + Label2: TLabel; + lDatabase: TLabel; + bDLoad: TButton; + lDatabase2: TLabel; + lFolder2: TLabel; + bToDB: TButton; + bFromDB: TButton; + pProgress: TProgressBar; + oDatabase: TOpenDialog; + lStatus: TLabel; + procedure FormCreate(Sender: TObject); + procedure bDLoadClick(Sender: TObject); + function BrowseDialog (const Title: string; const Flag: integer): string; + procedure bFLoadClick(Sender: TObject); + procedure UpdateLoadedSongs(Path: String; Count: integer); + procedure bToDBClick(Sender: TObject); + procedure bFromDBClick(Sender: TObject); + private + { Private-Deklarationen } + public + { Public-Deklarationen } + end; + +var + mainform: Tmainform; + DBLoaded: Boolean; + SFLoaded: Boolean; + + +implementation + +uses UScores; + +{$R *.dfm} + +function Tmainform.BrowseDialog + (const Title: string; const Flag: integer): string; +var + lpItemID : PItemIDList; + BrowseInfo : TBrowseInfo; + DisplayName : array[0..MAX_PATH] of char; + TempPath : array[0..MAX_PATH] of char; +begin + Result:=''; + FillChar(BrowseInfo, sizeof(TBrowseInfo), #0); + with BrowseInfo do begin + hwndOwner := Application.Handle; + pszDisplayName := @DisplayName; + lpszTitle := PChar(Title); + ulFlags := Flag; + end; + lpItemID := SHBrowseForFolder(BrowseInfo); + if lpItemId <> nil then begin + SHGetPathFromIDList(lpItemID, TempPath); + Result := TempPath; + GlobalFreePtr(lpItemID); + end; +end; + +procedure Tmainform.FormCreate(Sender: TObject); +begin + Database := TDataBaseSystem.Create; + Songs := TSongs.Create; + lStatus.Caption := 'Welcome to USD Score Converter'; + lFolder2.Caption := 'No Songs loaded'; + lFolder.Caption := ''; + lDataBase2.Caption := 'No Database loaded'; + lDataBase.Caption := ''; +end; + +procedure Tmainform.bDLoadClick(Sender: TObject); +begin + if oDatabase.Execute then + begin + try + Database.Init(oDataBase.FileName); + lDataBase2.Caption := 'Database loaded'; + lDataBase.Caption := oDataBase.FileName; + DBLoaded := True; + except + lDataBase2.Caption := 'No Database loaded'; + lDataBase.Caption := ''; + DBLoaded := False; + end; + end; + bToDB.Enabled := DBLoaded and SFLoaded; + bFromDB.Enabled := bToDB.Enabled; +end; + +procedure Tmainform.bFLoadClick(Sender: TObject); +var + Path: String; +begin + Path := BrowseDialog('Select UltraStar SongFolder', BIF_RETURNONLYFSDIRS); + + if Path <> '' then + begin + SetLength(Songs.Song, 0); + try + Songs.BrowseDir(Path + '\'); + lFolder2.Caption := Inttostr(Length(Songs.Song)) + ' Songs loaded'; + lFolder.Caption := Path; + SFLoaded := True; + except + lFolder2.Caption := 'No Songs loaded'; + lFolder.Caption := ''; + SFLoaded := False; + end; + end; + + bToDB.Enabled := DBLoaded and SFLoaded; + bFromDB.Enabled := bToDB.Enabled; +end; + +procedure Tmainform.UpdateLoadedSongs(Path: String; Count: integer); +begin + lFolder2.Caption := Inttostr(Count) + ' Songs loaded'; + lFolder.Caption := Path; + Application.ProcessMessages; +end; + +procedure Tmainform.bToDBClick(Sender: TObject); +var + I, J, K: Integer; + LastI: integer; +begin + if (Messagebox(0, PChar('If the same directory is added more than one time the Score-File will be useless. Contėnue ?'), PChar(Mainform.Caption), MB_ICONWARNING or MB_YESNO) = IDYes) then + begin + pProgress.Max := high(Songs.Song); + pProgress.Position := 0; + // Go through all Songs + For I := 0 to high(Songs.Song) do + begin + try + //Read Scores from .SCO File + ReadScore (Songs.Song[I]); + + //Go from Easy to Difficult + For J := 0 to 2 do + begin + //Go through all Score Entrys with Difficulty J + For K := 0 to high(Songs.Song[I].Score[J]) do + begin + //Add to DataBase + DataBase.AddScore(Songs.Song[I], J, Songs.Song[I].Score[J][K].Name, Songs.Song[I].Score[J][K].Score); + end; + end; + + except + showmessage ('Error Converting Score From Song: ' + Songs.Song[I].Path + Songs.Song[I].FileName); + end; + + //Update ProgressBar + J := I div 30; + if (LastI <> J) then + begin + LastI := J; + pProgress.Position := I; + lStatus.Caption := 'Adding Songscore: ' + Songs.Song[I].Artist + ' - ' + Songs.Song[I].Title; + Application.ProcessMessages; + end; + end; + + pProgress.Position := pProgress.Max; + lStatus.Caption := 'Finished'; + end; +end; + +procedure Tmainform.bFromDBClick(Sender: TObject); +var + I, J: Integer; + LastI: integer; + anyScoreinthere: boolean; +begin + if (Messagebox(0, PChar('All Score Entrys in the Song Directory having an equivalent will be Overwritten. Contėnue ?'), PChar(Mainform.Caption), MB_ICONWARNING or MB_YESNO) = IDYes) then + begin + pProgress.Max := high(Songs.Song); + pProgress.Position := 0; + // Go through all Songs + For I := 0 to high(Songs.Song) do + begin + try + //Not Write ScoreFile when there are no Scores for this File + anyScoreinthere := false; + //Read Scores from DB File + Database.ReadScore (Songs.Song[I]); + + //Go from Easy to Difficult + For J := 0 to 2 do + begin + anyScoreinthere := anyScoreinthere or (Length(Songs.Song[I].Score[J]) > 0); + end; + + if AnyScoreinThere then + WriteScore(Songs.Song[I]); + + except + showmessage ('Error Converting Score From Song: ' + Songs.Song[I].Path + Songs.Song[I].FileName); + end; + + //Update ProgressBar + J := I div 30; + if (LastI <> J) then + begin + LastI := J; + pProgress.Position := I; + lStatus.Caption := 'Writing ScoreFile: ' + Songs.Song[I].Artist + ' - ' + Songs.Song[I].Title; + Application.ProcessMessages; + end; + end; + + pProgress.Position := pProgress.Max; + lStatus.Caption := 'Finished'; + end; +end; + +end. |