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/UAudioInput_Bass.pas | 23 +- Game/Code/Classes/UCommandLine.pas | 5 +- Game/Code/Classes/UDataBase.pas | 1 + Game/Code/Classes/UDraw.pas | 28 ++- Game/Code/Classes/UFiles.pas | 360 +++-------------------------- Game/Code/Classes/UIni.pas | 10 +- Game/Code/Classes/ULog.pas | 6 +- Game/Code/Classes/UMain.pas | 86 +++---- Game/Code/Classes/UMusic.pas | 1 + Game/Code/Classes/UPlatform.pas | 74 ++---- Game/Code/Classes/UPlatformLinux.pas | 2 +- Game/Code/Classes/UPlatformMacOSX.pas | 20 +- Game/Code/Classes/UPlatformWindows.pas | 59 ++++- Game/Code/Classes/URecord.pas | 81 +++++-- Game/Code/Classes/USongs.pas | 259 +++++++++------------ Game/Code/Screens/UScreenEditConvert.pas | 1 + Game/Code/Screens/UScreenEditHeader.pas | 6 +- Game/Code/Screens/UScreenEditSub.pas | 51 ++-- Game/Code/Screens/UScreenMain.pas | 7 +- Game/Code/Screens/UScreenOptionsRecord.pas | 132 ++++++++--- Game/Code/Screens/UScreenOptionsSound.pas | 9 +- Game/Code/Screens/UScreenScore.pas | 6 +- Game/Code/Screens/UScreenSing.pas | 91 ++++---- Game/Code/Screens/UScreenSingModi.pas | 4 +- Game/Code/Screens/UScreenSong.pas | 18 +- Game/Code/Screens/UScreenStatMain.pas | 7 +- Game/Code/Screens/UScreenTop5.pas | 18 +- Game/Code/UltraStar.dpr | 1 + 28 files changed, 599 insertions(+), 767 deletions(-) diff --git a/Game/Code/Classes/UAudioInput_Bass.pas b/Game/Code/Classes/UAudioInput_Bass.pas index 9807ffc3..75a5aee5 100644 --- a/Game/Code/Classes/UAudioInput_Bass.pas +++ b/Game/Code/Classes/UAudioInput_Bass.pas @@ -79,7 +79,7 @@ begin //Check for Soundcard with same Description For I := 0 to SC-1 do begin - if (Recording.SoundCard[I].Description = Desc) then + if (AudioInputProcessor.SoundCard[I].Description = Desc) then begin Result := True; Break; @@ -88,7 +88,7 @@ begin end; begin - with Recording do + with AudioInputProcessor do begin // checks for recording devices and puts them into an array SetLength(SoundCard, 0); @@ -170,21 +170,22 @@ var PlayerLeft, PlayerRight: integer; CaptureSoundLeft, CaptureSoundRight: TSound; begin - for S := 0 to High(Recording.Sound) do - Recording.Sound[S].BufferLong[0].Clear; + for S := 0 to High(AudioInputProcessor.Sound) do + AudioInputProcessor.Sound[S].BufferLong[0].Clear; - for SC := 0 to High(Ini.CardList) do begin + for SC := 0 to High(Ini.CardList) do + begin PlayerLeft := Ini.CardList[SC].ChannelL-1; PlayerRight := Ini.CardList[SC].ChannelR-1; if PlayerLeft >= PlayersPlay then PlayerLeft := -1; if PlayerRight >= PlayersPlay then PlayerRight := -1; if (PlayerLeft > -1) or (PlayerRight > -1) then begin if (PlayerLeft > -1) then - CaptureSoundLeft := Recording.Sound[PlayerLeft] + CaptureSoundLeft := AudioInputProcessor.Sound[PlayerLeft] else CaptureSoundLeft := nil; if (PlayerRight > -1) then - CaptureSoundRight := Recording.Sound[PlayerRight] + CaptureSoundRight := AudioInputProcessor.Sound[PlayerRight] else CaptureSoundRight := nil; @@ -224,14 +225,14 @@ end; function MicrophoneCallback(stream: HSTREAM; buffer: Pointer; len: Cardinal; Card: Cardinal): boolean; stdcall; begin - Recording.HandleMicrophoneData(buffer, len, Recording.SoundCard[Card]); + AudioInputProcessor.HandleMicrophoneData(buffer, len, AudioInputProcessor.SoundCard[Card]); Result := true; end; {* * Start input-capturing on Soundcard specified by Card. * Params: - * Card - soundcard index in Recording.SoundCard array + * Card - soundcard index in AudioInputProcessor.SoundCard array * CaptureSoundLeft - sound(-buffer) used for left channel capture data * CaptureSoundRight - sound(-buffer) used for right channel capture data *} @@ -254,7 +255,7 @@ begin end else begin - bassSoundCard := TBassSoundCard(Recording.SoundCard[Card]); + bassSoundCard := TBassSoundCard(AudioInputProcessor.SoundCard[Card]); bassSoundCard.CaptureSoundLeft := CaptureSoundLeft; bassSoundCard.CaptureSoundRight := CaptureSoundRight; @@ -267,7 +268,7 @@ end; {* * Stop input-capturing on Soundcard specified by Card. * Params: - * Card - soundcard index in Recording.SoundCard array + * Card - soundcard index in AudioInputProcessor.SoundCard array *} procedure TAudioInput_Bass.StopCard(Card: byte); begin diff --git a/Game/Code/Classes/UCommandLine.pas b/Game/Code/Classes/UCommandLine.pas index 86f822a4..55dfc6ce 100644 --- a/Game/Code/Classes/UCommandLine.pas +++ b/Game/Code/Classes/UCommandLine.pas @@ -61,7 +61,8 @@ const implementation -uses SysUtils; +uses SysUtils, + uPlatform; // uINI -- Nasty requirement... ( removed with permission of blindy ) @@ -99,7 +100,7 @@ begin writeln( '' ); - halt; + platform.halt; end; //------------- diff --git a/Game/Code/Classes/UDataBase.pas b/Game/Code/Classes/UDataBase.pas index e99cb891..b5636d52 100644 --- a/Game/Code/Classes/UDataBase.pas +++ b/Game/Code/Classes/UDataBase.pas @@ -9,6 +9,7 @@ interface {$I switches.inc} uses USongs, + USong, SQLiteTable3; //-------------------- diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas index c399057b..662050dc 100644 --- a/Game/Code/Classes/UDraw.pas +++ b/Game/Code/Classes/UDraw.pas @@ -161,7 +161,7 @@ end; procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer); var - Pet: integer; + Pet : integer; begin; // Log.LogStatus('Oscilloscope', 'SingDraw'); glColor3f(Skin_OscR, Skin_OscG, Skin_OscB); @@ -169,14 +169,19 @@ begin; glColor3f(1, 1, 1); } glBegin(GL_LINE_STRIP); - glVertex2f(X, -Recording.Sound[NrSound].BufferArray[1] / $10000 * H + Y + H/2); - for Pet := 2 to Recording.Sound[NrSound].n div 1 do begin - glVertex2f(X + (Pet-1) * W / (Recording.Sound[NrSound].n - 1), - -Recording.Sound[NrSound].BufferArray[Pet] / $10000 * H + Y + H/2); + + glVertex2f(X, -AudioInputProcessor.Sound[NrSound].BufferArray[1] / $10000 * H + Y + H/2); + + for Pet := 2 to AudioInputProcessor.Sound[NrSound].n div 1 do + begin + glVertex2f( X + (Pet-1) * W / (AudioInputProcessor.Sound[NrSound].n - 1), + -AudioInputProcessor.Sound[NrSound].BufferArray[Pet] / $10000 * H + Y + H/2 ); end; glEnd; end; + + procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer); var Pet: integer; @@ -366,7 +371,7 @@ var glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if Player[NrGracza].IlNut > 0 then +//// if Player[NrGracza].IlNut > 0 then begin TempR := W / (Czesci[0].Czesc[Czesci[0].Akt].Koniec - Czesci[0].Czesc[Czesci[0].Akt].StartNote); for N := 0 to Player[NrGracza].HighNut do @@ -480,14 +485,7 @@ begin lTmpA := (Right-Left); lTmpB := (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); - - {$IFDEF LAZARUS} -{* - writeln( 'UDRAW (Right-Left) : ' + floattostr( lTmpA ) ); - writeln( 'UDRAW : ' + floattostr( lTmpB ) ); - writeln( '' ); -*} - {$ENDIF} + if ( lTmpA > 0 ) AND ( lTmpB > 0 ) THEN @@ -555,7 +553,7 @@ begin end; // if not FreeStyle end; // with end; // for - end; // with + end; // with 1 glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); 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 diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas index e4f5e823..599bb8fa 100644 --- a/Game/Code/Classes/UIni.pas +++ b/Game/Code/Classes/UIni.pas @@ -463,9 +463,9 @@ begin //{ B := False; //Look for Soundcard - for I2 := 0 to High(Recording.SoundCard) do + for I2 := 0 to High(AudioInputProcessor.SoundCard) do begin - if (S = Trim(Recording.SoundCard[I2].Description)) then + if (S = Trim(AudioInputProcessor.SoundCard[I2].Description)) then begin B := True; Break; @@ -485,12 +485,12 @@ begin end; // Record - append detected soundcards - for I := 0 to High(Recording.SoundCard) do + for I := 0 to High(AudioInputProcessor.SoundCard) do begin B := False; For I2 := 0 to High(CardList) do begin //Search for Card in List - if (CardList[I2].Name = Trim(Recording.SoundCard[I].Description)) then + if (CardList[I2].Name = Trim(AudioInputProcessor.SoundCard[I].Description)) then begin B := True; Break; @@ -502,7 +502,7 @@ begin begin I3 := Length(CardList); SetLength(CardList, I3+1); - CardList[I3].Name := Trim(Recording.SoundCard[I].Description); + CardList[I3].Name := Trim(AudioInputProcessor.SoundCard[I].Description); CardList[I3].Input := 0; CardList[I3].ChannelL := 0; CardList[I3].ChannelR := 0; diff --git a/Game/Code/Classes/ULog.pas b/Game/Code/Classes/ULog.pas index fc567d54..49b02c00 100644 --- a/Game/Code/Classes/ULog.pas +++ b/Game/Code/Classes/ULog.pas @@ -212,9 +212,9 @@ begin FS := TFileStream.Create(FileName, fmCreate); - for BL := 0 to High(Recording.Sound[SoundNr].BufferLong) do begin - Recording.Sound[SoundNr].BufferLong[BL].Seek(0, soBeginning); - FS.CopyFrom(Recording.Sound[SoundNr].BufferLong[BL], Recording.Sound[SoundNr].BufferLong[BL].Size); + for BL := 0 to High(AudioInputProcessor.Sound[SoundNr].BufferLong) do begin + AudioInputProcessor.Sound[SoundNr].BufferLong[BL].Seek(0, soBeginning); + FS.CopyFrom(AudioInputProcessor.Sound[SoundNr].BufferLong[BL], AudioInputProcessor.Sound[SoundNr].BufferLong[BL].Size); end; FS.Free; diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index e2e0eaa0..901d7370 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -20,6 +20,7 @@ uses ULog, ULyrics, UScreenSing, + USong, OpenGL12, {$IFDEF UseSerialPort} zlportio {you can disable it and all PortWriteB calls}, @@ -107,6 +108,8 @@ var Player: array of TPlayer; PlayersPlay: integer; + CurrentSong : TSong; + procedure InitializePaths; Procedure Main; @@ -130,7 +133,7 @@ uses USongs, math, UCommandLine, ULanguage, SDL_ttf, USkins, UCovers, UCatCovers, UDataBase, UPlaylist, UDLLManager, - UParty, UCore, UGraphicClasses, UPluginDefs, UPlatform; + UParty, UCore, UGraphicClasses, UPluginDefs, UPlatform; const Version = 'UltraStar Deluxe V 1.10 Alpha Build'; @@ -192,12 +195,14 @@ begin Log.BenchmarkEnd(1); Log.LogBenchmark('Loading Skin List', 1); +(* // Sound Card List Log.BenchmarkStart(1); Log.LogStatus('Loading Soundcard list', 'Initialization'); Recording := TRecord.Create; Log.BenchmarkEnd(1); Log.LogBenchmark('Loading Soundcard list', 1); +*) // Sound (+ fills Sound Card List) Log.BenchmarkStart(1); @@ -508,23 +513,23 @@ procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real); var NewTime: real; begin - if High(AktSong.BPM) = BPMNum then begin + if High(CurrentSong.BPM) = BPMNum then begin // last BPM - CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); + CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time); Time := 0; end else begin // not last BPM // count how much time is it for start of the new BPM and store it in NewTime - NewTime := GetTimeForBeats(AktSong.BPM[BPMNum].BPM, AktSong.BPM[BPMNum+1].StartBeat - AktSong.BPM[BPMNum].StartBeat); + NewTime := GetTimeForBeats(CurrentSong.BPM[BPMNum].BPM, CurrentSong.BPM[BPMNum+1].StartBeat - CurrentSong.BPM[BPMNum].StartBeat); // compare it to remaining time if (Time - NewTime) > 0 then begin // there is still remaining time - CurBeat := AktSong.BPM[BPMNum].StartBeat; + CurBeat := CurrentSong.BPM[BPMNum].StartBeat; Time := Time - NewTime; end else begin // there is no remaining time - CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); + CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time); Time := 0; end; // if end; // if @@ -539,18 +544,18 @@ var // TempTime: real; begin Result := 0; - if Length(AktSong.BPM) = 1 then Result := Time * AktSong.BPM[0].BPM / 60; + if Length(CurrentSong.BPM) = 1 then Result := Time * CurrentSong.BPM[0].BPM / 60; (* 2 BPMs *) -{ if Length(AktSong.BPM) > 1 then begin +{ if Length(CurrentSong.BPM) > 1 then begin (* new system *) CurBeat := 0; - TopBeat := GetBeats(AktSong.BPM[0].BPM, Time); - if TopBeat > AktSong.BPM[1].StartBeat then begin + TopBeat := GetBeats(CurrentSong.BPM[0].BPM, Time); + if TopBeat > CurrentSong.BPM[1].StartBeat then begin // analyze second BPM - Time := Time - GetTimeForBeats(AktSong.BPM[0].BPM, AktSong.BPM[1].StartBeat - CurBeat); - CurBeat := AktSong.BPM[1].StartBeat; - TopBeat := GetBeats(AktSong.BPM[1].BPM, Time); + Time := Time - GetTimeForBeats(CurrentSong.BPM[0].BPM, CurrentSong.BPM[1].StartBeat - CurBeat); + CurBeat := CurrentSong.BPM[1].StartBeat; + TopBeat := GetBeats(CurrentSong.BPM[1].BPM, Time); Result := CurBeat + TopBeat; end else begin @@ -560,7 +565,7 @@ begin end; // if} (* more BPMs *) - if Length(AktSong.BPM) > 1 then begin + if Length(CurrentSong.BPM) > 1 then begin CurBeat := 0; CurBPM := 0; @@ -578,21 +583,21 @@ var CurBPM: integer; begin Result := 0; - if Length(AktSong.BPM) = 1 then Result := AktSong.GAP / 1000 + Beat * 60 / AktSong.BPM[0].BPM; + if Length(CurrentSong.BPM) = 1 then Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM; (* more BPMs *) - if Length(AktSong.BPM) > 1 then begin - Result := AktSong.GAP / 1000; + if Length(CurrentSong.BPM) > 1 then begin + Result := CurrentSong.GAP / 1000; CurBPM := 0; - while (CurBPM <= High(AktSong.BPM)) and (Beat > AktSong.BPM[CurBPM].StartBeat) do begin - if (CurBPM < High(AktSong.BPM)) and (Beat >= AktSong.BPM[CurBPM+1].StartBeat) then begin + while (CurBPM <= High(CurrentSong.BPM)) and (Beat > CurrentSong.BPM[CurBPM].StartBeat) do begin + if (CurBPM < High(CurrentSong.BPM)) and (Beat >= CurrentSong.BPM[CurBPM+1].StartBeat) then begin // full range - Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (AktSong.BPM[CurBPM+1].StartBeat - AktSong.BPM[CurBPM].StartBeat); + Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) * (CurrentSong.BPM[CurBPM+1].StartBeat - CurrentSong.BPM[CurBPM].StartBeat); end; - if (CurBPM = High(AktSong.BPM)) or (Beat < AktSong.BPM[CurBPM+1].StartBeat) then begin + if (CurBPM = High(CurrentSong.BPM)) or (Beat < CurrentSong.BPM[CurBPM+1].StartBeat) then begin // in the middle - Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (Beat - AktSong.BPM[CurBPM].StartBeat); + Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) * (Beat - CurrentSong.BPM[CurBPM].StartBeat); end; Inc(CurBPM); end; @@ -615,7 +620,7 @@ begin Czas.Teraz := Czas.Teraz + TimeSkip; Czas.OldBeat := Czas.AktBeat; - Czas.MidBeat := GetMidBeat(Czas.Teraz - (AktSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function + Czas.MidBeat := GetMidBeat(Czas.Teraz - (CurrentSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function Czas.AktBeat := Floor(Czas.MidBeat); // Czas.OldHalf := Czas.AktHalf; @@ -623,11 +628,11 @@ begin // Czas.AktHalf := Floor(Czas.MidHalf); Czas.OldBeatC := Czas.AktBeatC; - Czas.MidBeatC := GetMidBeat(Czas.Teraz - (AktSong.Gap) / 1000); + Czas.MidBeatC := GetMidBeat(Czas.Teraz - (CurrentSong.Gap) / 1000); Czas.AktBeatC := Floor(Czas.MidBeatC); Czas.OldBeatD := Czas.AktBeatD; - Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (AktSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP + Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (CurrentSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP Czas.AktBeatD := Floor(Czas.MidBeatD); Czas.FracBeatD := Frac(Czas.MidBeatD); @@ -822,7 +827,7 @@ begin // beep; // On linux we get an AV @ NEWNOTE, line 600 of Classes/UMain.pas - if not assigned( Recording.Sound ) then // TODO : JB_Linux ... why is this now not assigned... it was fine a few hours ago.. + if not assigned( AudioInputProcessor.Sound ) then // TODO : JB_Linux ... why is this now not assigned... it was fine a few hours ago.. exit; // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth) @@ -831,7 +836,7 @@ begin begin // analyze buffer - Recording.Sound[CP].AnalizujBufor; + AudioInputProcessor.Sound[CP].AnalyzeBuffer; // adds some noise // Czas.Ton := Czas.Ton + Round(Random(3)) - 1; @@ -866,7 +871,7 @@ begin // Czas.Ton := 27; // gdy moze, to dodaje nute - if (Recording.Sound[CP].SzczytJest) and (Mozna) then begin + if (AudioInputProcessor.Sound[CP].SzczytJest) and (Mozna) then begin // operowanie na ostatniej nucie for Pet := 0 to Czesci[0].Czesc[S].HighNut do if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1) @@ -875,10 +880,11 @@ begin // to robi, tylko dla pary nut (oryginalnej i gracza) // przesuwanie tonu w odpowiednia game - while (Recording.Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do - Recording.Sound[CP].Ton := Recording.Sound[CP].Ton - 12; - while (Recording.Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do - Recording.Sound[CP].Ton := Recording.Sound[CP].Ton + 12; + while (AudioInputProcessor.Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do + AudioInputProcessor.Sound[CP].Ton := AudioInputProcessor.Sound[CP].Ton - 12; + + while (AudioInputProcessor.Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do + AudioInputProcessor.Sound[CP].Ton := AudioInputProcessor.Sound[CP].Ton + 12; // Half size Notes Patch NoteHit := false; @@ -887,8 +893,9 @@ begin //if Ini.Difficulty = 1 then Range := 1; //if Ini.Difficulty = 2 then Range := 0; Range := 2 - Ini.Difficulty; - if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - Recording.Sound[CP].Ton) <= Range then begin - Recording.Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton; + + if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - AudioInputProcessor.Sound[CP].Ton) <= Range then begin + AudioInputProcessor.Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton; // Half size Notes Patch @@ -929,7 +936,7 @@ begin Nowa := true; // jezeli ostatnia ma ten sam ton if (Player[CP].IlNut > 0 ) - and (Player[CP].Nuta[Player[CP].HighNut].Ton = Recording.Sound[CP].Ton) + and (Player[CP].Nuta[Player[CP].HighNut].Ton = AudioInputProcessor.Sound[CP].Ton) and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD) then Nowa := false; // jezeli jest jakas nowa nuta na sprawdzanym beacie @@ -943,10 +950,10 @@ begin Player[CP].IlNut := Player[CP].IlNut + 1; Player[CP].HighNut := Player[CP].HighNut + 1; SetLength(Player[CP].Nuta, Player[CP].IlNut); - Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD; + Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD; Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1; - Player[CP].Nuta[Player[CP].HighNut].Ton := Recording.Sound[CP].Ton; // Ton || TonDokl - Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat; + Player[CP].Nuta[Player[CP].HighNut].Ton := AudioInputProcessor.Sound[CP].Ton; // Ton || TonDokl + Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat; // Half Note Patch @@ -977,7 +984,8 @@ begin //On Sentence End -> For LineBonus + SingBar if (sDet >= low(Czesci[0].Czesc)) AND (sDet <= high(Czesci[0].Czesc)) then -if ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then +if assigned( Sender ) AND + ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then Sender.onSentenceEnd(sDet); end; diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index bf366130..a7f1918f 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -413,6 +413,7 @@ end; initialization begin singleton_AudioManager := TInterfaceList.Create(); + end; finalization diff --git a/Game/Code/Classes/UPlatform.pas b/Game/Code/Classes/UPlatform.pas index 19a960e7..bfb03d54 100644 --- a/Game/Code/Classes/UPlatform.pas +++ b/Game/Code/Classes/UPlatform.pas @@ -16,7 +16,6 @@ interface uses Classes; type - TDirectoryEntry = Record Name : WideString; IsDirectory : Boolean; @@ -27,33 +26,16 @@ type IPlatform = Interface ['{63A5EBC3-3F4D-4F23-8DFB-B5165FCA23DF}'] - Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; - function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; - - function GetLogPath : WideString; - function GetGameSharedPath : WideString; - function GetGameUserPath : WideString; - end; - - TPlatform = class( TInterfacedOBject, IPlatform ) - - // DirectoryFindFiles returns all files matching the filter. Do not use '*' in the filter. - // If you set ReturnAllSubDirs = true all directories will be returned, if yout set it to false - // directories are completely ignored. - function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; virtual; abstract; - - function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; virtual; - -// function GetGamePath : WideString; virtual; - function GetLogPath : WideString; virtual; - function GetGameSharedPath : WideString; virtual; - function GetGameUserPath : WideString; virtual; - + Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; + function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; + function FindSongFile(Dir, Mask: widestring): widestring; + procedure halt; + function GetLogPath : WideString; + function GetGameSharedPath : WideString; + function GetGameUserPath : WideString; end; - -var - Platform : IPlatform; + function Platform : IPlatform; implementation @@ -69,48 +51,30 @@ uses UPlatformMacOSX; {$ENDIF} -{ TPlatform } -(* -function TPlatform.GetGamePath: WideString; -begin - // Windows and Linux use this: - Result := ExtractFilePath(ParamStr(0)); -end; -*) -function TPlatform.GetLogPath : WideString; -begin - result := ExtractFilePath(ParamStr(0)); -end; - -function TPlatform.GetGameSharedPath : WideString; -begin - result := ExtractFilePath(ParamStr(0)); -end; +// I have modified it to use the Platform_singleton in this location ( in the implementaiton ) +// so that this variable can NOT be overwritten from anywhere else in the application. +// the accessor function platform, emulates all previous calls to work the same way. +var + Platform_singleton : IPlatform; -function TPlatform.GetGameUserPath : WideString; +function Platform : IPlatform; begin - result := ExtractFilePath(ParamStr(0)); + result := Platform_singleton; end; -function TPlatform.TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; -begin - // Linux and Mac don't check for running apps at the moment - Result := false; -end; initialization - {$IFDEF MSWINDOWS} - Platform := TPlatformWindows.Create; + Platform_singleton := TPlatformWindows.Create; {$ENDIF} {$IFDEF LINUX} - Platform := TPlatformLinux.Create; + Platform_singleton := TPlatformLinux.Create; {$ENDIF} {$IFDEF DARWIN} - Platform := TPlatformMacOSX.Create; + Platform_singleton := TPlatformMacOSX.Create; {$ENDIF} finalization - Platform := nil; + Platform_singleton := nil; end. diff --git a/Game/Code/Classes/UPlatformLinux.pas b/Game/Code/Classes/UPlatformLinux.pas index 0098baee..cde737b6 100644 --- a/Game/Code/Classes/UPlatformLinux.pas +++ b/Game/Code/Classes/UPlatformLinux.pas @@ -12,7 +12,7 @@ uses Classes, UPlatform; type - TPlatformLinux = class(TPlatform) + TPlatformLinux = class(TInterfacedObject, IPlatform) function get_homedir(): string; public Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; override; diff --git a/Game/Code/Classes/UPlatformMacOSX.pas b/Game/Code/Classes/UPlatformMacOSX.pas index a418919c..97c32fe3 100644 --- a/Game/Code/Classes/UPlatformMacOSX.pas +++ b/Game/Code/Classes/UPlatformMacOSX.pas @@ -12,13 +12,20 @@ uses Classes, UPlatform; type - TPlatformMacOSX = class(TPlatform) + TPlatformMacOSX = class( TInterfacedObject, IPlatform) private public +<<<<<<< .mine + Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; override; + function GetGamePath: WideString; override; + function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; + procedure halt(); +======= function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; override; function GetLogPath : WideString; override; function GetGameSharedPath : WideString; override; function GetGameUserPath : WideString; override; +>>>>>>> .r788 end; implementation @@ -100,4 +107,15 @@ begin FPCloseDir(TheDir); end; +function TPlatformMacOSX.TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; +begin + result := false; +end; + + +procedure TPlatformMacOSX.halt; +begin + halt; +end; + end. diff --git a/Game/Code/Classes/UPlatformWindows.pas b/Game/Code/Classes/UPlatformWindows.pas index 93e72e7a..d4ba757a 100644 --- a/Game/Code/Classes/UPlatformWindows.pas +++ b/Game/Code/Classes/UPlatformWindows.pas @@ -8,19 +8,30 @@ interface {$I switches.inc} -uses Classes, UPlatform; +uses Classes, + UPlatform; type - TPlatformWindows = class(TPlatform) + TPlatformWindows = class( TInterfacedObject, IPlatform) public - Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; override; - function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; override; + Function DirectoryFindFiles(Dir, Filter : WideString; ReturnAllSubDirs : Boolean) : TDirectoryEntryArray; + function TerminateIfAlreadyRunning(var WndTitle : String) : Boolean; + function GetGamePath: WideString; + function FindSongFile(Dir, Mask: widestring): widestring; + + procedure halt; + + function GetLogPath : WideString; + function GetGameSharedPath : WideString; + function GetGameUserPath : WideString; end; implementation -uses SysUtils, Windows; +uses SysUtils, + Windows, + Forms; type @@ -175,4 +186,42 @@ begin FindCloseW(SR); end; +function TPlatformWindows.GetGamePath: WideString; +begin + // Windows and Linux use this: + Result := ExtractFilePath(ParamStr(0)); +end; + +procedure TPlatformWindows.halt; +begin + application.terminate; +end; + +function TPlatformWindows.GetLogPath : WideString; +begin + result := ExtractFilePath(ParamStr(0)); +end; + +function TPlatformWindows.GetGameSharedPath : WideString; +begin + result := ExtractFilePath(ParamStr(0)); +end; + +function TPlatformWindows.GetGameUserPath : WideString; +begin + result := ExtractFilePath(ParamStr(0)); +end; + + function TPlatformWindows.FindSongFile(Dir, Mask: widestring): widestring; + var + SR: TSearchRec; // for parsing song directory +begin + Result := ''; + if SysUtils.FindFirst(Dir + Mask, faDirectory, SR) = 0 then begin + Result := SR.Name; + end; // if + SysUtils.FindClose(SR); +end; + + end. diff --git a/Game/Code/Classes/URecord.pas b/Game/Code/Classes/URecord.pas index dee1a687..ab351f6e 100644 --- a/Game/Code/Classes/URecord.pas +++ b/Game/Code/Classes/URecord.pas @@ -14,7 +14,9 @@ uses Classes, UCommon, UMusic, UIni; - + +// http://www.poltran.com + type TSound = class BufferNew: TMemoryStream; // buffer for newest sample @@ -26,7 +28,7 @@ type // pitch detection SzczytJest: boolean; // czy jest szczyt - Szczyt: integer; // pozycja szczytu na osi poziomej + pivot : integer; // Position of summit (top) on horizontal pivot TonDokl: real; // ton aktualnego szczytu Ton: integer; // ton bez ulamka TonGamy: integer; // ton w gamie. wartosci: 0-11 @@ -34,8 +36,8 @@ type // procedures procedure ProcessNewBuffer; - procedure AnalizujBufor; // use to analyze sound from buffers to get new pitch - procedure AnalizujByAutocorrelation; // we call it to analyze sound by checking Autocorrelation + procedure AnalyzeBuffer; // use to analyze sound from buffers to get new pitch + procedure AnalyzeByAutocorrelation; // we call it to analyze sound by checking Autocorrelation function AnalyzeAutocorrelationFreq(Freq: real): real; // use this to check one frequency by Autocorrelation end; @@ -54,31 +56,46 @@ type CaptureSoundRight: TSound; // sound(-buffer) used for right channel capture data end; - TRecord = class + TAudioInputProcessor = class Sound: array of TSound; SoundCard: array of TGenericSoundCard; + constructor Create; - + // handle microphone input procedure HandleMicrophoneData(Buffer: Pointer; Length: Cardinal; - InputDevice: TGenericSoundCard); + InputDevice: TGenericSoundCard); + + function volume( aChannel : byte ): byte; end; smallintarray = array [0..maxInt shr 1-1] of smallInt; psmallintarray = ^smallintarray; -var - Poz: integer; - Recording: TRecord; + function AudioInputProcessor(): TAudioInputProcessor; implementation uses UMain; +var + singleton_AudioInputProcessor : TAudioInputProcessor = nil; + + // FIXME: Race-Conditions between Callback-thread and main-thread // on BufferArray (maybe BufferNew also). // Use SDL-mutexes to solve this problem. + +function AudioInputProcessor(): TAudioInputProcessor; +begin + if singleton_AudioInputProcessor = nil then + singleton_AudioInputProcessor := TAudioInputProcessor.create(); + + result := singleton_AudioInputProcessor; + +end; + procedure TSound.ProcessNewBuffer; var S: integer; @@ -108,12 +125,12 @@ begin end; end; -procedure TSound.AnalizujBufor; +procedure TSound.AnalyzeBuffer; begin - AnalizujByAutocorrelation; + AnalyzeByAutocorrelation; end; -procedure TSound.AnalizujByAutocorrelation; +procedure TSound.AnalyzeByAutocorrelation; var T: integer; // tone F: real; // freq @@ -143,7 +160,7 @@ begin // analyze all 12 halftones for T := 0 to 35 do // to 11, then 23, now 35 (for Whitney and my high voice) begin - F := 130.81*Power(1.05946309436, T)/2; // let's analyze below 130.81 + F := 130.81 * Power(1.05946309436, T)/2; // let's analyze below 130.81 Wages[T] := AnalyzeAutocorrelationFreq(F); if Wages[T] > MaxW then @@ -164,8 +181,8 @@ begin if MaxV >= Threshold then begin // found acceptable volume // 0.1 SzczytJest := true; - TonGamy := MaxT mod 12; - Ton := MaxT mod 12; + TonGamy := MaxT mod 12; + Ton := MaxT mod 12; end; end; @@ -206,8 +223,7 @@ end; * Length - number of bytes in Buffer * Input - Soundcard-Input used for capture *} -procedure TRecord.HandleMicrophoneData(Buffer: Pointer; Length: Cardinal; - InputDevice: TGenericSoundCard); +procedure TAudioInputProcessor.HandleMicrophoneData(Buffer: Pointer; Length: Cardinal; InputDevice: TGenericSoundCard); var L: integer; S: integer; @@ -231,8 +247,14 @@ begin for S := 0 to L-1 do begin I := PSI^[S] * Boost; - if I > 32767 then I := 32767; // 0.5.0: limit - if I < -32768 then I := -32768; // 0.5.0: limit + + // TODO : JB - This will clip the audio... cant we reduce the "Boot" if the data clips ?? + if I > 32767 then + I := 32767; // 0.5.0: limit + + if I < -32768 then + I := -32768; // 0.5.0: limit + PSI^[S] := I; end; @@ -266,12 +288,13 @@ begin end; end; -constructor TRecord.Create; +constructor TAudioInputProcessor.Create; var S: integer; begin SetLength(Sound, 6 {max players});//Ini.Players+1); - for S := 0 to High(Sound) do begin //Ini.Players do begin + for S := 0 to High(Sound) do + begin //Ini.Players do begin Sound[S] := TSound.Create; Sound[S].Num := S; Sound[S].BufferNew := TMemoryStream.Create; @@ -281,6 +304,20 @@ begin end; end; +function TAudioInputProcessor.volume( aChannel : byte ): byte; +var + lCount : Integer; + lMaxVol : double; +begin; + lMaxVol := AudioInputProcessor.Sound[aChannel].BufferArray[1]; + for lCount := 2 to AudioInputProcessor.Sound[aChannel].n div 1 do + begin + if AudioInputProcessor.Sound[aChannel].BufferArray[lCount] > lMaxVol then + lMaxVol := AudioInputProcessor.Sound[aChannel].BufferArray[lCount]; + end; + + result := trunc( ( 255 / 32767 ) * trunc( lMaxVol ) ); +end; end. diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas index a4709b43..c5acec9c 100644 --- a/Game/Code/Classes/USongs.pas +++ b/Game/Code/Classes/USongs.pas @@ -40,6 +40,7 @@ uses {$IFDEF USE_PSEUDO_THREAD} PseudoThread, {$ENDIF} + USong, UCatCovers; type @@ -55,48 +56,6 @@ type Length: string; end; - TSong = record - Path: widestring; - Folder: widestring; // for sorting by folder - FileName: widestring; - - // sorting methods - Category: array of widestring; // I think I won't need this - Genre: widestring; - Edition: widestring; - Language: widestring; // 0.5.0: new - - Title: widestring; - Artist: widestring; - - Text: widestring; - Creator: widestring; - - Cover: widestring; - CoverTex: TTexture; - Mp3: widestring; - Background: widestring; - Video: widestring; - VideoGAP: real; - VideoLoaded: boolean; // 0.5.0: true if the video has been loaded - NotesGAP: integer; - Start: real; // in seconds - Finish: integer; // in miliseconds - Relative: boolean; - Resolution: integer; - BPM: array of TBPM; - GAP: real; // in miliseconds - - Score: array[0..2] of array of TScore; - - // these are used when sorting is enabled - Visible: boolean; // false if hidden, true if visible - Main: boolean; // false for songs, true for category buttons - OrderNum: integer; // has a number of category for category buttons and songs - OrderTyp: integer; // type of sorting for this button (0=name) - CatNumber: integer; // Count of Songs in Category for Cats and Number of Song in Category for Songs - end; - {$IFDEF USE_PSEUDO_THREAD} TSongs = class( TPseudoThread ) @@ -104,7 +63,6 @@ type TSongs = class( TThread ) {$ENDIF} private - BrowsePos : Integer; //Actual Pos in Song Array. eddie: Must be int, because it could be decremented to -1. fNotify , fWatch : longint; fParseSongDirectory : boolean; @@ -117,9 +75,13 @@ type protected procedure Execute; override; public - Song : array of TSong; // array of songs +// Song : array of TSong; // array of songs + SongList : TList; // array of songs Selected : integer; // selected song index constructor create(); + destructor destroy(); + + procedure LoadSongList; // load all songs procedure BrowseDir(Dir: widestring); // should return number of songs in the future procedure Sort(Order: integer); @@ -127,6 +89,7 @@ type property Processing : boolean read fProcessing; end; + TCatSongs = class Song: array of TSong; // array of categories with songs Selected: integer; // selected song index @@ -150,7 +113,6 @@ type var Songs: TSongs; // all songs CatSongs: TCatSongs; // categorized songs - AktSong: TSong; // one song *unknown use) const IN_ACCESS = $00000001; //* File was accessed */ @@ -187,6 +149,8 @@ begin inherited create( false ); self.freeonterminate := true; + SongList := TList.create(); + {$ifdef Delphi} fDirWatch := TDirectoryWatch.create(nil); fDirWatch.OnChange := DoDirChanged; @@ -218,12 +182,18 @@ begin writeln( 'Calling syscall_nr_inotify_init : '+ inttostr(fWatch) ); *) {$endif} - -{$IFNDEF USE_PSEUDO_THREAD} - Setlength(Song, 0); + +{$IFNDEF USE_PSEUDO_THREAD} +// Setlength(Song, 0); + SongList.clear; {$ENDIF} end; +destructor TSongs.destroy(); +begin + freeandnil( SongList ); +end; + procedure TSongs.DoDirChanged(Sender: TObject); begin LoadSongList(); @@ -237,7 +207,7 @@ begin int_LoadSongList(); {$ELSE} fParseSongDirectory := true; - + while not self.terminated do begin @@ -256,21 +226,15 @@ procedure TSongs.int_LoadSongList; begin try fProcessing := true; - Setlength(Song, 0); + SongList.clear; Log.LogError('SongList', 'Searching For Songs'); - Setlength(Song, 50); - - BrowsePos := 0; // browse directories BrowseDir(SongPath); - + if UserSongPath <> SongPath then BrowseDir(UserSongPath); - - //Set Correct SongArray Length - SetLength(Song, BrowsePos); if assigned( CatSongs ) then CatSongs.Refresh; @@ -287,7 +251,6 @@ begin ScreenSong.OnShow; // refresh ScreenSong end; - finally Log.LogError('SongList', 'Search Complete'); @@ -305,12 +268,13 @@ end; procedure TSongs.BrowseDir(Dir: widestring); var - SLen: integer; - i : Integer; + i : Integer; Files : TDirectoryEntryArray; + lSong : TSong; begin Files := Platform.DirectoryFindFiles( Dir, '.txt', true); + for i := 0 to Length(Files)-1 do begin if Files[i].IsDirectory then @@ -319,37 +283,21 @@ begin end else begin - SLen := BrowsePos; + lSong := TSong.create( Dir + Files[i].Name ); - Song[SLen].Path := Dir; -// Song[SLen].Folder := Copy(Dir, Length(SongPath)+1, 10000); - Song[SLen].Folder := Copy(Dir, Length(Dir)+1, 10000); - Song[SLen].Folder := Copy(Song[SLen].Folder, 1, Pos( PathDelim , Song[SLen].Folder)-1); - Song[SLen].FileName := Files[i].Name; - - if (AnalyseFile(Song[SLen]) = false) then + if NOT lSong.Analyse then begin Log.LogError('AnalyseFile failed for "' + Files[i].Name + '".'); - Dec(BrowsePos); + freeandnil( lSong ); end else begin - if Song[SLen].Cover = '' then - Song[SLen].Cover := FindSongFile(Dir, '*[CO].jpg'); + SongList.add( lSong ); end; - //Change Length Only every 50 Entrys - Inc(BrowsePos); - - if (BrowsePos mod 50 = 0) AND (BrowsePos <> 0) then - begin - SetLength(Song, Length(Song) + 50); - end; end; end; SetLength( Files, 0); - -// Log.LogStatus('Parsing directory: ' + Dir + SR.Name, 'LoadSongList'); end; procedure TSongs.Sort(Order: integer); @@ -361,91 +309,99 @@ begin case Order of sEdition: // by edition begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Edition, Song[S-1].Edition) < 0 then begin + for S2 := 0 to SongList.Count -1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Edition, TSong( SongList[S-1] ).Edition) < 0 then + begin // zamiana miejscami - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; sGenre: // by genre begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Genre, Song[S-1].Genre) < 0 then begin + for S2 := 0 to SongList.Count-1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Genre, TSong( SongList[S-1] ).Genre) < 0 then + begin // zamiana miejscami - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; sTitle: // by title begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Title, Song[S-1].Title) < 0 then begin + for S2 := 0 to SongList.Count-1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Title, TSong( SongList[S-1] ).Title) < 0 then + begin // zamiana miejscami - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; sArtist: // by artist begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Artist, Song[S-1].Artist) < 0 then begin + for S2 := 0 to SongList.Count-1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Artist, TSong( SongList[S-1] ).Artist) < 0 then + begin // zamiana miejscami - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; sFolder: // by folder begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Folder, Song[S-1].Folder) < 0 then begin + for S2 := 0 to SongList.Count-1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Folder, TSong( SongList[S-1] ).Folder) < 0 then + begin // zamiana miejscami - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; sTitle2: // by title2 begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Title, Song[S-1].Title) < 0 then begin + for S2 := 0 to SongList.Count-1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Title, TSong( SongList[S-1] ).Title) < 0 then + begin // zamiana miejscami - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; sArtist2: // by artist2 begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Artist, Song[S-1].Artist) < 0 then begin + for S2 := 0 to SongList.Count-1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Artist, TSong( SongList[S-1] ).Artist) < 0 then + begin // zamiana miejscami - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; sLanguage: // by Language begin - for S2 := 0 to Length(Song)-1 do - for S := 1 to Length(Song)-1 do - if CompareText(Song[S].Language, Song[S-1].Language) < 0 then begin - TempSong := Song[S-1]; - Song[S-1] := Song[S]; - Song[S] := TempSong; + for S2 := 0 to SongList.Count-1 do + for S := 1 to SongList.Count-1 do + if CompareText(TSong( SongList[S] ).Language, TSong( SongList[S-1] ).Language) < 0 then + begin + TempSong := SongList[S-1]; + SongList[S-1] := SongList[S]; + SongList[S] := TempSong; end; end; @@ -509,12 +465,13 @@ case Ini.Sorting of //Songs leeren SetLength (Song, 0); - for S := Low(Songs.Song) to High(Songs.Song) do begin + for S := 0 to Songs.SongList.Count-1 do + begin if (Ini.Tabs = 1) then - if (Ini.Sorting = sEdition) and (CompareText(SS, Songs.Song[S].Edition) <> 0) then begin + if (Ini.Sorting = sEdition) and (CompareText(SS, TSong( Songs.SongList[S] ).Edition) <> 0) then begin // add Category Button Inc(Order); - SS := Songs.Song[S].Edition; + SS := TSong( Songs.SongList[S] ).Edition; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := '[' + SS + ']'; @@ -554,10 +511,10 @@ case Ini.Sorting of CatSongs.Song[CatLen].Visible := true; end - else if (Ini.Sorting = sGenre) and (CompareText(SS, Songs.Song[S].Genre) <> 0) then begin + else if (Ini.Sorting = sGenre) and (CompareText(SS, TSong( Songs.SongList[S] ).Genre) <> 0) then begin // add Genre Button Inc(Order); - SS := Songs.Song[S].Genre; + SS := TSong( Songs.SongList[S] ).Genre; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := SS; @@ -580,10 +537,10 @@ case Ini.Sorting of CatSongs.Song[CatLen].Visible := true; end - else if (Ini.Sorting = sLanguage) and (CompareText(SS, Songs.Song[S].Language) <> 0) then begin + else if (Ini.Sorting = sLanguage) and (CompareText(SS, TSong( Songs.SongList[S] ).Language) <> 0) then begin // add Language Button Inc(Order); - SS := Songs.Song[S].Language; + SS := TSong( Songs.SongList[S] ).Language; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := SS; @@ -607,11 +564,11 @@ case Ini.Sorting of end else if (Ini.Sorting = sTitle) and - (Length(Songs.Song[S].Title)>=1) and - (Letter <> UpperCase(Songs.Song[S].Title)[1]) then begin + (Length(TSong( Songs.SongList[S] ).Title)>=1) and + (Letter <> UpperCase(TSong( Songs.SongList[S] ).Title)[1]) then begin // add a letter Category Button Inc(Order); - Letter := Uppercase(Songs.Song[S].Title)[1]; + Letter := Uppercase(TSong( Songs.SongList[S] ).Title)[1]; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := '[' + Letter + ']'; @@ -636,10 +593,11 @@ case Ini.Sorting of CatSongs.Song[CatLen].Visible := true; end - else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> UpperCase(Songs.Song[S].Artist)[1]) then begin + else if (Ini.Sorting = sArtist) and (Length(TSong( Songs.SongList[S] ).Artist)>=1) and + (Letter <> UpperCase(TSong( Songs.SongList[S] ).Artist)[1]) then begin // add a letter Category Button Inc(Order); - Letter := UpperCase(Songs.Song[S].Artist)[1]; + Letter := UpperCase(TSong( Songs.SongList[S] ).Artist)[1]; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := '[' + Letter + ']'; @@ -663,10 +621,10 @@ case Ini.Sorting of CatSongs.Song[CatLen].Visible := true; end - else if (Ini.Sorting = sFolder) and (CompareText(SS, Songs.Song[S].Folder) <> 0) then begin + else if (Ini.Sorting = sFolder) and (CompareText(SS, TSong( Songs.SongList[S] ).Folder) <> 0) then begin // 0.5.0: add folder tab Inc(Order); - SS := Songs.Song[S].Folder; + SS := TSong( Songs.SongList[S] ).Folder; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := SS; @@ -689,8 +647,8 @@ case Ini.Sorting of CatSongs.Song[CatLen].Visible := true; end - else if (Ini.Sorting = sTitle2) AND (Length(Songs.Song[S].Title)>=1) then begin - if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Title)[1]; + else if (Ini.Sorting = sTitle2) AND (Length(TSong( Songs.SongList[S] ).Title)>=1) then begin + if (ord(TSong( Songs.SongList[S] ).Title[1]) > 47) and (ord(TSong( Songs.SongList[S] ).Title[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(TSong( Songs.SongList[S] ).Title)[1]; if (Letter <> Letter2) then begin // add a letter Category Button Inc(Order); @@ -719,8 +677,8 @@ case Ini.Sorting of end; end - else if (Ini.Sorting = sArtist2) AND (Length(Songs.Song[S].Artist)>=1) then begin - if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Artist)[1]; + else if (Ini.Sorting = sArtist2) AND (Length(TSong( Songs.SongList[S] ).Artist)>=1) then begin + if (ord(TSong( Songs.SongList[S] ).Artist[1]) > 47) and (ord(TSong( Songs.SongList[S] ).Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(TSong( Songs.SongList[S] ).Artist)[1]; if (Letter <> Letter2) then begin // add a letter Category Button Inc(Order); @@ -755,7 +713,7 @@ case Ini.Sorting of Inc (CatNumber); //Increase Number in Cat - CatSongs.Song[CatLen] := Songs.Song[S]; + CatSongs.Song[CatLen] := TSong( Songs.SongList[S] ); CatSongs.Song[CatLen].OrderNum := Order; // assigns category CatSongs.Song[CatLen].CatNumber := CatNumber; @@ -923,4 +881,11 @@ begin end; end; + + +// ----------------------------------------------------------------------------- + + + + end. diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas index e370ad67..a523afd2 100644 --- a/Game/Code/Screens/UScreenEditConvert.pas +++ b/Game/Code/Screens/UScreenEditConvert.pas @@ -16,6 +16,7 @@ uses UMenu, {$ENDIF} ULog, USongs, + USong, UMusic, UThemes; diff --git a/Game/Code/Screens/UScreenEditHeader.pas b/Game/Code/Screens/UScreenEditHeader.pas index 7c8b2d56..60466a27 100644 --- a/Game/Code/Screens/UScreenEditHeader.pas +++ b/Game/Code/Screens/UScreenEditHeader.pas @@ -4,7 +4,11 @@ interface {$I switches.inc} -uses UMenu, SDL, USongs, UThemes; +uses UMenu, + SDL, + USongs, + USong, + UThemes; type TScreenEditHeader = class(TMenu) diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas index 725dd4e9..57d6777e 100644 --- a/Game/Code/Screens/UScreenEditSub.pas +++ b/Game/Code/Screens/UScreenEditSub.pas @@ -15,6 +15,7 @@ uses UFiles, UTime, USongs, + USong, UIni, ULog, UTexture, @@ -143,40 +144,40 @@ begin begin // Increase BPM if SDL_ModState = 0 then - AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) + 1) / 5; // (1/20) + CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 5) + 1) / 5; // (1/20) if SDL_ModState = KMOD_LSHIFT then - AktSong.BPM[0].BPM := AktSong.BPM[0].BPM + 4; // (1/1) + CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM + 4; // (1/1) if SDL_ModState = KMOD_LCTRL then - AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) + 1) / 25; // (1/100) + CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 25) + 1) / 25; // (1/100) end; SDLK_MINUS: begin // Decrease BPM if SDL_ModState = 0 then - AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) - 1) / 5; + CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 5) - 1) / 5; if SDL_ModState = KMOD_LSHIFT then - AktSong.BPM[0].BPM := AktSong.BPM[0].BPM - 4; + CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM - 4; if SDL_ModState = KMOD_LCTRL then - AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) - 1) / 25; + CurrentSong.BPM[0].BPM := Round((CurrentSong.BPM[0].BPM * 25) - 1) / 25; end; SDLK_0: begin // Increase GAP if SDL_ModState = 0 then - AktSong.GAP := AktSong.GAP + 10; + CurrentSong.GAP := CurrentSong.GAP + 10; if SDL_ModState = KMOD_LSHIFT then - AktSong.GAP := AktSong.GAP + 1000; + CurrentSong.GAP := CurrentSong.GAP + 1000; end; SDLK_9: begin // Decrease GAP if SDL_ModState = 0 then - AktSong.GAP := AktSong.GAP - 10; + CurrentSong.GAP := CurrentSong.GAP - 10; if SDL_ModState = KMOD_LSHIFT then - AktSong.GAP := AktSong.GAP - 1000; + CurrentSong.GAP := CurrentSong.GAP - 1000; end; SDLK_KP_PLUS: @@ -222,13 +223,13 @@ begin begin // Save Song if SDL_ModState = KMOD_LSHIFT then - SaveSong(AktSong, Czesci[0], Path + FileName, true) + SaveSong(CurrentSong, Czesci[0], Path + FileName, true) else - SaveSong(AktSong, Czesci[0], Path + FileName, false); + SaveSong(CurrentSong, Czesci[0], Path + FileName, false); {if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then // Save Song - SaveSongDebug(AktSong, Czesci[0], 'C:\song.asm', false);} + SaveSongDebug(CurrentSong, Czesci[0], 'C:\song.asm', false);} end; @@ -656,7 +657,7 @@ var C: integer; N: integer; begin - AktSong.BPM[0].BPM := AktSong.BPM[0].BPM / 2; + CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM / 2; for C := 0 to Czesci[0].High do begin Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start div 2; Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote div 2; @@ -673,7 +674,7 @@ var C: integer; N: integer; begin - AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2; + CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM * 2; for C := 0 to Czesci[0].High do begin Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start * 2; Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote * 2; @@ -1160,7 +1161,7 @@ begin try ResetSingTemp; - Error := not LoadSong(Path + FileName); +// Error := not LoadSong(Path + FileName); // todo - JB come back to this except Error := True; end; @@ -1179,15 +1180,15 @@ begin MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table MidiOut.Open; {$ENDIF} - Text[TextTitle].Text := AktSong.Title; - Text[TextArtist].Text := AktSong.Artist; - Text[TextMp3].Text := AktSong.Mp3; + Text[TextTitle].Text := CurrentSong.Title; + Text[TextArtist].Text := CurrentSong.Artist; + Text[TextMp3].Text := CurrentSong.Mp3; Czesci[0].Akt := 0; AktNuta := 0; Czesci[0].Czesc[0].Nuta[0].Color := 1; - AudioPlayback.Open(Path + AktSong.Mp3); + AudioPlayback.Open(Path + CurrentSong.Mp3); //Set Down Music Volume for Better hearability of Midi Sounds //Music.SetVolume(40); @@ -1238,7 +1239,7 @@ begin {$ENDIF} // click - AktBeat := Floor(GetMidBeat(MidiPos - AktSong.GAP / 1000)); + AktBeat := Floor(GetMidBeat(MidiPos - CurrentSong.GAP / 1000)); Text[TextDebug].Text := IntToStr(AktBeat); if AktBeat <> LastClick then begin @@ -1269,8 +1270,8 @@ begin // click if (Click) and (PlaySentence) then begin -// AktBeat := Floor(AktSong.BPM[0].BPM * (Music.Position - AktSong.GAP / 1000) / 60); - AktBeat := Floor(GetMidBeat(AudioPlayback.Position - AktSong.GAP / 1000)); +// AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60); + AktBeat := Floor(GetMidBeat(AudioPlayback.Position - CurrentSong.GAP / 1000)); Text[TextDebug].Text := IntToStr(AktBeat); if AktBeat <> LastClick then begin for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do @@ -1288,8 +1289,8 @@ begin Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut); // Song info - Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4); - Text[TextGAP].Text := FloatToStr(AktSong.GAP); + Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4); + Text[TextGAP].Text := FloatToStr(CurrentSong.GAP); //Error reading Variables when no Song is loaded if not Error then diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas index 5f7a0461..a4dc5f0d 100644 --- a/Game/Code/Screens/UScreenMain.pas +++ b/Game/Code/Screens/UScreenMain.pas @@ -124,7 +124,7 @@ begin //Solo if (Interaction = 0) then begin - if (Length(Songs.Song) >= 1) then + if (Songs.SongList.Count >= 1) then begin AudioPlayback.PlayStart; if (Ini.Players >= 0) and (Ini.Players <= 3) then PlayersPlay := Ini.Players + 1; @@ -138,8 +138,9 @@ begin end; //Multi - if Interaction = 1 then begin - if (Length(Songs.Song) >= 1) then + if Interaction = 1 then + begin + if (Songs.SongList.Count >= 1) then begin if (Length(DLLMan.Plugins)>=1) then begin diff --git a/Game/Code/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas index 80259802..42776717 100644 --- a/Game/Code/Screens/UScreenOptionsRecord.pas +++ b/Game/Code/Screens/UScreenOptionsRecord.pas @@ -15,14 +15,21 @@ type SelectSlideChannelR: integer; public constructor Create; override; - function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; - procedure onShow; override; - procedure UpdateCard; + function Draw: boolean; override; + function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; + procedure onShow; override; + procedure onHide; override; + procedure UpdateCard; end; implementation -uses SysUtils, UGraphic, URecord, ULog; +uses SysUtils, + UGraphic, + URecord, + UDraw, + UMain, + ULog; function TScreenOptionsRecord.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; begin @@ -43,7 +50,7 @@ begin end; SDLK_RETURN: begin - if SelInteraction = 4 then begin + if SelInteraction = 5 then begin Ini.Save; AudioPlayback.PlayBack; FadeTo(@ScreenOptions); @@ -55,19 +62,21 @@ begin InteractPrev; SDLK_RIGHT: begin - if (SelInteraction >= 0) and (SelInteraction <= 3) then begin + if (SelInteraction >= 0) and (SelInteraction <= 4) then begin AudioPlayback.PlayOption; InteractInc; end; - if SelInteraction = 0 then UpdateCard; +// if SelInteraction = 0 then UpdateCard; + UpdateCard; end; SDLK_LEFT: begin - if (SelInteraction >= 0) and (SelInteraction <= 3) then begin + if (SelInteraction >= 0) and (SelInteraction <= 4) then begin AudioPlayback.PlayOption; InteractDec; end; - if SelInteraction = 0 then UpdateCard; + UpdateCard; +// if SelInteraction = 0 then UpdateCard; end; end; end; @@ -80,22 +89,27 @@ var SCI: integer; begin inherited Create; - + LoadFromTheme(Theme.OptionsRecord); - SetLength(ICard, Length(Recording.SoundCard)); - for SC := 0 to High(Recording.SoundCard) do - ICard[SC] := Recording.SoundCard[SC].Description; + SetLength(ICard, Length(AudioInputProcessor.SoundCard)); + for SC := 0 to High(AudioInputProcessor.SoundCard) do + ICard[SC] := AudioInputProcessor.SoundCard[SC].Description; + + if (Length(AudioInputProcessor.SoundCard) > 0) then + begin + SetLength(IInput, Length(AudioInputProcessor.SoundCard[Ini.Card].Input)); + for SCI := 0 to High(AudioInputProcessor.SoundCard[Ini.Card].Input) do + IInput[SCI] := AudioInputProcessor.SoundCard[Ini.Card].Input[SCI].Name; - if (Length(Recording.SoundCard) > 0) then begin - SetLength(IInput, Length(Recording.SoundCard[Ini.Card].Input)); - for SCI := 0 to High(Recording.SoundCard[Ini.Card].Input) do - IInput[SCI] := Recording.SoundCard[Ini.Card].Input[SCI].Name; AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, Ini.Card, ICard); + SelectSlideInput := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput, Ini.CardList[0].Input, IInput); SelectSlideChannelL := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelL, Ini.CardList[0].ChannelL, IChannel); SelectSlideChannelR := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelR, Ini.CardList[0].ChannelR, IChannel); + + AddSelect(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost); end; AddButton(Theme.OptionsRecord.ButtonExit); @@ -108,6 +122,16 @@ end; procedure TScreenOptionsRecord.onShow; begin Interaction := 0; + writeln( 'AudioInput.CaptureStart') ; + + PlayersPlay := 2; // TODO : This needs fixing + AudioInput.CaptureStart; + +end; + +procedure TScreenOptionsRecord.onHide; +begin + AudioInput.CaptureStop; end; procedure TScreenOptionsRecord.UpdateCard; @@ -115,18 +139,74 @@ var SC: integer; SCI: integer; begin - SC := Ini.Card; -// if SC = 1 then beep; + writeln( 'Update Card') ; + AudioInput.CaptureStop; + try + SC := Ini.Card; + // if SC = 1 then beep; + + SetLength(IInput, Length(AudioInputProcessor.SoundCard[SC].Input)); + for SCI := 0 to High(AudioInputProcessor.SoundCard[SC].Input) do begin + IInput[SCI] := AudioInputProcessor.SoundCard[SC].Input[SCI].Name; + // Log.LogError(IInput[SCI]); + end; - SetLength(IInput, Length(Recording.SoundCard[SC].Input)); - for SCI := 0 to High(Recording.SoundCard[SC].Input) do begin - IInput[SCI] := Recording.SoundCard[SC].Input[SCI].Name; -// Log.LogError(IInput[SCI]); + + UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectSlideInput, IInput, Ini.CardList[SC].Input); + UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelL, SelectSlideChannelL, IChannel, Ini.CardList[SC].ChannelL); + UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelR, SelectSlideChannelR, IChannel, Ini.CardList[SC].ChannelR); + + finally + AudioInput.CaptureStart; end; +end; - UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectSlideInput, IInput, Ini.CardList[SC].Input); - UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelL, SelectSlideChannelL, IChannel, Ini.CardList[SC].ChannelL); - UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelR, SelectSlideChannelR, IChannel, Ini.CardList[SC].ChannelR); +function TScreenOptionsRecord.Draw: boolean; +begin + DrawBG; + DrawFG; + + // TODO : this needs to be positioned correctly + if PlayersPlay = 1 then + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + + if PlayersPlay = 2 then begin + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); + end; + if ScreenAct = 2 then begin + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2); + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3); + end; + end; + + if PlayersPlay = 3 then begin + SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0); + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0); + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); + end; + if ScreenAct = 2 then begin + SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3); + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4); + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5); + end; + end; + + Result := True; end; + end. diff --git a/Game/Code/Screens/UScreenOptionsSound.pas b/Game/Code/Screens/UScreenOptionsSound.pas index 867a10b6..64a0413f 100644 --- a/Game/Code/Screens/UScreenOptionsSound.pas +++ b/Game/Code/Screens/UScreenOptionsSound.pas @@ -51,14 +51,14 @@ begin InteractPrev; SDLK_RIGHT: begin - if (SelInteraction >= 0) and (SelInteraction <= 5) then begin + if (SelInteraction >= 0) and (SelInteraction <= 6) then begin AudioPlayback.PlayOption; InteractInc; end; end; SDLK_LEFT: begin - if (SelInteraction >= 0) and (SelInteraction <= 5) then begin + if (SelInteraction >= 0) and (SelInteraction <= 6) then begin AudioPlayback.PlayOption; InteractDec; end; @@ -75,15 +75,14 @@ begin LoadFromTheme(Theme.OptionsSound); - AddSelect(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost); + AddSelect(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost); // TODO - This need moving to ScreenOptionsRecord AddSelect(Theme.OptionsSound.SelectClickAssist, Ini.ClickAssist, IClickAssist); AddSelect(Theme.OptionsSound.SelectBeatClick, Ini.BeatClick, IBeatClick); AddSelect(Theme.OptionsSound.SelectThreshold, Ini.Threshold, IThreshold); //Song Preview AddSelectSlide(Theme.OptionsSound.SelectSlidePreviewVolume, Ini.PreviewVolume, IPreviewVolume); - AddSelectSlide - (Theme.OptionsSound.SelectSlidePreviewFading, Ini.PreviewFading, IPreviewFading); + AddSelectSlide(Theme.OptionsSound.SelectSlidePreviewFading, Ini.PreviewFading, IPreviewFading); AddButton(Theme.OptionsSound.ButtonExit); if (Length(Button[0].Text)=0) then diff --git a/Game/Code/Screens/UScreenScore.pas b/Game/Code/Screens/UScreenScore.pas index 84fd4e15..c53844f5 100644 --- a/Game/Code/Screens/UScreenScore.pas +++ b/Game/Code/Screens/UScreenScore.pas @@ -304,9 +304,9 @@ begin // Singstar Fadeout := false; - Text[TextArtist].Text := AktSong.Artist; - Text[TextTitle].Text := AktSong.Title; - Text[TextArtistTitle].Text := AktSong.Artist + ' - ' + AktSong.Title; + Text[TextArtist].Text := CurrentSong.Artist; + Text[TextTitle].Text := CurrentSong.Title; + Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title; // set visibility case PlayersPlay of diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index 5a9ecae7..adfc4d2c 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -101,22 +101,29 @@ type fCurrentVideoPlaybackEngine : IVideoPlayback; constructor Create; override; - procedure onShow; override; - procedure onShowFinish; override; - function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; - function Draw: boolean; override; - procedure Finish; virtual; - procedure UpdateLCD; - procedure Pause; //Pause Mod(Toggles Pause) - - //OnSentenceEnd for LineBonus + Singbar - procedure onSentenceEnd(S: Cardinal); - //OnSentenceChange (for Golden Notes) - procedure onSentenceChange(S: Cardinal); + procedure onShow; override; + procedure onShowFinish; override; + + function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; + function Draw: boolean; override; + + procedure Finish; virtual; + procedure UpdateLCD; + procedure Pause; //Pause Mod(Toggles Pause) + + procedure onSentenceEnd(S: Cardinal); //OnSentenceEnd for LineBonus + Singbar + procedure onSentenceChange(S: Cardinal); //OnSentenceChange (for Golden Notes) end; implementation -uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math; + +uses UGraphic, + UDraw, + UMain, + Classes, + URecord, + ULanguage, + math; // Method for input parsing. If False is returned, GetNextWindow // should be checked to know the next window to load; @@ -204,7 +211,7 @@ begin AudioPlayback.Pause; // pause Video - if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then + if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then fCurrentVideoPlaybackEngine.Pause; end @@ -218,7 +225,7 @@ begin AudioPlayback.Play; // Video - if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then + if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then fCurrentVideoPlaybackEngine.Pause; Paused := false; @@ -425,12 +432,13 @@ begin {Static[StaticP3RScoreBG].Visible := V3R; Text[TextP3RScore].Visible := V3R; } - // load notes ResetSingTemp; // Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!'); - AktSong := CatSongs.Song[CatSongs.Selected]; + CurrentSong := CatSongs.Song[CatSongs.Selected]; + try - if not LoadSong(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName) then + if not CurrentSong.LoadSong then +// 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); @@ -449,26 +457,26 @@ begin 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 + CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path; +// CurrentSong.GAP := CurrentSong.GAP + 40 {4096 = 100ms for buffer} + 20 {microphone} + 60000 / CurrentSong.BPM[0].BPM / 2; // temporary until UMain will be fixed // set movie - if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then + if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then begin // todo: VideoGap and Start time verwursten - fCurrentVideoPlaybackEngine.Open( AktSong.Path + AktSong.Video ); + fCurrentVideoPlaybackEngine.Open( CurrentSong.Path + CurrentSong.Video ); - fCurrentVideoPlaybackEngine.position := AktSong.VideoGAP + AktSong.Start; + fCurrentVideoPlaybackEngine.position := CurrentSong.VideoGAP + CurrentSong.Start; - AktSong.VideoLoaded := true; + CurrentSong.VideoLoaded := true; end; // set background - if (AktSong.Background <> '') and (AktSong.VideoLoaded = false) then + if (CurrentSong.Background <> '') and (CurrentSong.VideoLoaded = false) then try - Tex_Background := Texture.LoadTexture(AktSong.Path + AktSong.Background); + Tex_Background := Texture.LoadTexture(CurrentSong.Path + CurrentSong.Background); except - log.LogError('Background could not be loaded: ' + AktSong.Path + AktSong.Background); + log.LogError('Background could not be loaded: ' + CurrentSong.Path + CurrentSong.Background); Tex_Background.TexNum := -1; end else @@ -478,20 +486,20 @@ begin // play music (I) AudioInput.CaptureStart; - AudioPlayback.Position := AktSong.Start; + AudioPlayback.Position := CurrentSong.Start; // Music.Play; // prepare timer (I) // CountSkipTimeSet; - Czas.Teraz := AktSong.Start; + Czas.Teraz := CurrentSong.Start; Czas.Razem := AudioPlayback.Length; - if (AktSong.Finish > 0) then Czas.Razem := AktSong.Finish / 1000; + if (CurrentSong.Finish > 0) then Czas.Razem := CurrentSong.Finish / 1000; Czas.OldBeat := -1; for P := 0 to High(Player) do ClearScores(P); // main text - Lyrics.Clear (AktSong.BPM[0].BPM, AktSong.Resolution); + Lyrics.Clear (CurrentSong.BPM[0].BPM, CurrentSong.Resolution); // set custom options case Ini.LyricsFont of @@ -870,7 +878,7 @@ procedure TScreenSing.onShowFinish; begin // play movie (II) - if AktSong.VideoLoaded then + if CurrentSong.VideoLoaded then begin try writeln( 'VideoPlayback.FFmpegGetFrame' ); @@ -884,11 +892,11 @@ begin on E : Exception do begin //If an Error occurs Reading Video: prevent Video from being Drawn again and Close Video - AktSong.VideoLoaded := False; + CurrentSong.VideoLoaded := False; Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); Log.LogError('Error Message : '+ E.message ); Log.LogError(' In : '+ E.ClassName +' (TScreenSing.onShowFinish)' ); - Log.LogError('Corrupted File: ' + AktSong.Video); + Log.LogError('Corrupted File: ' + CurrentSong.Video); try // CloseSmpeg; fCurrentVideoPlaybackEngine.Close; @@ -1141,7 +1149,8 @@ begin SingDrawBackground; // update and draw movie - if ShowFinish and ( AktSong.VideoLoaded or fShowVisualization ) then + if ShowFinish and + ( CurrentSong.VideoLoaded or fShowVisualization ) then // if ShowFinish then begin // try @@ -1161,12 +1170,12 @@ begin begin //If an Error occurs drawing: prevent Video from being Drawn again and Close Video - AktSong.VideoLoaded := False; + CurrentSong.VideoLoaded := False; log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); Log.LogError('Error Message : '+ E.message ); Log.LogError(' In : '+ E.ClassName +' (TScreenSing.Draw)' ); - Log.LogError('Corrupted File: ' + AktSong.Video); + Log.LogError('Corrupted File: ' + CurrentSong.Video); try // CloseSmpeg; fCurrentVideoPlaybackEngine.Close; @@ -1183,9 +1192,9 @@ begin DrawFG; // check for music finish -// Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(Czas.Teraz*1000) + ' ' + IntToStr(AktSong.Finish)); +// Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(Czas.Teraz*1000) + ' ' + IntToStr(CurrentSong.Finish)); if ShowFinish then begin - if (not AudioPlayback.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin + if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or (Czas.Teraz*1000 <= CurrentSong.Finish)) then begin //Pause Mod: if not Paused then Sing(Self); // analyze song @@ -1251,11 +1260,11 @@ begin Log.LogBenchmark('Creating files', 0); end; - if AktSong.VideoLoaded then + if CurrentSong.VideoLoaded then begin // CloseSmpeg; fCurrentVideoPlaybackEngine.Close; - AktSong.VideoLoaded := false; // to prevent drawing closed video + CurrentSong.VideoLoaded := false; // to prevent drawing closed video end; SetFontItalic (False); diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas index 5d87ffdd..7d2eba07 100644 --- a/Game/Code/Screens/UScreenSingModi.pas +++ b/Game/Code/Screens/UScreenSingModi.pas @@ -520,7 +520,7 @@ end; // comment by blindy: wo zum henker wird denn in diesem screen ein video abgespielt? // update and draw movie // wie wo wadd? also in der selben funktion in der uscreensing kommt des video in der zeile 995, oder was wollteste wissen? :X -{ if ShowFinish and AktSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin +{ if ShowFinish and CurrentSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin UpdateSmpeg; // this only draws end;} @@ -530,7 +530,7 @@ end; if ShowFinish then begin if DllMan.Selected.LoadSong then begin - if (not AudioPlayback.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin + if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or (Czas.Teraz*1000 <= CurrentSong.Finish)) then begin //Pause Mod: if not Paused then Sing(Self); // analyze song diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas index 4f90e2ca..4b42288a 100644 --- a/Game/Code/Screens/UScreenSong.pas +++ b/Game/Code/Screens/UScreenSong.pas @@ -383,7 +383,7 @@ begin end; SDLK_RETURN: begin - if Length(Songs.Song) > 0 then + if Songs.SongList.Count > 0 then begin {$IFDEF UseSerialPort} // PortWriteB($378, 0); @@ -438,7 +438,7 @@ begin SDLK_M: //Show SongMenu begin - if (Length(Songs.Song) > 0) then begin + if (Songs.SongList.Count > 0) then begin if (Mode = 0) then begin if not CatSongs.Song[Interaction].Main then begin // clicked on Song if CatSongs.CatNumShow = -3 then @@ -457,14 +457,14 @@ begin SDLK_P: //Show Playlist Menu begin - if (Length(Songs.Song) > 0) AND (Mode = 0) then begin + if (Songs.SongList.Count > 0) AND (Mode = 0) then begin ScreenSongMenu.MenuShow(SM_Playlist_Load); end; end; SDLK_J: //Show Jumpto Menu begin - if (Length(Songs.Song) > 0) AND (Mode = 0) then + if (Songs.SongList.Count > 0) AND (Mode = 0) then begin ScreenSongJumpto.Visible := True; end; @@ -553,7 +553,7 @@ begin SDLK_RIGHT: begin - if (Length(Songs.Song) > 0) AND (Mode = 0) then + if (Songs.SongList.Count > 0) AND (Mode = 0) then begin AudioPlayback.PlayChange; SelectNext; @@ -568,7 +568,7 @@ begin SDLK_LEFT: begin - if (Length(Songs.Song) > 0)AND (Mode = 0) then begin + if (Songs.SongList.Count > 0)AND (Mode = 0) then begin AudioPlayback.PlayChange; SelectPrev; ChangeMusic; @@ -585,7 +585,7 @@ begin SDLK_R: begin - if (Length(Songs.Song) > 0) AND (Mode = 0) then begin + if (Songs.SongList.Count > 0) AND (Mode = 0) then begin if (SDL_ModState = KMOD_LSHIFT) AND (Ini.Tabs_at_startup = 1) then //Random Category begin @@ -1819,7 +1819,7 @@ begin EqualizerTime := A; Data := AudioPlayback.GetFFTData; - B:=0; + B := 0; Pos := 0; Res := ceil(92/Theme.Song.Equalizer.Bands);//How much channels are used for one Band @@ -2121,7 +2121,7 @@ end; procedure TScreenSong.OpenEditor; begin - if (Length(Songs.Song) > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = 0) then + if (Songs.SongList.Count > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = 0) then begin AudioPlayback.Stop; AudioPlayback.PlayStart; diff --git a/Game/Code/Screens/UScreenStatMain.pas b/Game/Code/Screens/UScreenStatMain.pas index 7e5c7d91..f7257201 100644 --- a/Game/Code/Screens/UScreenStatMain.pas +++ b/Game/Code/Screens/UScreenStatMain.pas @@ -37,6 +37,7 @@ implementation uses UGraphic, UDataBase, USongs, + USong, ULanguage, UCommon, {$IFDEF win32} @@ -133,8 +134,8 @@ begin //Set Songs with Vid SongswithVid := 0; - For I := 0 to high(Songs.Song) do - if (Songs.Song[I].Video <> '') then + For I := 0 to Songs.SongList.Count -1 do + if (TSong(Songs.SongList[I]).Video <> '') then Inc(SongswithVid); end; @@ -233,7 +234,7 @@ begin %2:d Count of UnSung Songs %3:d Count of Songs with Video (A3) %4:s Name of the most popular Song} - A1 := Length(Songs.Song); + A1 := Songs.SongList.Count; A2 := Database.GetTotalEntrys(2); A3 := SongswithVid; diff --git a/Game/Code/Screens/UScreenTop5.pas b/Game/Code/Screens/UScreenTop5.pas index bf19fed2..207f6ee6 100644 --- a/Game/Code/Screens/UScreenTop5.pas +++ b/Game/Code/Screens/UScreenTop5.pas @@ -92,29 +92,29 @@ var begin Fadeout := false; - //ReadScore(AktSong); + //ReadScore(CurrentSong); PMax := Ini.Players; if Ini.Players = 4 then Ini.Players := 5; for I := 0 to PMax do - DataBase.AddScore(AktSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalI)); + DataBase.AddScore(CurrentSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalI)); - DataBase.WriteScore(AktSong); - DataBase.ReadScore(AktSong); + DataBase.WriteScore(CurrentSong); + DataBase.ReadScore(CurrentSong); - Text[TextArtistTitle].Text := AktSong.Artist + ' - ' + AktSong.Title; + Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title; - for I := 1 to Length(AktSong.Score[Ini.Difficulty]) do begin + for I := 1 to Length(CurrentSong.Score[Ini.Difficulty]) do begin Static[StaticNumber[I]].Visible := true; Text[TextNumber[I]].Visible := true; Text[TextName[I]].Visible := true; Text[TextScore[I]].Visible := true; - Text[TextName[I]].Text := AktSong.Score[Ini.Difficulty, I-1].Name; - Text[TextScore[I]].Text := IntToStr(AktSong.Score[Ini.Difficulty, I-1].Score); + Text[TextName[I]].Text := CurrentSong.Score[Ini.Difficulty, I-1].Name; + Text[TextScore[I]].Text := IntToStr(CurrentSong.Score[Ini.Difficulty, I-1].Score); end; - for I := Length(AktSong.Score[Ini.Difficulty])+1 to 5 do begin + for I := Length(CurrentSong.Score[Ini.Difficulty])+1 to 5 do begin Static[StaticNumber[I]].Visible := false; Text[TextNumber[I]].Visible := false; Text[TextName[I]].Visible := false; diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr index 236d0b1e..ca639d1e 100644 --- a/Game/Code/UltraStar.dpr +++ b/Game/Code/UltraStar.dpr @@ -87,6 +87,7 @@ uses URecord in 'Classes\URecord.pas', UTime in 'Classes\UTime.pas', TextGL in 'Classes\TextGL.pas', + USong in 'Classes\USong.pas', USongs in 'Classes\USongs.pas', UIni in 'Classes\UIni.pas', ULyrics in 'Classes\ULyrics.pas', -- cgit v1.2.3